More x, y cleanup and 100 column fixes.

git-svn-id: https://zxing.googlecode.com/svn/trunk@1017 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
dswitkin 2009-07-08 21:17:52 +00:00
parent 402880798c
commit 54e6ed418a
3 changed files with 76 additions and 74 deletions

View file

@ -40,22 +40,22 @@ public final class DefaultGridSampler extends GridSampler {
BitMatrix bits = new BitMatrix(dimension); BitMatrix bits = new BitMatrix(dimension);
float[] points = new float[dimension << 1]; float[] points = new float[dimension << 1];
for (int i = 0; i < dimension; i++) { for (int y = 0; y < dimension; y++) {
int max = points.length; int max = points.length;
float iValue = (float) i + 0.5f; float iValue = (float) y + 0.5f;
for (int j = 0; j < max; j += 2) { for (int x = 0; x < max; x += 2) {
points[j] = (float) (j >> 1) + 0.5f; points[x] = (float) (x >> 1) + 0.5f;
points[j + 1] = iValue; points[x + 1] = iValue;
} }
transform.transformPoints(points); transform.transformPoints(points);
// Quick check to see if points transformed to something inside the image; // Quick check to see if points transformed to something inside the image;
// sufficient to check the endpoints // sufficient to check the endpoints
checkAndNudgePoints(image, points); checkAndNudgePoints(image, points);
try { try {
for (int j = 0; j < max; j += 2) { for (int x = 0; x < max; x += 2) {
if (image.get((int) points[j], (int) points[j + 1])) { if (image.get((int) points[x], (int) points[x + 1])) {
// Black(-ish) pixel // Black(-ish) pixel
bits.set(j >> 1, i); bits.set(x >> 1, y);
} }
} }
} catch (ArrayIndexOutOfBoundsException aioobe) { } catch (ArrayIndexOutOfBoundsException aioobe) {

View file

@ -138,25 +138,25 @@ public final class GlobalHistogramBinarizer extends Binarizer {
int maxBucketCount = 0; int maxBucketCount = 0;
int firstPeak = 0; int firstPeak = 0;
int firstPeakSize = 0; int firstPeakSize = 0;
for (int i = 0; i < numBuckets; i++) { for (int x = 0; x < numBuckets; x++) {
if (buckets[i] > firstPeakSize) { if (buckets[x] > firstPeakSize) {
firstPeak = i; firstPeak = x;
firstPeakSize = buckets[i]; firstPeakSize = buckets[x];
} }
if (buckets[i] > maxBucketCount) { if (buckets[x] > maxBucketCount) {
maxBucketCount = buckets[i]; maxBucketCount = buckets[x];
} }
} }
// Find the second-tallest peak which is somewhat far from the tallest peak. // Find the second-tallest peak which is somewhat far from the tallest peak.
int secondPeak = 0; int secondPeak = 0;
int secondPeakScore = 0; int secondPeakScore = 0;
for (int i = 0; i < numBuckets; i++) { for (int x = 0; x < numBuckets; x++) {
int distanceToBiggest = i - firstPeak; int distanceToBiggest = x - firstPeak;
// Encourage more distant second peaks by multiplying by square of distance. // Encourage more distant second peaks by multiplying by square of distance.
int score = buckets[i] * distanceToBiggest * distanceToBiggest; int score = buckets[x] * distanceToBiggest * distanceToBiggest;
if (score > secondPeakScore) { if (score > secondPeakScore) {
secondPeak = i; secondPeak = x;
secondPeakScore = score; secondPeakScore = score;
} }
} }
@ -179,11 +179,11 @@ public final class GlobalHistogramBinarizer extends Binarizer {
// Find a valley between them that is low and closer to the white peak. // Find a valley between them that is low and closer to the white peak.
int bestValley = secondPeak - 1; int bestValley = secondPeak - 1;
int bestValleyScore = -1; int bestValleyScore = -1;
for (int i = secondPeak - 1; i > firstPeak; i--) { for (int x = secondPeak - 1; x > firstPeak; x--) {
int fromFirst = i - firstPeak; int fromFirst = x - firstPeak;
int score = fromFirst * fromFirst * (secondPeak - i) * (maxBucketCount - buckets[i]); int score = fromFirst * fromFirst * (secondPeak - x) * (maxBucketCount - buckets[x]);
if (score > bestValleyScore) { if (score > bestValleyScore) {
bestValley = i; bestValley = x;
bestValleyScore = score; bestValleyScore = score;
} }
} }

View file

@ -52,28 +52,29 @@ public final class MonochromeRectangleDetector {
int width = image.getWidth(); int width = image.getWidth();
int halfHeight = height >> 1; int halfHeight = height >> 1;
int halfWidth = width >> 1; int halfWidth = width >> 1;
int iSkip = Math.max(1, height / (MAX_MODULES << 3)); int deltaY = Math.max(1, height / (MAX_MODULES << 3));
int jSkip = Math.max(1, width / (MAX_MODULES << 3)); int deltaX = Math.max(1, width / (MAX_MODULES << 3));
int top = 0;
int bottom = height;
int left = 0;
int right = width;
ResultPoint pointA = findCornerFromCenter(halfWidth, 0, left, right,
halfHeight, -deltaY, top, bottom, halfWidth >> 1);
top = (int) pointA.getY() - 1;
ResultPoint pointB = findCornerFromCenter(halfWidth, -deltaX, left, right,
halfHeight, 0, top, bottom, halfHeight >> 1);
left = (int) pointB.getX() - 1;
ResultPoint pointC = findCornerFromCenter(halfWidth, deltaX, left, right,
halfHeight, 0, top, bottom, halfHeight >> 1);
right = (int) pointC.getX() + 1;
ResultPoint pointD = findCornerFromCenter(halfWidth, 0, left, right,
halfHeight, deltaY, top, bottom, halfWidth >> 1);
bottom = (int) pointD.getY() + 1;
int minI = 0;
int maxI = height;
int minJ = 0;
int maxJ = width;
ResultPoint pointA = findCornerFromCenter(halfHeight, -iSkip, minI, maxI, halfWidth, 0,
minJ, maxJ, halfWidth >> 1);
minI = (int) pointA.getY() - 1;
ResultPoint pointB = findCornerFromCenter(halfHeight, 0, minI, maxI, halfWidth, -jSkip,
minJ, maxJ, halfHeight >> 1);
minJ = (int) pointB.getX() - 1;
ResultPoint pointC = findCornerFromCenter(halfHeight, 0, minI, maxI, halfWidth, jSkip,
minJ, maxJ, halfHeight >> 1);
maxJ = (int) pointC.getX() + 1;
ResultPoint pointD = findCornerFromCenter(halfHeight, iSkip, minI, maxI, halfWidth, 0,
minJ, maxJ, halfWidth >> 1);
maxI = (int) pointD.getY() + 1;
// Go try to find point A again with better information -- might have been off at first. // Go try to find point A again with better information -- might have been off at first.
pointA = findCornerFromCenter(halfHeight, -iSkip, minI, maxI, halfWidth, 0, minJ, maxJ, pointA = findCornerFromCenter(halfWidth, 0, left, right,
halfWidth >> 2); halfHeight, -deltaY, top, bottom, halfWidth >> 2);
return new ResultPoint[] { pointA, pointB, pointC, pointD }; return new ResultPoint[] { pointA, pointB, pointC, pointD };
} }
@ -82,60 +83,59 @@ public final class MonochromeRectangleDetector {
* Attempts to locate a corner of the barcode by scanning up, down, left or right from a center * Attempts to locate a corner of the barcode by scanning up, down, left or right from a center
* point which should be within the barcode. * point which should be within the barcode.
* *
* @param centerI center's i componennt (vertical) * @param centerX center's x component (horizontal)
* @param di change in i per step. If scanning up this is negative; down, positive; * @param deltaX same as deltaY but change in x per step instead
* @param left minimum value of x
* @param right maximum value of x
* @param centerY center's y component (vertical)
* @param deltaY change in y per step. If scanning up this is negative; down, positive;
* left or right, 0 * left or right, 0
* @param minI minimum value of i to search through (meaningless when di == 0) * @param top minimum value of y to search through (meaningless when di == 0)
* @param maxI maximum value of i * @param bottom maximum value of y
* @param centerJ center's j component (horizontal)
* @param dj same as di but change in j per step instead
* @param minJ see minI
* @param maxJ see minJ
* @param maxWhiteRun maximum run of white pixels that can still be considered to be within * @param maxWhiteRun maximum run of white pixels that can still be considered to be within
* the barcode * the barcode
* @return a {@link com.google.zxing.ResultPoint} encapsulating the corner that was found * @return a {@link com.google.zxing.ResultPoint} encapsulating the corner that was found
* @throws com.google.zxing.ReaderException if such a point cannot be found * @throws com.google.zxing.ReaderException if such a point cannot be found
*/ */
private ResultPoint findCornerFromCenter(int centerI, int di, int minI, int maxI, private ResultPoint findCornerFromCenter(int centerX, int deltaX, int left, int right,
int centerJ, int dj, int minJ, int maxJ, int centerY, int deltaY, int top, int bottom, int maxWhiteRun) throws ReaderException {
int maxWhiteRun) throws ReaderException {
int[] lastRange = null; int[] lastRange = null;
for (int i = centerI, j = centerJ; for (int y = centerY, x = centerX;
i < maxI && i >= minI && j < maxJ && j >= minJ; y < bottom && y >= top && x < right && x >= left;
i += di, j += dj) { y += deltaY, x += deltaX) {
int[] range; int[] range;
if (dj == 0) { if (deltaX == 0) {
// horizontal slices, up and down // horizontal slices, up and down
range = blackWhiteRange(i, maxWhiteRun, minJ, maxJ, true); range = blackWhiteRange(y, maxWhiteRun, left, right, true);
} else { } else {
// vertical slices, left and right // vertical slices, left and right
range = blackWhiteRange(j, maxWhiteRun, minI, maxI, false); range = blackWhiteRange(x, maxWhiteRun, top, bottom, false);
} }
if (range == null) { if (range == null) {
if (lastRange == null) { if (lastRange == null) {
throw ReaderException.getInstance(); throw ReaderException.getInstance();
} }
// lastRange was found // lastRange was found
if (dj == 0) { if (deltaX == 0) {
int lastI = i - di; int lastY = y - deltaY;
if (lastRange[0] < centerJ) { if (lastRange[0] < centerX) {
if (lastRange[1] > centerJ) { if (lastRange[1] > centerX) {
// straddle, choose one or the other based on direction // straddle, choose one or the other based on direction
return new ResultPoint(di > 0 ? lastRange[0] : lastRange[1], lastI); return new ResultPoint(deltaY > 0 ? lastRange[0] : lastRange[1], lastY);
} }
return new ResultPoint(lastRange[0], lastI); return new ResultPoint(lastRange[0], lastY);
} else { } else {
return new ResultPoint(lastRange[1], lastI); return new ResultPoint(lastRange[1], lastY);
} }
} else { } else {
int lastJ = j - dj; int lastX = x - deltaX;
if (lastRange[0] < centerI) { if (lastRange[0] < centerY) {
if (lastRange[1] > centerI) { if (lastRange[1] > centerY) {
return new ResultPoint(lastJ, dj < 0 ? lastRange[0] : lastRange[1]); return new ResultPoint(lastX, deltaX < 0 ? lastRange[0] : lastRange[1]);
} }
return new ResultPoint(lastJ, lastRange[0]); return new ResultPoint(lastX, lastRange[0]);
} else { } else {
return new ResultPoint(lastJ, lastRange[1]); return new ResultPoint(lastX, lastRange[1]);
} }
} }
} }
@ -172,7 +172,8 @@ public final class MonochromeRectangleDetector {
int whiteRunStart = start; int whiteRunStart = start;
do { do {
start--; start--;
} while (start >= minDim && !(horizontal ? image.get(start, fixedDimension) : image.get(fixedDimension, start))); } while (start >= minDim && !(horizontal ? image.get(start, fixedDimension) :
image.get(fixedDimension, start)));
int whiteRunSize = whiteRunStart - start; int whiteRunSize = whiteRunStart - start;
if (start < minDim || whiteRunSize > maxWhiteRun) { if (start < minDim || whiteRunSize > maxWhiteRun) {
start = whiteRunStart; start = whiteRunStart;
@ -191,7 +192,8 @@ public final class MonochromeRectangleDetector {
int whiteRunStart = end; int whiteRunStart = end;
do { do {
end++; end++;
} while (end < maxDim && !(horizontal ? image.get(end, fixedDimension) : image.get(fixedDimension, end))); } while (end < maxDim && !(horizontal ? image.get(end, fixedDimension) :
image.get(fixedDimension, end)));
int whiteRunSize = end - whiteRunStart; int whiteRunSize = end - whiteRunStart;
if (end >= maxDim || whiteRunSize > maxWhiteRun) { if (end >= maxDim || whiteRunSize > maxWhiteRun) {
end = whiteRunStart; end = whiteRunStart;