예제 #1
0
CFX_Int32Array* CBC_Detector::findGuardPattern(CBC_CommonBitMatrix* matrix,
                                               int32_t column,
                                               int32_t row,
                                               int32_t width,
                                               FX_BOOL whiteFirst,
                                               int32_t* pattern,
                                               int32_t patternLength,
                                               CFX_Int32Array& counters) {
  for (int32_t i = 0; i < counters.GetSize(); i++) {
    counters.SetAt(i, 0);
  }
  FX_BOOL isWhite = whiteFirst;
  int32_t patternStart = column;
  int32_t pixelDrift = 0;
  CFX_Int32Array* intarray = new CFX_Int32Array;
  while (matrix->Get(patternStart, row) && patternStart > 0 &&
         pixelDrift++ < MAX_PIXEL_DRIFT) {
    patternStart--;
  }
  int32_t x = patternStart;
  int32_t counterPosition = 0;
  for (; x < width; x++) {
    FX_BOOL pixel = matrix->Get(x, row);
    if (pixel ^ isWhite) {
      counters[counterPosition]++;
    } else {
      if (counterPosition == patternLength - 1) {
        if (patternMatchVariance(counters, pattern, MAX_INDIVIDUAL_VARIANCE) <
            MAX_AVG_VARIANCE) {
          intarray->Add(patternStart);
          intarray->Add(x);
          return intarray;
        }
        patternStart += counters[0] + counters[1];
        for (int32_t l = 2, k = 0; l < patternLength; l++, k++) {
          counters.SetAt(k, counters.GetAt(l));
        }
        counters.SetAt(patternLength - 2, 0);
        counters.SetAt(patternLength - 1, 0);
        counterPosition--;
      } else {
        counterPosition++;
      }
      counters[counterPosition] = 1;
      isWhite = !isWhite;
    }
  }
  if (counterPosition == patternLength - 1) {
    if (patternMatchVariance(counters, pattern, MAX_INDIVIDUAL_VARIANCE) <
        MAX_AVG_VARIANCE) {
      intarray->Add(patternStart);
      intarray->Add(x - 1);
      return intarray;
    }
  }
  delete intarray;
  return NULL;
}
예제 #2
0
		int Code128Reader::decodeCode(Ref<BitArray> row, int counters[], int countersCount,
		    int rowOffset) {
		  if (!recordPattern(row, rowOffset, counters, countersCount)) {
		    throw ReaderException("");
		  }
			unsigned int bestVariance = MAX_AVG_VARIANCE; // worst variance we'll accept
			int bestMatch = -1;
			for (int d = 0; d < CODE_PATTERNS_LENGTH; d++) {
				int pattern[countersLength];

				for(int ind = 0; ind< countersLength; ind++){
					pattern[ind] = CODE_PATTERNS[d][ind];
				}
//				memcpy(pattern, CODE_PATTERNS[d], countersLength);
				unsigned int variance = patternMatchVariance(counters, countersCount, pattern,
				    MAX_INDIVIDUAL_VARIANCE);
				if (variance < bestVariance) {
					bestVariance = variance;
					bestMatch = d;
				}
			}
			// TODO We're overlooking the fact that the STOP pattern has 7 values, not 6.
			if (bestMatch >= 0) {
				return bestMatch;
			} else {
				throw ReaderException("");
			}
		}
