* 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
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