X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;f=core%2Fsrc%2Fcom%2Fgoogle%2Fzxing%2Fqrcode%2Fdetector%2FFinderPatternFinder.java;h=199b895a854257d4f2b941a5f470551c249c8353;hb=abe15d5bb8bd23019ca9c4ab48f9385c6a92bd0e;hp=9d3855809a04c1f2423bbc1346e3fea0c5861c29;hpb=88e5e1bed654d322da10c394d7f6ce6944528189;p=zxing.git diff --git a/core/src/com/google/zxing/qrcode/detector/FinderPatternFinder.java b/core/src/com/google/zxing/qrcode/detector/FinderPatternFinder.java index 9d385580..199b895a 100755 --- a/core/src/com/google/zxing/qrcode/detector/FinderPatternFinder.java +++ b/core/src/com/google/zxing/qrcode/detector/FinderPatternFinder.java @@ -463,7 +463,7 @@ public class FinderPatternFinder { // OK, we have at least 3 confirmed centers, but, it's possible that one is a "false positive" // and that we need to keep looking. We detect this by asking if the estimated module sizes // vary too much. We arbitrarily say that when the total deviation from average exceeds - // 15% of the total module size estimates, it's too much. + // 5% of the total module size estimates, it's too much. float average = totalModuleSize / (float) max; float totalDeviation = 0.0f; for (int i = 0; i < max; i++) { @@ -480,33 +480,34 @@ public class FinderPatternFinder { * @throws ReaderException if 3 such finder patterns do not exist */ private FinderPattern[] selectBestPatterns() throws ReaderException { - Collections.insertionSort(possibleCenters, new CenterComparator()); - int size = 0; - int max = possibleCenters.size(); - while (size < max) { - if (((FinderPattern) possibleCenters.elementAt(size)).getCount() < CENTER_QUORUM) { - break; - } - size++; - } - if (size < 3) { + int startSize = possibleCenters.size(); + if (startSize < 3) { // Couldn't find enough finder patterns throw ReaderException.getInstance(); } - if (size > 3) { - // Throw away all but those first size candidate points we found. - possibleCenters.setSize(size); - // We need to pick the best three. Find the most - // popular ones whose module size is nearest the average - float averageModuleSize = 0.0f; - for (int i = 0; i < size; i++) { - averageModuleSize += ((FinderPattern) possibleCenters.elementAt(i)).getEstimatedModuleSize(); + // Filter outlier possibilities whose module size is too different + if (startSize > 3) { + // But we can only afford to do so if we have at least 4 possibilities to choose from + float totalModuleSize = 0.0f; + for (int i = 0; i < startSize; i++) { + totalModuleSize += ((FinderPattern) possibleCenters.get(i)).getEstimatedModuleSize(); } - averageModuleSize /= (float) size; - // We don't have java.util.Collections in J2ME - Collections.insertionSort(possibleCenters, new ClosestToAverageComparator(averageModuleSize)); + float average = totalModuleSize / (float) startSize; + for (int i = 0; i < possibleCenters.size() && possibleCenters.size() > 3; i++) { + FinderPattern pattern = (FinderPattern) possibleCenters.get(i); + if (Math.abs(pattern.getEstimatedModuleSize() - average) > 0.2f * average) { + possibleCenters.remove(i); + i--; + } + } + } + + if (possibleCenters.size() > 3) { + // Throw away all but those first size candidate points we found. + Collections.insertionSort(possibleCenters, new CenterComparator()); + possibleCenters.setSize(3); } return new FinderPattern[]{ @@ -525,22 +526,4 @@ public class FinderPatternFinder { } } - /** - *

Orders by variance from average module size, ascending.

- */ - private static class ClosestToAverageComparator implements Comparator { - private final float averageModuleSize; - - private ClosestToAverageComparator(float averageModuleSize) { - this.averageModuleSize = averageModuleSize; - } - - public int compare(Object center1, Object center2) { - return Math.abs(((FinderPattern) center1).getEstimatedModuleSize() - averageModuleSize) < - Math.abs(((FinderPattern) center2).getEstimatedModuleSize() - averageModuleSize) ? - -1 : - 1; - } - } - }