p1ToX, p1ToY, p2ToX, p2ToY, p3ToX, p3ToY, p4ToX, p4ToY,
p1FromX, p1FromY, p2FromX, p2FromY, p3FromX, p3FromY, p4FromX, p4FromY);
+ return sampleGrid(image, dimension, transform);
+ }
+
+ public BitMatrix sampleGrid(BitMatrix image,
+ int dimension,
+ PerspectiveTransform transform) throws ReaderException {
BitMatrix bits = new BitMatrix(dimension);
float[] points = new float[dimension << 1];
for (int y = 0; y < dimension; y++) {
return bits;
}
-}
\ No newline at end of file
+}
float p3FromX, float p3FromY,
float p4FromX, float p4FromY) throws ReaderException;
+ public BitMatrix sampleGrid(BitMatrix image,
+ int dimension,
+ PerspectiveTransform transform) throws ReaderException {
+ throw new UnsupportedOperationException();
+ }
+
+
/**
* <p>Checks a set of points that have been transformed to sample points on an image against
* the image's dimensions to see if the point are even within the image.</p>
*\r
* @author Sean Owen\r
*/\r
-final class PerspectiveTransform {\r
+public final class PerspectiveTransform {\r
\r
private final float a11, a12, a13, a21, a22, a23, a31, a32, a33;\r
\r
this.a33 = a33;\r
}\r
\r
- static PerspectiveTransform quadrilateralToQuadrilateral(float x0, float y0,\r
- float x1, float y1,\r
- float x2, float y2,\r
- float x3, float y3,\r
- float x0p, float y0p,\r
- float x1p, float y1p,\r
- float x2p, float y2p,\r
- float x3p, float y3p) {\r
+ public static PerspectiveTransform quadrilateralToQuadrilateral(float x0, float y0,\r
+ float x1, float y1,\r
+ float x2, float y2,\r
+ float x3, float y3,\r
+ float x0p, float y0p,\r
+ float x1p, float y1p,\r
+ float x2p, float y2p,\r
+ float x3p, float y3p) {\r
\r
PerspectiveTransform qToS = quadrilateralToSquare(x0, y0, x1, y1, x2, y2, x3, y3);\r
PerspectiveTransform sToQ = squareToQuadrilateral(x0p, y0p, x1p, y1p, x2p, y2p, x3p, y3p);\r
return sToQ.times(qToS);\r
}\r
\r
- void transformPoints(float[] points) {\r
+ public void transformPoints(float[] points) {\r
int max = points.length;\r
float a11 = this.a11;\r
float a12 = this.a12;\r
}\r
}\r
\r
- static PerspectiveTransform squareToQuadrilateral(float x0, float y0,\r
- float x1, float y1,\r
- float x2, float y2,\r
- float x3, float y3) {\r
+ /** Convenience method, not optimized for performance. */\r
+ public void transformPoints(float[] xValues, float[] yValues) {\r
+ int n = xValues.length;\r
+ for (int i = 0; i < n; i ++) {\r
+ float x = xValues[i];\r
+ float y = yValues[i];\r
+ float denominator = a13 * x + a23 * y + a33;\r
+ xValues[i] = (a11 * x + a21 * y + a31) / denominator;\r
+ yValues[i] = (a12 * x + a22 * y + a32) / denominator;\r
+ }\r
+ }\r
+\r
+ public static PerspectiveTransform squareToQuadrilateral(float x0, float y0,\r
+ float x1, float y1,\r
+ float x2, float y2,\r
+ float x3, float y3) {\r
float dy2 = y3 - y2;\r
float dy3 = y0 - y1 + y2 - y3;\r
if (dy2 == 0.0f && dy3 == 0.0f) {\r
}\r
}\r
\r
- private static PerspectiveTransform quadrilateralToSquare(float x0, float y0,\r
- float x1, float y1,\r
- float x2, float y2,\r
- float x3, float y3) {\r
+ public static PerspectiveTransform quadrilateralToSquare(float x0, float y0,\r
+ float x1, float y1,\r
+ float x2, float y2,\r
+ float x3, float y3) {\r
// Here, the adjoint serves as the inverse:\r
return squareToQuadrilateral(x0, y0, x1, y1, x2, y2, x3, y3).buildAdjoint();\r
}\r
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.DetectorResult;
import com.google.zxing.common.GridSampler;
+import com.google.zxing.common.PerspectiveTransform;
import com.google.zxing.qrcode.decoder.Version;
import java.util.Hashtable;
return image;
}
+ protected ResultPointCallback getResultPointCallback() {
+ return resultPointCallback;
+ }
+
/**
* <p>Detects a QR Code in an image, simply.</p>
*
// If we didn't find alignment pattern... well try anyway without it
}
- BitMatrix bits = sampleGrid(image, topLeft, topRight, bottomLeft, alignmentPattern, dimension);
+ PerspectiveTransform transform =
+ createTransform(topLeft, topRight, bottomLeft, alignmentPattern, dimension);
+
+ BitMatrix bits = sampleGrid(image, transform, dimension);
ResultPoint[] points;
if (alignmentPattern == null) {
return new DetectorResult(bits, points);
}
- private static BitMatrix sampleGrid(BitMatrix image,
- ResultPoint topLeft,
- ResultPoint topRight,
- ResultPoint bottomLeft,
- ResultPoint alignmentPattern,
- int dimension) throws ReaderException {
+ public PerspectiveTransform createTransform(ResultPoint topLeft,
+ ResultPoint topRight,
+ ResultPoint bottomLeft,
+ ResultPoint alignmentPattern,
+ int dimension) {
float dimMinusThree = (float) dimension - 3.5f;
float bottomRightX;
float bottomRightY;
sourceBottomRightX = sourceBottomRightY = dimMinusThree;
}
- GridSampler sampler = GridSampler.getInstance();
- return sampler.sampleGrid(
- image,
- dimension,
+ PerspectiveTransform transform = PerspectiveTransform.quadrilateralToQuadrilateral(
3.5f,
3.5f,
dimMinusThree,
bottomRightY,
bottomLeft.getX(),
bottomLeft.getY());
+
+ return transform;
+ }
+
+ private static BitMatrix sampleGrid(BitMatrix image,
+ PerspectiveTransform transform,
+ int dimension) throws ReaderException {
+
+ GridSampler sampler = GridSampler.getInstance();
+ return sampler.sampleGrid(image, dimension, transform);
}
/**
* <p>Computes the dimension (number of modules on a size) of the QR Code based on the position
* of the finder patterns and estimated module size.</p>
*/
- private static int computeDimension(ResultPoint topLeft,
- ResultPoint topRight,
- ResultPoint bottomLeft,
+ protected static int computeDimension(ResultPoint topLeft,
+ ResultPoint topRight,
+ ResultPoint bottomLeft,
float moduleSize) throws ReaderException {
int tltrCentersDimension = round(ResultPoint.distance(topLeft, topRight) / moduleSize);
int tlblCentersDimension = round(ResultPoint.distance(topLeft, bottomLeft) / moduleSize);
* <p>Computes an average estimated module size based on estimated derived from the positions
* of the three finder patterns.</p>
*/
- private float calculateModuleSize(ResultPoint topLeft, ResultPoint topRight,
- ResultPoint bottomLeft) {
+ protected float calculateModuleSize(ResultPoint topLeft,
+ ResultPoint topRight,
+ ResultPoint bottomLeft) {
// Take the average
return (calculateModuleSizeOneWay(topLeft, topRight) +
calculateModuleSizeOneWay(topLeft, bottomLeft)) / 2.0f;
* @return {@link AlignmentPattern} if found, or null otherwise
* @throws ReaderException if an unexpected error occurs during detection
*/
- private AlignmentPattern findAlignmentInRegion(float overallEstModuleSize,
- int estAlignmentX,
- int estAlignmentY,
- float allowanceFactor)
+ protected AlignmentPattern findAlignmentInRegion(float overallEstModuleSize,
+ int estAlignmentX,
+ int estAlignmentY,
+ float allowanceFactor)
throws ReaderException {
// Look for an alignment pattern (3 modules in size) around where it
// should be
private static int round(float d) {
return (int) (d + 0.5f);
}
-
}