Changed the 2D histogram calculation to sample four rows spread across the image...
[zxing.git] / core / src / com / google / zxing / common / BlackPointEstimator.java
index 9fdc04b..0520d10 100644 (file)
@@ -25,8 +25,7 @@ import com.google.zxing.ReaderException;
  * which is the best line between "white" and "black" in a grayscale image.</p>\r
  *\r
  * <p>For an interesting discussion of this issue, see\r
- * <a href="http://webdiis.unizar.es/~neira/12082/thresholding.pdf">http://webdiis.unizar.es/~neira/12082/thresholding.pdf</a>.\r
- * </p>\r
+ * <a href="http://webdiis.unizar.es/~neira/12082/thresholding.pdf">this paper</a>.</p>\r
  *\r
  * NOTE: This class is not threadsafe.\r
  *\r
@@ -74,21 +73,26 @@ public final class BlackPointEstimator {
     initArrays(width);\r
 \r
     if (method.equals(BlackPointEstimationMethod.TWO_D_SAMPLING)) {\r
-      int minDimension = width < height ? width : height;\r
-      int startX = (width - minDimension) >> 1;\r
-      int startY = (height - minDimension) >> 1;\r
-      for (int n = 0; n < minDimension; n++) {\r
-        int luminance = source.getLuminance(startX + n, startY + n);\r
-        histogram[luminance >> LUMINANCE_SHIFT]++;\r
+      // We used to sample a diagonal in the 2D case, but it missed a lot of pixels, and it required\r
+      // n calls to getLuminance(). We had a net improvement of 63 blackbox tests decoded by\r
+      // sampling several rows from the middle of the image, using getLuminanceRow(). We read more\r
+      // pixels total, but with fewer function calls, and more continguous memory.\r
+      for (int y = 1; y < 5; y++) {\r
+        int row = height * y / 5;\r
+        int[] localLuminances = source.getLuminanceRow(row, luminances);\r
+        int right = width * 4 / 5;\r
+        for (int x = width / 5; x < right; x++) {\r
+          histogram[localLuminances[x] >> LUMINANCE_SHIFT]++;\r
+        }\r
       }\r
     } else if (method.equals(BlackPointEstimationMethod.ROW_SAMPLING)) {\r
       if (argument < 0 || argument >= height) {\r
         throw new IllegalArgumentException("Row is not within the image: " + argument);\r
       }\r
 \r
-      luminances = source.getLuminanceRow(argument, luminances);\r
+      int[] localLuminances = source.getLuminanceRow(argument, luminances);\r
       for (int x = 0; x < width; x++) {\r
-        histogram[luminances[x] >> LUMINANCE_SHIFT]++;\r
+        histogram[localLuminances[x] >> LUMINANCE_SHIFT]++;\r
       }\r
     } else {\r
       throw new IllegalArgumentException("Unknown method");\r