Fixed the rest of my typos and added basic unit test
authorsrowen <srowen@59b500cc-1b3d-0410-9834-0bbf25fbcc57>
Fri, 9 Nov 2007 22:19:46 +0000 (22:19 +0000)
committersrowen <srowen@59b500cc-1b3d-0410-9834-0bbf25fbcc57>
Fri, 9 Nov 2007 22:19:46 +0000 (22:19 +0000)
git-svn-id: http://zxing.googlecode.com/svn/trunk@23 59b500cc-1b3d-0410-9834-0bbf25fbcc57

core/src/com/google/zxing/qrcode/detector/DefaultGridSampler.java
core/src/com/google/zxing/qrcode/detector/PerspectiveTransform.java
core/test/src/com/google/zxing/qrcode/detector/PerspectiveTransformTestCase.java [new file with mode: 0644]

index 4b71ece..5223d7f 100644 (file)
@@ -77,7 +77,7 @@ public final class DefaultGridSampler extends GridSampler {
       for (int j = 0; j < max; j += 2) {
         if (image.isBlack((int) points[j], (int) points[j + 1])) {
           // Black(-ish) pixel
-          bits.set(i, j);
+          bits.set(i, j >> 1);
         }
       }
     }
index f07f097..5a55d34 100644 (file)
@@ -49,9 +49,11 @@ final class PerspectiveTransform {
                                                            float x1p, float y1p,\r
                                                            float x2p, float y2p,\r
                                                            float x3p, float y3p) {\r
-    return\r
-        quadrilateralToSquare(x0, y0, x1, y1, x2, y2, x3, y3).times(\r
-        squareToQuadrilateral(x0p, y0p, x1p, y1p, x2p, y2p, x3p, 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
+    PerspectiveTransform product = sToQ.times(qToS);\r
+    return product;\r
   }\r
 \r
   void transformPoints(float[] points) {\r
@@ -74,32 +76,31 @@ final class PerspectiveTransform {
     }\r
   }\r
 \r
-  private static PerspectiveTransform squareToQuadrilateral(float x0, float y0,\r
+  static PerspectiveTransform squareToQuadrilateral(float x0, float y0,\r
                                                             float x1, float y1,\r
                                                             float x2, float y2,\r
                                                             float x3, float y3) {\r
-    float dx1 = x1 - x2;\r
-    float dx2 = x3 - x2;\r
-    float dx3 = x0 - x1 + x2 - x3;\r
-    float dy1 = y1 - y2;\r
     float dy2 = y3 - y2;\r
     float dy3 = y0 - y1 + y2 - y3;\r
-    float denominator = dx1*dy2 - dx2*dy1;\r
-    float a13 = (dx3*dy2 - dx2*dy3) / denominator;\r
-    float a23 = (dx1*dy3 - dx3*dy1) / denominator;\r
-\r
-       return new PerspectiveTransform(x1 - x0 + a13*x1,\r
-                                  x3 - x0 + a23*x3,\r
-                                  x0,\r
-                                  y1 - y0 + a13*y1,\r
-                                  y3 - y0 + a23*y3,\r
-                                  y0,\r
-                                  a13,\r
-                                  a23,\r
-                                  1.0f);\r
+    if (dy2 == 0.0f && dy3 == 0.0f) {\r
+      return new PerspectiveTransform(x1 - x0, x2 - x1, x0,\r
+                                      y1 - y0, y2 - y1, y0,\r
+                                      0.0f,    0.0f,    1.0f);\r
+    } else {\r
+      float dx1 = x1 - x2;\r
+      float dx2 = x3 - x2;\r
+      float dx3 = x0 - x1 + x2 - x3;\r
+      float dy1 = y1 - y2;\r
+      float denominator = dx1*dy2 - dx2*dy1;\r
+      float a13 = (dx3*dy2 - dx2*dy3) / denominator;\r
+      float a23 = (dx1*dy3 - dx3*dy1) / denominator;\r
+      return new PerspectiveTransform(x1 - x0 + a13*x1, x3 - x0 + a23*x3, x0,\r
+                                      y1 - y0 + a13*y1, y3 - y0 + a23*y3, y0,\r
+                                      a13,              a23,              1.0f);\r
+    }\r
   }\r
 \r
-  private static PerspectiveTransform quadrilateralToSquare(float x0, float y0,\r
+  static PerspectiveTransform quadrilateralToSquare(float x0, float y0,\r
                                                             float x1, float y1,\r
                                                             float x2, float y2,\r
                                                             float x3, float y3) {\r
@@ -107,7 +108,7 @@ final class PerspectiveTransform {
     return squareToQuadrilateral(x0, y0, x1, y1, x2, y2, x3, y3).buildAdjoint();\r
   }\r
 \r
-  private PerspectiveTransform buildAdjoint() {\r
+  PerspectiveTransform buildAdjoint() {\r
     // Adjoint is the transpose of the cofactor matrix:\r
        return new PerspectiveTransform(a22*a33 - a23*a32,\r
                                   a23*a31 - a21*a33,\r
@@ -120,16 +121,17 @@ final class PerspectiveTransform {
                                   a11*a22 - a12*a21);\r
   }\r
 \r
-  private PerspectiveTransform times(PerspectiveTransform other) {\r
+  PerspectiveTransform times(PerspectiveTransform other) {\r
     return new PerspectiveTransform(a11*other.a11 + a21*other.a12 + a31*other.a13,\r
-                                    a11*other.a12 + a12*other.a22 + a13*other.a32,\r
-                                    a11*other.a13 + a12*other.a23 + a13*other.a33,\r
-                                    a21*other.a11 + a22*other.a21 + a23*other.a31,\r
-                                    a21*other.a12 + a22*other.a22 + a23*other.a32,\r
-                                    a21*other.a13 + a22*other.a23 + a23*other.a33,\r
-                                    a31*other.a11 + a32*other.a21 + a33*other.a31,\r
-                                    a31*other.a12 + a32*other.a22 + a33*other.a33,\r
-                                    a31*other.a13 + a32*other.a23 + a33*other.a33);\r
+                                    a11*other.a21 + a21*other.a22 + a31*other.a23,\r
+                                    a11*other.a31 + a21*other.a32 + a31*other.a33,\r
+                                    a12*other.a11 + a22*other.a12 + a32*other.a13,\r
+                                    a12*other.a21 + a22*other.a22 + a32*other.a23,\r
+                                    a12*other.a31 + a22*other.a32 + a32*other.a33,\r
+                                    a13*other.a11 + a23*other.a12 + a33*other.a13,\r
+                                    a13*other.a21 + a23*other.a22 + a33*other.a23,\r
+                                    a13*other.a31 + a23*other.a32 + a33*other.a33);\r
+\r
   }\r
 \r
 }\r
diff --git a/core/test/src/com/google/zxing/qrcode/detector/PerspectiveTransformTestCase.java b/core/test/src/com/google/zxing/qrcode/detector/PerspectiveTransformTestCase.java
new file mode 100644 (file)
index 0000000..451cd2a
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2007 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.zxing.qrcode.detector;
+
+import junit.framework.TestCase;
+
+/**
+ * @author srowen@google.com (Sean Owen)
+ */
+public final class PerspectiveTransformTestCase extends TestCase {
+
+  private static final float EPSILON = 0.0001f;
+
+  public void testSquareToQuadrilateral() {
+    PerspectiveTransform pt = PerspectiveTransform.squareToQuadrilateral(
+        2.0f, 3.0f, 10.0f, 4.0f, 16.0f, 15.0f, 4.0f, 9.0f);
+    assertPointEquals(2.0f, 3.0f, 0.0f, 0.0f, pt);
+    assertPointEquals(10.0f, 4.0f, 1.0f, 0.0f, pt);
+    assertPointEquals(4.0f, 9.0f, 0.0f, 1.0f, pt);
+    assertPointEquals(16.0f, 15.0f, 1.0f, 1.0f, pt);
+    assertPointEquals(6.535211f, 6.8873234f, 0.5f, 0.5f, pt);
+    assertPointEquals(48.0f, 42.42857f, 1.5f, 1.5f, pt);
+  }
+
+  public void testQuadrilateralToQuadrilateral() {
+    PerspectiveTransform pt = PerspectiveTransform.quadrilateralToQuadrilateral(
+        2.0f, 3.0f, 10.0f, 4.0f, 16.0f, 15.0f, 4.0f, 9.0f,
+        103.0f, 110.0f, 300.0f, 120.0f, 290.0f, 270.0f, 150.0f, 280.0f);
+    assertPointEquals(103.0f, 110.0f, 2.0f, 3.0f, pt);
+    assertPointEquals(300.0f, 120.0f, 10.0f, 4.0f, pt);
+    assertPointEquals(290.0f, 270.0f, 16.0f, 15.0f, pt);
+    assertPointEquals(150.0f, 280.0f, 4.0f, 9.0f, pt);
+    assertPointEquals(7.1516876f, -64.60185f, 0.5f, 0.5f, pt);
+    assertPointEquals(328.09116f, 334.16385f,50.0f, 50.0f, pt);
+  }
+
+  private static void assertPointEquals(float expectedX, float expectedY, float sourceX, float sourceY, PerspectiveTransform pt) {
+    float[] points = new float[] { sourceX, sourceY };
+    pt.transformPoints(points);
+    assertEquals(expectedX, points[0], EPSILON);
+    assertEquals(expectedY, points[1], EPSILON);
+  }
+
+}
\ No newline at end of file