From: dswitkin Date: Fri, 22 May 2009 20:59:15 +0000 (+0000) Subject: Changed the 2D histogram calculation to sample four rows spread across the image... X-Git-Url: http://git.rot13.org/?p=zxing.git;a=commitdiff_plain;h=7758b4675ce61ebff30db49ad9093bfee0ec7a4a Changed the 2D histogram calculation to sample four rows spread across the image rather than taking a diagonal. We get a net increase of 63 blackbox tests with this change. git-svn-id: http://zxing.googlecode.com/svn/trunk@950 59b500cc-1b3d-0410-9834-0bbf25fbcc57 --- diff --git a/core/src/com/google/zxing/common/BaseMonochromeBitmapSource.java b/core/src/com/google/zxing/common/BaseMonochromeBitmapSource.java index 2e16a73a..06f0513e 100644 --- a/core/src/com/google/zxing/common/BaseMonochromeBitmapSource.java +++ b/core/src/com/google/zxing/common/BaseMonochromeBitmapSource.java @@ -59,15 +59,15 @@ public abstract class BaseMonochromeBitmapSource implements MonochromeBitmapSour // 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) { @@ -78,7 +78,7 @@ public abstract class BaseMonochromeBitmapSource implements MonochromeBitmapSour } } else { for (int x = 0; x < getWidth; x++) { - if (luminances[startX + x] < blackPoint) { + if (localLuminances[startX + x] < blackPoint) { row.set(x); } } @@ -95,11 +95,11 @@ public abstract class BaseMonochromeBitmapSource implements MonochromeBitmapSour // 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); } } diff --git a/core/src/com/google/zxing/common/BlackPointEstimator.java b/core/src/com/google/zxing/common/BlackPointEstimator.java index 9fdc04b6..0520d106 100644 --- a/core/src/com/google/zxing/common/BlackPointEstimator.java +++ b/core/src/com/google/zxing/common/BlackPointEstimator.java @@ -25,8 +25,7 @@ import com.google.zxing.ReaderException; * which is the best line between "white" and "black" in a grayscale image.

* *

For an interesting discussion of this issue, see - * http://webdiis.unizar.es/~neira/12082/thresholding.pdf. - *

+ * this paper.

* * NOTE: This class is not threadsafe. * @@ -74,21 +73,26 @@ public final class BlackPointEstimator { initArrays(width); if (method.equals(BlackPointEstimationMethod.TWO_D_SAMPLING)) { - int minDimension = width < height ? width : height; - int startX = (width - minDimension) >> 1; - int startY = (height - minDimension) >> 1; - for (int n = 0; n < minDimension; n++) { - int luminance = source.getLuminance(startX + n, startY + n); - histogram[luminance >> LUMINANCE_SHIFT]++; + // We used to sample a diagonal in the 2D case, but it missed a lot of pixels, and it required + // n calls to getLuminance(). We had a net improvement of 63 blackbox tests decoded by + // sampling several rows from the middle of the image, using getLuminanceRow(). We read more + // pixels total, but with fewer function calls, and more continguous memory. + for (int y = 1; y < 5; y++) { + int row = height * y / 5; + int[] localLuminances = source.getLuminanceRow(row, luminances); + int right = width * 4 / 5; + for (int x = width / 5; x < right; x++) { + histogram[localLuminances[x] >> LUMINANCE_SHIFT]++; + } } } else if (method.equals(BlackPointEstimationMethod.ROW_SAMPLING)) { if (argument < 0 || argument >= height) { throw new IllegalArgumentException("Row is not within the image: " + argument); } - luminances = source.getLuminanceRow(argument, luminances); + int[] localLuminances = source.getLuminanceRow(argument, luminances); for (int x = 0; x < width; x++) { - histogram[luminances[x] >> LUMINANCE_SHIFT]++; + histogram[localLuminances[x] >> LUMINANCE_SHIFT]++; } } else { throw new IllegalArgumentException("Unknown method"); diff --git a/core/test/src/com/google/zxing/datamatrix/DataMatrixBlackBox2TestCase.java b/core/test/src/com/google/zxing/datamatrix/DataMatrixBlackBox2TestCase.java index bb13f1ca..710bbe7e 100644 --- a/core/test/src/com/google/zxing/datamatrix/DataMatrixBlackBox2TestCase.java +++ b/core/test/src/com/google/zxing/datamatrix/DataMatrixBlackBox2TestCase.java @@ -27,7 +27,7 @@ public final class DataMatrixBlackBox2TestCase extends AbstractBlackBoxTestCase 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); diff --git a/core/test/src/com/google/zxing/qrcode/QRCodeBlackBox1TestCase.java b/core/test/src/com/google/zxing/qrcode/QRCodeBlackBox1TestCase.java index d54168e5..f6b83eaa 100644 --- a/core/test/src/com/google/zxing/qrcode/QRCodeBlackBox1TestCase.java +++ b/core/test/src/com/google/zxing/qrcode/QRCodeBlackBox1TestCase.java @@ -27,9 +27,9 @@ public final class QRCodeBlackBox1TestCase extends AbstractBlackBoxTestCase { 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); } diff --git a/core/test/src/com/google/zxing/qrcode/QRCodeBlackBox2TestCase.java b/core/test/src/com/google/zxing/qrcode/QRCodeBlackBox2TestCase.java index 2ba64ae1..085cbf30 100644 --- a/core/test/src/com/google/zxing/qrcode/QRCodeBlackBox2TestCase.java +++ b/core/test/src/com/google/zxing/qrcode/QRCodeBlackBox2TestCase.java @@ -27,10 +27,10 @@ public final class QRCodeBlackBox2TestCase extends AbstractBlackBoxTestCase { 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 diff --git a/core/test/src/com/google/zxing/qrcode/QRCodeBlackBox3TestCase.java b/core/test/src/com/google/zxing/qrcode/QRCodeBlackBox3TestCase.java index a8b9125d..9440d405 100644 --- a/core/test/src/com/google/zxing/qrcode/QRCodeBlackBox3TestCase.java +++ b/core/test/src/com/google/zxing/qrcode/QRCodeBlackBox3TestCase.java @@ -27,10 +27,10 @@ public final class QRCodeBlackBox3TestCase extends AbstractBlackBoxTestCase { 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 diff --git a/core/test/src/com/google/zxing/qrcode/QRCodeBlackBox4TestCase.java b/core/test/src/com/google/zxing/qrcode/QRCodeBlackBox4TestCase.java index 02168f92..c614aa87 100644 --- a/core/test/src/com/google/zxing/qrcode/QRCodeBlackBox4TestCase.java +++ b/core/test/src/com/google/zxing/qrcode/QRCodeBlackBox4TestCase.java @@ -29,10 +29,10 @@ public final class QRCodeBlackBox4TestCase extends AbstractBlackBoxTestCase { 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