mirror of
https://github.com/zxing/zxing.git
synced 2025-03-05 20:48:51 -08:00
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: https://zxing.googlecode.com/svn/trunk@950 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
parent
825d99786d
commit
ec77a581d2
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,8 +25,7 @@ import com.google.zxing.ReaderException;
|
|||
* which is the best line between "white" and "black" in a grayscale image.</p>
|
||||
*
|
||||
* <p>For an interesting discussion of this issue, see
|
||||
* <a href="http://webdiis.unizar.es/~neira/12082/thresholding.pdf">http://webdiis.unizar.es/~neira/12082/thresholding.pdf</a>.
|
||||
* </p>
|
||||
* <a href="http://webdiis.unizar.es/~neira/12082/thresholding.pdf">this paper</a>.</p>
|
||||
*
|
||||
* 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");
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue