// Reuse the same int array each time
initLuminances();
- luminances = getLuminanceRow(y, luminances);
+ int[] localLuminances = getLuminanceRow(y, luminances);
// If the current decoder calculated the blackPoint based on one row, assume we're trying to
// decode a 1D barcode, and apply some sharpening.
if (lastMethod.equals(BlackPointEstimationMethod.ROW_SAMPLING)) {
- int left = luminances[startX];
- int center = luminances[startX + 1];
+ int left = localLuminances[startX];
+ int center = localLuminances[startX + 1];
for (int x = 1; x < getWidth - 1; x++) {
- int right = luminances[startX + x + 1];
+ int right = localLuminances[startX + x + 1];
// Simple -1 4 -1 box filter with a weight of 2
int luminance = ((center << 2) - left - right) >> 1;
if (luminance < blackPoint) {
}
} else {
for (int x = 0; x < getWidth; x++) {
- if (luminances[startX + x] < blackPoint) {
+ if (localLuminances[startX + x] < blackPoint) {
row.set(x);
}
}
// Reuse the same int array each time
initLuminances();
- luminances = getLuminanceColumn(x, luminances);
+ int[] localLuminances = getLuminanceColumn(x, luminances);
// We don't handle "row sampling" specially here
for (int y = 0; y < getHeight; y++) {
- if (luminances[startY + y] < blackPoint) {
+ if (localLuminances[startY + y] < blackPoint) {
column.set(y);
}
}
* 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
public DataMatrixBlackBox2TestCase() {
// TODO use MultiFormatReader here once Data Matrix decoder is done
super("test/data/blackbox/datamatrix-2", new DataMatrixReader(), BarcodeFormat.DATAMATRIX);
- addTest(3, 3, 0.0f);
+ addTest(2, 2, 0.0f);
addTest(1, 1, 90.0f);
addTest(4, 4, 180.0f);
addTest(3, 3, 270.0f);
public QRCodeBlackBox1TestCase() {
super("test/data/blackbox/qrcode-1", new MultiFormatReader(), BarcodeFormat.QR_CODE);
- addTest(18, 18, 0.0f);
- addTest(14, 14, 90.0f);
- addTest(18, 18, 180.0f);
+ addTest(19, 19, 0.0f);
+ addTest(15, 15, 90.0f);
+ addTest(16, 16, 180.0f);
addTest(13, 14, 270.0f);
}
public QRCodeBlackBox2TestCase() {
super("test/data/blackbox/qrcode-2", new MultiFormatReader(), BarcodeFormat.QR_CODE);
- addTest(22, 22, 0.0f);
- addTest(18, 18, 90.0f);
+ addTest(24, 24, 0.0f);
+ addTest(21, 21, 90.0f);
addTest(22, 22, 180.0f);
- addTest(17, 17, 270.0f);
+ addTest(17, 18, 270.0f);
}
}
\ No newline at end of file
public QRCodeBlackBox3TestCase() {
super("test/data/blackbox/qrcode-3", new MultiFormatReader(), BarcodeFormat.QR_CODE);
- addTest(29, 29, 0.0f);
- addTest(26, 26, 90.0f);
- addTest(30, 30, 180.0f);
- addTest(29, 29, 270.0f);
+ addTest(33, 33, 0.0f);
+ addTest(33, 33, 90.0f);
+ addTest(32, 32, 180.0f);
+ addTest(34, 34, 270.0f);
}
}
\ No newline at end of file
public QRCodeBlackBox4TestCase() {
super("test/data/blackbox/qrcode-4", new MultiFormatReader(), BarcodeFormat.QR_CODE);
- addTest(33, 33, 0.0f);
- addTest(33, 33, 90.0f);
- addTest(32, 32, 180.0f);
- addTest(32, 32, 270.0f);
+ addTest(34, 34, 0.0f);
+ addTest(36, 36, 90.0f);
+ addTest(35, 35, 180.0f);
+ addTest(34, 34, 270.0f);
}
}
\ No newline at end of file