예제 #3
0
		int* Code128Reader::findStartPattern(Ref<BitArray> row){
			int width = row->getSize();
			int rowOffset = 0;
			while (rowOffset < width) {
				if (row->get(rowOffset)) {
					break;
				}
				rowOffset++;
			}

			int counterPosition = 0;
			int counters[countersLength] = {0,0,0,0,0,0};
			int patternStart = rowOffset;
			bool isWhite = false;
			int patternLength =  sizeof(counters) / sizeof(int);

			for (int i = rowOffset; i < width; i++) {
				bool pixel = row->get(i);
				if (pixel ^ isWhite) {
					counters[counterPosition]++;
				} else {
					if (counterPosition == patternLength - 1) {
						unsigned int bestVariance = MAX_AVG_VARIANCE;
						int bestMatch = -1;
						for (int startCode = CODE_START_A; startCode <= CODE_START_C; startCode++) {
							unsigned int variance = patternMatchVariance(counters, sizeof(counters) / sizeof(int),
							    CODE_PATTERNS[startCode], MAX_INDIVIDUAL_VARIANCE);
							if (variance < bestVariance) {
								bestVariance = variance;
								bestMatch = startCode;
							}
						}
						if (bestMatch >= 0) {
							// Look for whitespace before start pattern, >= 50% of width of start pattern
							if (row->isRange(fmaxl(0, patternStart - (i - patternStart) / 2), patternStart,
							    false)) {
								int* resultValue = new int[3];
								resultValue[0] = patternStart;
								resultValue[1] = i;
								resultValue[2] = bestMatch;
								return resultValue;
							}
						}
						patternStart += counters[0] + counters[1];
						for (int y = 2; y < patternLength; y++) {
							counters[y - 2] = counters[y];
						}
						counters[patternLength - 2] = 0;
						counters[patternLength - 1] = 0;
						counterPosition--;
					} else {
						counterPosition++;
					}
					counters[counterPosition] = 1;
					isWhite = !isWhite;
				}
			}
			throw ReaderException("");
		}
예제 #4
0
//		int UPCEANReader::decodeDigit(Ref<BitArray> row, int counters[], int countersLen, int rowOffset, int** patterns/*[][]*/, int paterns1Len, int paterns2Len)		
		int UPCEANReader::decodeDigit(Ref<BitArray> row, int counters[], int countersLen, int rowOffset, UPC_EAN_PATTERNS patternType){
			recordPattern(row, rowOffset, counters, countersLen);
			unsigned int bestVariance = MAX_AVG_VARIANCE; // worst variance we'll accept
			int bestMatch = -1;
			
			int max = 0;
			switch (patternType) {
				case UPC_EAN_PATTERNS_L_PATTERNS:
					max = L_PATTERNS_LEN;
					for (int i = 0; i < max; i++) {
						int pattern[countersLen];
						for(int j = 0; j< countersLen; j++){
							pattern[j] = L_PATTERNS[i][j];
						}
						
						unsigned int variance = patternMatchVariance(counters, countersLen, pattern, MAX_INDIVIDUAL_VARIANCE);
						if (variance < bestVariance) {
							bestVariance = variance;
							bestMatch = i;
						}
					}
					break;
				case UPC_EAN_PATTERNS_L_AND_G_PATTERNS:
					max = L_AND_G_PATTERNS_LEN;
					for (int i = 0; i < max; i++) {
						int pattern[countersLen];
						for(int j = 0; j< countersLen; j++){
							pattern[j] = L_AND_G_PATTERNS[i][j];
						}
						
						unsigned int variance = patternMatchVariance(counters, countersLen, pattern, MAX_INDIVIDUAL_VARIANCE);
						if (variance < bestVariance) {
							bestVariance = variance;
							bestMatch = i;
						}
					}
					break;
				default:
					break;
			}
			if (bestMatch >= 0) {
				return bestMatch;
			} else {
				throw ReaderException("UPCEANReader::decodeDigit: No best mach");
			}
		}
