From: srowen Date: Tue, 8 Dec 2009 19:58:01 +0000 (+0000) Subject: Opening up the Detector a little to allow extension, such as per Ralf X-Git-Url: http://git.rot13.org/?p=zxing.git;a=commitdiff_plain;h=4462da54f2f4511aed5654b1ee071429a0c417d5 Opening up the Detector a little to allow extension, such as per Ralf git-svn-id: http://zxing.googlecode.com/svn/trunk@1143 59b500cc-1b3d-0410-9834-0bbf25fbcc57 --- diff --git a/core/src/com/google/zxing/common/DefaultGridSampler.java b/core/src/com/google/zxing/common/DefaultGridSampler.java index 026a0f1b..f0a9e073 100644 --- a/core/src/com/google/zxing/common/DefaultGridSampler.java +++ b/core/src/com/google/zxing/common/DefaultGridSampler.java @@ -38,6 +38,12 @@ 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, 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++) { @@ -72,4 +78,4 @@ public final class DefaultGridSampler extends GridSampler { return bits; } -} \ No newline at end of file +} diff --git a/core/src/com/google/zxing/common/GridSampler.java b/core/src/com/google/zxing/common/GridSampler.java index e7af414a..5f2588fc 100644 --- a/core/src/com/google/zxing/common/GridSampler.java +++ b/core/src/com/google/zxing/common/GridSampler.java @@ -92,6 +92,13 @@ public abstract class GridSampler { float p3FromX, float p3FromY, float p4FromX, float p4FromY) throws ReaderException; + public BitMatrix sampleGrid(BitMatrix image, + int dimension, + PerspectiveTransform transform) throws ReaderException { + throw new UnsupportedOperationException(); + } + + /** *

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.

diff --git a/core/src/com/google/zxing/common/PerspectiveTransform.java b/core/src/com/google/zxing/common/PerspectiveTransform.java index b79e4adc..9e65baff 100644 --- a/core/src/com/google/zxing/common/PerspectiveTransform.java +++ b/core/src/com/google/zxing/common/PerspectiveTransform.java @@ -23,7 +23,7 @@ package com.google.zxing.common; * * @author Sean Owen */ -final class PerspectiveTransform { +public final class PerspectiveTransform { private final float a11, a12, a13, a21, a22, a23, a31, a32, a33; @@ -41,21 +41,21 @@ final class PerspectiveTransform { this.a33 = a33; } - static PerspectiveTransform quadrilateralToQuadrilateral(float x0, float y0, - float x1, float y1, - float x2, float y2, - float x3, float y3, - float x0p, float y0p, - float x1p, float y1p, - float x2p, float y2p, - float x3p, float y3p) { + public static PerspectiveTransform quadrilateralToQuadrilateral(float x0, float y0, + float x1, float y1, + float x2, float y2, + float x3, float y3, + float x0p, float y0p, + float x1p, float y1p, + float x2p, float y2p, + float x3p, float y3p) { PerspectiveTransform qToS = quadrilateralToSquare(x0, y0, x1, y1, x2, y2, x3, y3); PerspectiveTransform sToQ = squareToQuadrilateral(x0p, y0p, x1p, y1p, x2p, y2p, x3p, y3p); return sToQ.times(qToS); } - void transformPoints(float[] points) { + public void transformPoints(float[] points) { int max = points.length; float a11 = this.a11; float a12 = this.a12; @@ -75,10 +75,22 @@ final class PerspectiveTransform { } } - static PerspectiveTransform squareToQuadrilateral(float x0, float y0, - float x1, float y1, - float x2, float y2, - float x3, float y3) { + /** Convenience method, not optimized for performance. */ + public void transformPoints(float[] xValues, float[] yValues) { + int n = xValues.length; + for (int i = 0; i < n; i ++) { + float x = xValues[i]; + float y = yValues[i]; + float denominator = a13 * x + a23 * y + a33; + xValues[i] = (a11 * x + a21 * y + a31) / denominator; + yValues[i] = (a12 * x + a22 * y + a32) / denominator; + } + } + + public static PerspectiveTransform squareToQuadrilateral(float x0, float y0, + float x1, float y1, + float x2, float y2, + float x3, float y3) { float dy2 = y3 - y2; float dy3 = y0 - y1 + y2 - y3; if (dy2 == 0.0f && dy3 == 0.0f) { @@ -99,10 +111,10 @@ final class PerspectiveTransform { } } - private static PerspectiveTransform quadrilateralToSquare(float x0, float y0, - float x1, float y1, - float x2, float y2, - float x3, float y3) { + public static PerspectiveTransform quadrilateralToSquare(float x0, float y0, + float x1, float y1, + float x2, float y2, + float x3, float y3) { // Here, the adjoint serves as the inverse: return squareToQuadrilateral(x0, y0, x1, y1, x2, y2, x3, y3).buildAdjoint(); } diff --git a/core/src/com/google/zxing/qrcode/detector/Detector.java b/core/src/com/google/zxing/qrcode/detector/Detector.java index a8a7d837..ee724404 100644 --- a/core/src/com/google/zxing/qrcode/detector/Detector.java +++ b/core/src/com/google/zxing/qrcode/detector/Detector.java @@ -23,6 +23,7 @@ import com.google.zxing.ResultPointCallback; 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; @@ -46,6 +47,10 @@ public class Detector { return image; } + protected ResultPointCallback getResultPointCallback() { + return resultPointCallback; + } + /** *

Detects a QR Code in an image, simply.

* @@ -117,7 +122,10 @@ public class Detector { // 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) { @@ -128,12 +136,11 @@ public class Detector { 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; @@ -150,10 +157,7 @@ public class Detector { sourceBottomRightX = sourceBottomRightY = dimMinusThree; } - GridSampler sampler = GridSampler.getInstance(); - return sampler.sampleGrid( - image, - dimension, + PerspectiveTransform transform = PerspectiveTransform.quadrilateralToQuadrilateral( 3.5f, 3.5f, dimMinusThree, @@ -170,15 +174,25 @@ public class Detector { 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); } /** *

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.

*/ - 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); @@ -201,8 +215,9 @@ public class Detector { *

Computes an average estimated module size based on estimated derived from the positions * of the three finder patterns.

*/ - 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; @@ -329,10 +344,10 @@ public class Detector { * @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 @@ -365,5 +380,4 @@ public class Detector { private static int round(float d) { return (int) (d + 0.5f); } - }