Adjust formatting on last change. Simplify GridSampler

git-svn-id: https://zxing.googlecode.com/svn/trunk@1618 59b500cc-1b3d-0410-9834-0bbf25fbcc57
This commit is contained in:
srowen 2010-10-07 08:29:41 +00:00
parent 5053864cb3
commit aa6c437d71
6 changed files with 73 additions and 127 deletions

View file

@ -24,7 +24,8 @@ import com.google.zxing.NotFoundException;
public final class DefaultGridSampler extends GridSampler {
public BitMatrix sampleGrid(BitMatrix image,
int dimension,
int dimensionX,
int dimensionY,
float p1ToX, float p1ToY,
float p2ToX, float p2ToY,
float p3ToX, float p3ToY,
@ -38,63 +39,45 @@ public final class DefaultGridSampler extends GridSampler {
p1ToX, p1ToY, p2ToX, p2ToY, p3ToX, p3ToY, p4ToX, p4ToY,
p1FromX, p1FromY, p2FromX, p2FromY, p3FromX, p3FromY, p4FromX, p4FromY);
return sampleGrid(image, dimension, dimension, transform);
return sampleGrid(image, dimensionX, dimensionY, transform);
}
public BitMatrix sampleGrid(BitMatrix image,
int dimensionX,
int dimensionY,
float p1ToX, float p1ToY,
float p2ToX, float p2ToY,
float p3ToX, float p3ToY,
float p4ToX, float p4ToY,
float p1FromX, float p1FromY,
float p2FromX, float p2FromY,
float p3FromX, float p3FromY,
float p4FromX, float p4FromY) throws NotFoundException {
PerspectiveTransform transform = PerspectiveTransform.quadrilateralToQuadrilateral(
p1ToX, p1ToY, p2ToX, p2ToY, p3ToX, p3ToY, p4ToX, p4ToY,
p1FromX, p1FromY, p2FromX, p2FromY, p3FromX, p3FromY, p4FromX, p4FromY);
return sampleGrid(image, dimensionX, dimensionY, transform);
}
public BitMatrix sampleGrid(BitMatrix image,
int dimensionX, int dimensionY,
PerspectiveTransform transform) throws NotFoundException {
BitMatrix bits = new BitMatrix(dimensionX, dimensionY);
float[] points = new float[dimensionX << 1];
for (int y = 0; y < dimensionY; y++) {
int max = points.length;
float iValue = (float) y + 0.5f;
for (int x = 0; x < max; x += 2) {
points[x] = (float) (x >> 1) + 0.5f;
points[x + 1] = iValue;
}
transform.transformPoints(points);
// Quick check to see if points transformed to something inside the image;
// sufficient to check the endpoints
checkAndNudgePoints(image, points);
try {
for (int x = 0; x < max; x += 2) {
if (image.get((int) points[x], (int) points[x + 1])) {
// Black(-ish) pixel
bits.set(x >> 1, y);
}
}
} catch (ArrayIndexOutOfBoundsException aioobe) {
// This feels wrong, but, sometimes if the finder patterns are misidentified, the resulting
// transform gets "twisted" such that it maps a straight line of points to a set of points
// whose endpoints are in bounds, but others are not. There is probably some mathematical
// way to detect this about the transformation that I don't know yet.
// This results in an ugly runtime exception despite our clever checks above -- can't have
// that. We could check each point's coordinates but that feels duplicative. We settle for
// catching and wrapping ArrayIndexOutOfBoundsException.
throw NotFoundException.getNotFoundInstance();
}
}
return bits;
}
int dimensionX,
int dimensionY,
PerspectiveTransform transform) throws NotFoundException {
BitMatrix bits = new BitMatrix(dimensionX, dimensionY);
float[] points = new float[dimensionX << 1];
for (int y = 0; y < dimensionY; y++) {
int max = points.length;
float iValue = (float) y + 0.5f;
for (int x = 0; x < max; x += 2) {
points[x] = (float) (x >> 1) + 0.5f;
points[x + 1] = iValue;
}
transform.transformPoints(points);
// Quick check to see if points transformed to something inside the image;
// sufficient to check the endpoints
checkAndNudgePoints(image, points);
try {
for (int x = 0; x < max; x += 2) {
if (image.get((int) points[x], (int) points[x + 1])) {
// Black(-ish) pixel
bits.set(x >> 1, y);
}
}
} catch (ArrayIndexOutOfBoundsException aioobe) {
// This feels wrong, but, sometimes if the finder patterns are misidentified, the resulting
// transform gets "twisted" such that it maps a straight line of points to a set of points
// whose endpoints are in bounds, but others are not. There is probably some mathematical
// way to detect this about the transformation that I don't know yet.
// This results in an ugly runtime exception despite our clever checks above -- can't have
// that. We could check each point's coordinates but that feels duplicative. We settle for
// catching and wrapping ArrayIndexOutOfBoundsException.
throw NotFoundException.getNotFoundInstance();
}
}
return bits;
}
}