예제 #5
0
		int* UPCEANReader::findGuardPattern(Ref<BitArray> row, int rowOffset, bool whiteFirst, const int pattern[], int patternLen){
			int patternLength = patternLen;
			
			int counters[patternLength];
			int countersCount = sizeof(counters)/sizeof(int);
			for (int i=0; i<countersCount ; i++) {
				counters[i]=0;
			}
			int width = row->getSize();
			bool isWhite = false;
			while (rowOffset < width) {
				isWhite = !row->get(rowOffset);
				if (whiteFirst == isWhite) {
					break;
				}
				rowOffset++;
			}
			
			int counterPosition = 0;
			int patternStart = rowOffset;
			for (int x = rowOffset; x < width; x++) {
				bool pixel = row->get(x);
				if (pixel ^ isWhite) {
					counters[counterPosition]++;
				} else {
					if (counterPosition == patternLength - 1) {
						if (patternMatchVariance(counters, countersCount, pattern, MAX_INDIVIDUAL_VARIANCE) < MAX_AVG_VARIANCE) {
							int* resultValue = new int[2];
							resultValue[0] = patternStart;
							resultValue[1] = x;
							return resultValue;
						}
						patternStart += counters[0] + counters[1];
						for (int y = 2; y < patternLength; y++) {
							counters[y - 2] = counters[y];
						}
						counters[patternLength - 2] = 0;
						counters[patternLength - 1] = 0;
						counterPosition--;
					} else {
						counterPosition++;
					}
					counters[counterPosition] = 1;
					isWhite = !isWhite;
				}
			}
			throw ReaderException("findGuardPattern");
		}
예제 #6
0
    /**
     * @param row       row of black/white values to search
     * @param rowOffset position to start search
     * @param pattern   pattern of counts of number of black and white pixels that are
     *                  being searched for as a pattern
     * @return start/end horizontal offset of guard pattern, as an array of two
     *         ints
     * @throws ReaderException if pattern is not found
     */
    int* ITFReader::findGuardPattern(Ref<BitArray> row, int rowOffset, const int pattern[],
        int patternLen) {
      // TODO: This is very similar to implementation in UPCEANReader. Consider if they can be
      // merged to a single method.
      int patternLength = patternLen;
      int counters[patternLength];
      for (int i=0; i<patternLength; i++) {
        counters[i] = 0;
      }
      int width = (int)row->getSize();
      bool isWhite = false;

      int counterPosition = 0;
      int patternStart = rowOffset;
      for (int x = rowOffset; x < width; x++) {
        bool pixel = row->get(x);
        if (pixel ^ isWhite) {
          counters[counterPosition]++;
        } else {
          if (counterPosition == patternLength - 1) {
            if (patternMatchVariance(counters, patternLength, pattern,
                MAX_INDIVIDUAL_VARIANCE) < MAX_AVG_VARIANCE) {
              int* resultValue = new int[2];
              resultValue[0] = patternStart;
              resultValue[1] = x;
              return resultValue;
            }
            patternStart += counters[0] + counters[1];
            for (int y = 2; y < patternLength; y++) {
              counters[y - 2] = counters[y];
            }
            counters[patternLength - 2] = 0;
            counters[patternLength - 1] = 0;
            counterPosition--;
          } else {
            counterPosition++;
          }
          counters[counterPosition] = 1;
          isWhite = !isWhite;
        }
      }
      throw ReaderException("");
    }
예제 #7
0
 /**
  * Attempts to decode a sequence of ITF black/white lines into single
  * digit.
  *
  * @param counters the counts of runs of observed black/white/black/... values
  * @return The decoded digit
  * @throws ReaderException if digit cannot be decoded
  */
 int ITFReader::decodeDigit(int counters[], int countersLen){
   unsigned int bestVariance = MAX_AVG_VARIANCE; // worst variance we'll accept
   int bestMatch = -1;
   int max = PATTERNS_LEN;
   for (int i = 0; i < max; i++) {
     int pattern[countersLen];
     for(int ind = 0; ind<countersLen; ind++){
       pattern[ind] = PATTERNS[i][ind];
     }
     unsigned int variance = patternMatchVariance(counters, countersLen, pattern,
         MAX_INDIVIDUAL_VARIANCE);
     if (variance < bestVariance) {
       bestVariance = variance;
       bestMatch = i;
     }
   }
   if (bestMatch >= 0) {
     return bestMatch;
   } else {
     throw ReaderException("digit didint found");
   }
 }