mirror of
https://github.com/zxing/zxing.git
synced 2025-03-05 20:48:51 -08:00
Try more possible finder patterns, but be stricter about vetting them. Produces about a 30% increase in accuracy on our test cases.
git-svn-id: https://zxing.googlecode.com/svn/trunk@244 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
parent
e3d418f458
commit
c82d0790c3
|
@ -164,7 +164,7 @@ final class AlignmentPatternFinder {
|
|||
*/
|
||||
private boolean foundPatternCross(int[] stateCount) {
|
||||
float moduleSize = this.moduleSize;
|
||||
float maxVariance = moduleSize / 2.5f;
|
||||
float maxVariance = moduleSize / 2.0f;
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (Math.abs(moduleSize - stateCount[i]) >= maxVariance) {
|
||||
return false;
|
||||
|
@ -184,7 +184,7 @@ final class AlignmentPatternFinder {
|
|||
* observed in any reading state, based on the results of the horizontal scan
|
||||
* @return vertical center of alignment pattern, or {@link Float#NaN} if not found
|
||||
*/
|
||||
private float crossCheckVertical(int startI, int centerJ, int maxCount) {
|
||||
private float crossCheckVertical(int startI, int centerJ, int maxCount, int originalStateCountTotal) {
|
||||
MonochromeBitmapSource image = this.image;
|
||||
|
||||
int maxI = image.getHeight();
|
||||
|
@ -225,6 +225,11 @@ final class AlignmentPatternFinder {
|
|||
return Float.NaN;
|
||||
}
|
||||
|
||||
int stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2];
|
||||
if (5 * Math.abs(stateCountTotal - originalStateCountTotal) >= originalStateCountTotal) {
|
||||
return Float.NaN;
|
||||
}
|
||||
|
||||
return foundPatternCross(stateCount) ? centerFromEnd(stateCount, i) : Float.NaN;
|
||||
}
|
||||
|
||||
|
@ -240,8 +245,9 @@ final class AlignmentPatternFinder {
|
|||
* @return {@link AlignmentPattern} if we have found the same pattern twice, or null if not
|
||||
*/
|
||||
private AlignmentPattern handlePossibleCenter(int[] stateCount, int i, int j) {
|
||||
int stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2];
|
||||
float centerJ = centerFromEnd(stateCount, j);
|
||||
float centerI = crossCheckVertical(i, (int) centerJ, 2 * stateCount[1]);
|
||||
float centerI = crossCheckVertical(i, (int) centerJ, 2 * stateCount[1], stateCountTotal);
|
||||
if (!Float.isNaN(centerI)) {
|
||||
float estimatedModuleSize = (float) (stateCount[0] + stateCount[1] + stateCount[2]) / 3.0f;
|
||||
int max = possibleCenters.size();
|
||||
|
|
|
@ -62,14 +62,14 @@ public final class Detector {
|
|||
Version provisionalVersion = Version.getProvisionalVersionForDimension(dimension);
|
||||
int modulesBetweenFPCenters = provisionalVersion.getDimensionForVersion() - 7;
|
||||
|
||||
// Guess where a "bottom right" finder pattern would have been
|
||||
float bottomRightX = topRight.getX() - topLeft.getX() + bottomLeft.getX();
|
||||
float bottomRightY = topRight.getY() - topLeft.getY() + bottomLeft.getY();
|
||||
|
||||
AlignmentPattern alignmentPattern = null;
|
||||
// Anything above version 1 has an alignment pattern
|
||||
if (provisionalVersion.getAlignmentPatternCenters().length > 0) {
|
||||
|
||||
// Guess where a "bottom right" finder pattern would have been
|
||||
float bottomRightX = topRight.getX() - topLeft.getX() + bottomLeft.getX();
|
||||
float bottomRightY = topRight.getY() - topLeft.getY() + bottomLeft.getY();
|
||||
|
||||
// Estimate that alignment pattern is closer by 3 modules
|
||||
// from "bottom right" to known top left location
|
||||
float correctionToTopLeft = 1.0f - 3.0f / (float) modulesBetweenFPCenters;
|
||||
|
|
|
@ -179,8 +179,8 @@ final class FinderPatternFinder {
|
|||
return false;
|
||||
}
|
||||
float moduleSize = (float) totalModuleSize / 7.0f;
|
||||
float maxVariance = moduleSize / 2.5f;
|
||||
// Allow less than 40% variance from 1-1-3-1-1 proportions
|
||||
float maxVariance = moduleSize / 2.0f;
|
||||
// Allow less than 50% variance from 1-1-3-1-1 proportions
|
||||
return Math.abs(moduleSize - stateCount[0]) < maxVariance &&
|
||||
Math.abs(moduleSize - stateCount[1]) < maxVariance &&
|
||||
Math.abs(3.0f * moduleSize - stateCount[2]) < 3.0f * maxVariance &&
|
||||
|
@ -199,7 +199,7 @@ final class FinderPatternFinder {
|
|||
* observed in any reading state, based on the results of the horizontal scan
|
||||
* @return vertical center of finder pattern, or {@link Float#NaN} if not found
|
||||
*/
|
||||
private float crossCheckVertical(int startI, int centerJ, int maxCount) {
|
||||
private float crossCheckVertical(int startI, int centerJ, int maxCount, int originalStateCountTotal) {
|
||||
MonochromeBitmapSource image = this.image;
|
||||
|
||||
int maxI = image.getHeight();
|
||||
|
@ -254,15 +254,22 @@ final class FinderPatternFinder {
|
|||
return Float.NaN;
|
||||
}
|
||||
|
||||
// If we found a finder-pattern-like section, but its size is more than 20% different than
|
||||
// the original, assume it's a false positive
|
||||
int stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2] + stateCount[3] + stateCount[4];
|
||||
if (5 * Math.abs(stateCountTotal - originalStateCountTotal) >= originalStateCountTotal) {
|
||||
return Float.NaN;
|
||||
}
|
||||
|
||||
return foundPatternCross(stateCount) ? centerFromEnd(stateCount, i) : Float.NaN;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Like {@link #crossCheckVertical(int, int, int)}, and in fact is basically identical,
|
||||
* <p>Like {@link #crossCheckVertical(int, int, int, int)}, and in fact is basically identical,
|
||||
* except it reads horizontally instead of vertically. This is used to cross-cross
|
||||
* check a vertical cross check and locate the real center of the alignment pattern.</p>
|
||||
*/
|
||||
private float crossCheckHorizontal(int startJ, int centerI, int maxCount) {
|
||||
private float crossCheckHorizontal(int startJ, int centerI, int maxCount, int originalStateCountTotal) {
|
||||
MonochromeBitmapSource image = this.image;
|
||||
|
||||
int maxJ = image.getWidth();
|
||||
|
@ -314,6 +321,13 @@ final class FinderPatternFinder {
|
|||
return Float.NaN;
|
||||
}
|
||||
|
||||
// If we found a finder-pattern-like section, but its size is significantly different than
|
||||
// the original, assume it's a false positive
|
||||
int stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2] + stateCount[3] + stateCount[4];
|
||||
if (5 * Math.abs(stateCountTotal - originalStateCountTotal) >= originalStateCountTotal) {
|
||||
return Float.NaN;
|
||||
}
|
||||
|
||||
return foundPatternCross(stateCount) ? centerFromEnd(stateCount, j) : Float.NaN;
|
||||
}
|
||||
|
||||
|
@ -336,14 +350,14 @@ final class FinderPatternFinder {
|
|||
private boolean handlePossibleCenter(int[] stateCount,
|
||||
int i,
|
||||
int j) {
|
||||
int stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2] + stateCount[3] + stateCount[4];
|
||||
float centerJ = centerFromEnd(stateCount, j);
|
||||
float centerI = crossCheckVertical(i, (int) centerJ, stateCount[2]);
|
||||
float centerI = crossCheckVertical(i, (int) centerJ, stateCount[2], stateCountTotal);
|
||||
if (!Float.isNaN(centerI)) {
|
||||
// Re-cross check
|
||||
centerJ = crossCheckHorizontal((int) centerJ, (int) centerI, stateCount[2]);
|
||||
centerJ = crossCheckHorizontal((int) centerJ, (int) centerI, stateCount[2], stateCountTotal);
|
||||
if (!Float.isNaN(centerJ)) {
|
||||
float estimatedModuleSize =
|
||||
(float) (stateCount[0] + stateCount[1] + stateCount[2] + stateCount[3] + stateCount[4]) / 7.0f;
|
||||
float estimatedModuleSize = (float) stateCountTotal / 7.0f;
|
||||
boolean found = false;
|
||||
int max = possibleCenters.size();
|
||||
for (int index = 0; index < max; index++) {
|
||||
|
|
Loading…
Reference in a new issue