View file

@ -58,40 +58,6 @@ public abstract class GridSampler {
return gridSampler;
}
/**
* <p>Samples an image for a square matrix of bits of the given dimension. This is used to extract
* the black/white modules of a 2D barcode like a QR Code found in an image. Because this barcode
* may be rotated or perspective-distorted, the caller supplies four points in the source image
* that define known points in the barcode, so that the image may be sampled appropriately.</p>
*
* <p>The last eight "from" parameters are four X/Y coordinate pairs of locations of points in
* the image that define some significant points in the image to be sample. For example,
* these may be the location of finder pattern in a QR Code.</p>
*
* <p>The first eight "to" parameters are four X/Y coordinate pairs measured in the destination
* {@link BitMatrix}, from the top left, where the known points in the image given by the "from"
* parameters map to.</p>
*
* <p>These 16 parameters define the transformation needed to sample the image.</p>
*
* @param image image to sample
* @param dimension width/height of {@link BitMatrix} to sample from image
* @return {@link BitMatrix} representing a grid of points sampled from the image within a region
* defined by the "from" parameters
* @throws NotFoundException if image can't be sampled, for example, if the transformation defined
* by the given points is invalid or results in sampling outside the image boundaries
*/
public abstract BitMatrix sampleGrid(BitMatrix image,
int dimension,
float p1ToX, float p1ToY,
float p2ToX, float p2ToY,
float p3ToX, float p3ToY,
float p4ToX, float p4ToY,
float p1FromX, float p1FromY,
float p2FromX, float p2FromY,
float p3FromX, float p3FromY,
float p4FromX, float p4FromY) throws NotFoundException;
/**
* Samples an image for a rectangular matrix of bits of the given dimension.
* @param image image to sample
@ -103,23 +69,21 @@ public abstract class GridSampler {
* by the given points is invalid or results in sampling outside the image boundaries
*/
public abstract BitMatrix sampleGrid(BitMatrix image,
int dimensionX,
int dimensionY,
float p1ToX, float p1ToY,
float p2ToX, float p2ToY,
float p3ToX, float p3ToY,
float p4ToX, float p4ToY,
float p1FromX, float p1FromY,
float p2FromX, float p2FromY,
float p3FromX, float p3FromY,
float p4FromX, float p4FromY) throws NotFoundException;
public BitMatrix sampleGrid(BitMatrix image,
int dimension,
PerspectiveTransform transform) throws NotFoundException {
throw new IllegalStateException(); // Can't use UnsupportedOperationException
}
int dimensionX,
int dimensionY,
float p1ToX, float p1ToY,
float p2ToX, float p2ToY,
float p3ToX, float p3ToY,
float p4ToX, float p4ToY,
float p1FromX, float p1FromY,
float p2FromX, float p2FromY,
float p3FromX, float p3FromY,
float p4FromX, float p4FromY) throws NotFoundException;
public abstract BitMatrix sampleGrid(BitMatrix image,
int dimensionX,
int dimensionY,
PerspectiveTransform transform) throws NotFoundException;
/**
* <p>Checks a set of points that have been transformed to sample points on an image against
@ -136,8 +100,7 @@ public abstract class GridSampler {
* @param points actual points in x1,y1,...,xn,yn form
* @throws NotFoundException if an endpoint is lies outside the image boundaries
*/
protected static void checkAndNudgePoints(BitMatrix image, float[] points)
throws NotFoundException {
protected static void checkAndNudgePoints(BitMatrix image, float[] points) throws NotFoundException {
int width = image.getWidth();
int height = image.getHeight();
// Check and nudge points from start until we see some that are OK:

View file

@ -418,7 +418,6 @@ final class BitMatrixParser {
int sizeDataRegionRow = numDataRegionsRow * dataRegionSizeRows;
int sizeDataRegionColumn = numDataRegionsColumn * dataRegionSizeColumns;
// TODO(bbrown): Make this work with rectangular codes
BitMatrix bitMatrixWithoutAlignment = new BitMatrix(sizeDataRegionColumn, sizeDataRegionRow);
for (int dataRegionRow = 0; dataRegionRow < numDataRegionsRow; ++dataRegionRow) {
int dataRegionRowOffset = dataRegionRow * dataRegionSizeRows;

View file

@ -260,37 +260,35 @@ public final class Detector {
ResultPoint topRight,
int dimension) {
float corr = distance(bottomLeft, bottomRight) / (float)dimension;
float corr = distance(bottomLeft, bottomRight) / (float) dimension;
int norm = distance(topLeft, topRight);
float cos = (topRight.getX() - topLeft.getX()) / norm;
float sin = (topRight.getY() - topLeft.getY()) / norm;
ResultPoint c1 = new ResultPoint(topRight.getX()+corr*cos, topRight.getY()+corr*sin);
ResultPoint c1 = new ResultPoint(topRight.getX() + corr * cos, topRight.getY() + corr * sin);
corr = distance(bottomLeft, bottomRight) / (float)dimension;
corr = distance(bottomLeft, bottomRight) / (float) dimension;
norm = distance(bottomRight, topRight);
cos = (topRight.getX() - bottomRight.getX()) / norm;
sin = (topRight.getY() - bottomRight.getY()) / norm;
ResultPoint c2 = new ResultPoint(topRight.getX()+corr*cos, topRight.getY()+corr*sin);
ResultPoint c2 = new ResultPoint(topRight.getX() + corr * cos, topRight.getY() + corr * sin);
if (!isValid(c1)){
if (isValid(c2)){
if (!isValid(c1)) {
if (isValid(c2)) {
return c2;
}
return null;
} else if (!isValid(c2)){
} else if (!isValid(c2)) {
return c1;
}
int l1 = Math.abs(transitionsBetween(topLeft, c1).getTransitions() - transitionsBetween(bottomRight, c1).getTransitions());
int l2 = Math.abs(transitionsBetween(topLeft, c2).getTransitions() - transitionsBetween(bottomRight, c2).getTransitions());
if (l1 <= l2){
return c1;
}
return c2;
int l1 = Math.abs(transitionsBetween(topLeft, c1).getTransitions() -
transitionsBetween(bottomRight, c1).getTransitions());
int l2 = Math.abs(transitionsBetween(topLeft, c2).getTransitions() -
transitionsBetween(bottomRight, c2).getTransitions());
return l1 <= l2 ? c1 : c2;
}
private boolean isValid(ResultPoint p) {

View file

@ -377,7 +377,10 @@ public final class Detector {
// very corners. So there is no 0.5f here; 0.0f is right.
GridSampler sampler = GridSampler.getInstance();
return sampler.sampleGrid(matrix, dimension, 0.0f, // p1ToX
return sampler.sampleGrid(
matrix,
dimension, dimension,
0.0f, // p1ToX
0.0f, // p1ToY
dimension, // p2ToX
0.0f, // p2ToY

View file

@ -184,7 +184,7 @@ public class Detector {
int dimension) throws NotFoundException {
GridSampler sampler = GridSampler.getInstance();
return sampler.sampleGrid(image, dimension, transform);
return sampler.sampleGrid(image, dimension, dimension, transform);
}
/**