FinderPatternFinder.java (zxing-zxing-3.4.0) | : | FinderPatternFinder.java (zxing-zxing-3.4.1) | ||
---|---|---|---|---|
skipping to change at line 97 | skipping to change at line 97 | |||
// QR versions regardless of how dense they are. | // QR versions regardless of how dense they are. | |||
int iSkip = (3 * maxI) / (4 * MAX_MODULES); | int iSkip = (3 * maxI) / (4 * MAX_MODULES); | |||
if (iSkip < MIN_SKIP || tryHarder) { | if (iSkip < MIN_SKIP || tryHarder) { | |||
iSkip = MIN_SKIP; | iSkip = MIN_SKIP; | |||
} | } | |||
boolean done = false; | boolean done = false; | |||
int[] stateCount = new int[5]; | int[] stateCount = new int[5]; | |||
for (int i = iSkip - 1; i < maxI && !done; i += iSkip) { | for (int i = iSkip - 1; i < maxI && !done; i += iSkip) { | |||
// Get a row of black/white values | // Get a row of black/white values | |||
clearCounts(stateCount); | doClearCounts(stateCount); | |||
int currentState = 0; | int currentState = 0; | |||
for (int j = 0; j < maxJ; j++) { | for (int j = 0; j < maxJ; j++) { | |||
if (image.get(j, i)) { | if (image.get(j, i)) { | |||
// Black pixel | // Black pixel | |||
if ((currentState & 1) == 1) { // Counting white pixels | if ((currentState & 1) == 1) { // Counting white pixels | |||
currentState++; | currentState++; | |||
} | } | |||
stateCount[currentState]++; | stateCount[currentState]++; | |||
} else { // White pixel | } else { // White pixel | |||
if ((currentState & 1) == 0) { // Counting black pixels | if ((currentState & 1) == 0) { // Counting black pixels | |||
skipping to change at line 133 | skipping to change at line 133 | |||
// it, entire width of center of finder pattern | // it, entire width of center of finder pattern | |||
// Skip by rowSkip, but back off by stateCount[2] (size of last center | // Skip by rowSkip, but back off by stateCount[2] (size of last center | |||
// of pattern we saw) to be conservative, and also back of f by iSkip which | // of pattern we saw) to be conservative, and also back of f by iSkip which | |||
// is about to be re-added | // is about to be re-added | |||
i += rowSkip - stateCount[2] - iSkip; | i += rowSkip - stateCount[2] - iSkip; | |||
j = maxJ - 1; | j = maxJ - 1; | |||
} | } | |||
} | } | |||
} else { | } else { | |||
shiftCounts2(stateCount); | doShiftCounts2(stateCount); | |||
currentState = 3; | currentState = 3; | |||
continue; | continue; | |||
} | } | |||
// Clear state to start looking again | // Clear state to start looking again | |||
currentState = 0; | currentState = 0; | |||
clearCounts(stateCount); | doClearCounts(stateCount); | |||
} else { // No, shift counts back by two | } else { // No, shift counts back by two | |||
shiftCounts2(stateCount); | doShiftCounts2(stateCount); | |||
currentState = 3; | currentState = 3; | |||
} | } | |||
} else { | } else { | |||
stateCount[++currentState]++; | stateCount[++currentState]++; | |||
} | } | |||
} else { // Counting white pixels | } else { // Counting white pixels | |||
stateCount[currentState]++; | stateCount[currentState]++; | |||
} | } | |||
} | } | |||
} | } | |||
skipping to change at line 235 | skipping to change at line 235 | |||
// Allow less than 75% variance from 1-1-3-1-1 proportions | // Allow less than 75% variance from 1-1-3-1-1 proportions | |||
return | return | |||
Math.abs(moduleSize - stateCount[0]) < maxVariance && | Math.abs(moduleSize - stateCount[0]) < maxVariance && | |||
Math.abs(moduleSize - stateCount[1]) < maxVariance && | Math.abs(moduleSize - stateCount[1]) < maxVariance && | |||
Math.abs(3.0f * moduleSize - stateCount[2]) < 3 * maxVarianc e && | Math.abs(3.0f * moduleSize - stateCount[2]) < 3 * maxVarianc e && | |||
Math.abs(moduleSize - stateCount[3]) < maxVariance && | Math.abs(moduleSize - stateCount[3]) < maxVariance && | |||
Math.abs(moduleSize - stateCount[4]) < maxVariance; | Math.abs(moduleSize - stateCount[4]) < maxVariance; | |||
} | } | |||
private int[] getCrossCheckStateCount() { | private int[] getCrossCheckStateCount() { | |||
clearCounts(crossCheckStateCount); | doClearCounts(crossCheckStateCount); | |||
return crossCheckStateCount; | return crossCheckStateCount; | |||
} | } | |||
@Deprecated | ||||
protected final void clearCounts(int[] counts) { | protected final void clearCounts(int[] counts) { | |||
for (int x = 0; x < counts.length; x++) { | doClearCounts(counts); | |||
counts[x] = 0; | ||||
} | ||||
} | } | |||
@Deprecated | ||||
protected final void shiftCounts2(int[] stateCount) { | protected final void shiftCounts2(int[] stateCount) { | |||
doShiftCounts2(stateCount); | ||||
} | ||||
protected static void doClearCounts(int[] counts) { | ||||
Arrays.fill(counts, 0); | ||||
} | ||||
protected static void doShiftCounts2(int[] stateCount) { | ||||
stateCount[0] = stateCount[2]; | stateCount[0] = stateCount[2]; | |||
stateCount[1] = stateCount[3]; | stateCount[1] = stateCount[3]; | |||
stateCount[2] = stateCount[4]; | stateCount[2] = stateCount[4]; | |||
stateCount[3] = 1; | stateCount[3] = 1; | |||
stateCount[4] = 0; | stateCount[4] = 0; | |||
} | } | |||
/** | /** | |||
* After a vertical and horizontal scan finds a potential finder pattern, this method | * After a vertical and horizontal scan finds a potential finder pattern, this method | |||
* "cross-cross-cross-checks" by scanning down diagonally through the center o f the possible | * "cross-cross-cross-checks" by scanning down diagonally through the center o f the possible | |||
skipping to change at line 619 | skipping to change at line 627 | |||
int startSize = possibleCenters.size(); | int startSize = possibleCenters.size(); | |||
if (startSize < 3) { | if (startSize < 3) { | |||
// Couldn't find enough finder patterns | // Couldn't find enough finder patterns | |||
throw NotFoundException.getNotFoundInstance(); | throw NotFoundException.getNotFoundInstance(); | |||
} | } | |||
possibleCenters.sort(moduleComparator); | possibleCenters.sort(moduleComparator); | |||
double distortion = Double.MAX_VALUE; | double distortion = Double.MAX_VALUE; | |||
double[] squares = new double[3]; | ||||
FinderPattern[] bestPatterns = new FinderPattern[3]; | FinderPattern[] bestPatterns = new FinderPattern[3]; | |||
for (int i = 0; i < possibleCenters.size() - 2; i++) { | for (int i = 0; i < possibleCenters.size() - 2; i++) { | |||
FinderPattern fpi = possibleCenters.get(i); | FinderPattern fpi = possibleCenters.get(i); | |||
float minModuleSize = fpi.getEstimatedModuleSize(); | float minModuleSize = fpi.getEstimatedModuleSize(); | |||
for (int j = i + 1; j < possibleCenters.size() - 1; j++) { | for (int j = i + 1; j < possibleCenters.size() - 1; j++) { | |||
FinderPattern fpj = possibleCenters.get(j); | FinderPattern fpj = possibleCenters.get(j); | |||
double squares0 = squaredDistance(fpi, fpj); | double squares0 = squaredDistance(fpi, fpj); | |||
for (int k = j + 1; k < possibleCenters.size(); k++) { | for (int k = j + 1; k < possibleCenters.size(); k++) { | |||
FinderPattern fpk = possibleCenters.get(k); | FinderPattern fpk = possibleCenters.get(k); | |||
float maxModuleSize = fpk.getEstimatedModuleSize(); | float maxModuleSize = fpk.getEstimatedModuleSize(); | |||
if (maxModuleSize > minModuleSize * 1.4f) { | if (maxModuleSize > minModuleSize * 1.4f) { | |||
// module size is not similar | // module size is not similar | |||
continue; | continue; | |||
} | } | |||
squares[0] = squares0; | double a = squares0; | |||
squares[1] = squaredDistance(fpj, fpk); | double b = squaredDistance(fpj, fpk); | |||
squares[2] = squaredDistance(fpi, fpk); | double c = squaredDistance(fpi, fpk); | |||
Arrays.sort(squares); | ||||
// sorts ascending - inlined | ||||
if (a < b) { | ||||
if (b > c) { | ||||
if (a < c) { | ||||
double temp = b; | ||||
b = c; | ||||
c = temp; | ||||
} else { | ||||
double temp = a; | ||||
a = c; | ||||
c = b; | ||||
b = temp; | ||||
} | ||||
} | ||||
} else { | ||||
if (b < c) { | ||||
if (a < c) { | ||||
double temp = a; | ||||
a = b; | ||||
b = temp; | ||||
} else { | ||||
double temp = a; | ||||
a = b; | ||||
b = c; | ||||
c = temp; | ||||
} | ||||
} else { | ||||
double temp = a; | ||||
a = c; | ||||
c = temp; | ||||
} | ||||
} | ||||
// a^2 + b^2 = c^2 (Pythagorean theorem), and a = b (isosceles triangl e). | // a^2 + b^2 = c^2 (Pythagorean theorem), and a = b (isosceles triangl e). | |||
// Since any right triangle satisfies the formula c^2 - b^2 - a^2 = 0, | // Since any right triangle satisfies the formula c^2 - b^2 - a^2 = 0, | |||
// we need to check both two equal sides separately. | // we need to check both two equal sides separately. | |||
// The value of |c^2 - 2 * b^2| + |c^2 - 2 * a^2| increases as dissimi larity | // The value of |c^2 - 2 * b^2| + |c^2 - 2 * a^2| increases as dissimi larity | |||
// from isosceles right triangle. | // from isosceles right triangle. | |||
double d = Math.abs(squares[2] - 2 * squares[1]) + Math.abs(squares[2] - 2 * squares[0]); | double d = Math.abs(c - 2 * b) + Math.abs(c - 2 * a); | |||
if (d < distortion) { | if (d < distortion) { | |||
distortion = d; | distortion = d; | |||
bestPatterns[0] = fpi; | bestPatterns[0] = fpi; | |||
bestPatterns[1] = fpj; | bestPatterns[1] = fpj; | |||
bestPatterns[2] = fpk; | bestPatterns[2] = fpk; | |||
} | } | |||
} | } | |||
} | } | |||
} | } | |||
End of changes. 12 change blocks. | ||||
14 lines changed or deleted | 53 lines changed or added |