From b238cb782820a58d8ab62a116532536ad7751b49 Mon Sep 17 00:00:00 2001
From: dswitkin
Date: Thu, 2 Jul 2009 20:07:09 +0000
Subject: [PATCH] I noticed that the codeword coordinates in PDF 417 barcodes
were a few pixels off if there was skew or rotation in the image. I added a
simple method to correct the vertical component of these points, and the
units tests went from 8/23 to 11/23.
git-svn-id: https://zxing.googlecode.com/svn/trunk@1015 59b500cc-1b3d-0410-9834-0bbf25fbcc57
---
.../zxing/pdf417/detector/Detector.java | 53 ++++++++++++++++++-
.../zxing/pdf417/PDF417BlackBox2TestCase.java | 2 +-
2 files changed, 52 insertions(+), 3 deletions(-)
diff --git a/core/src/com/google/zxing/pdf417/detector/Detector.java b/core/src/com/google/zxing/pdf417/detector/Detector.java
index b59bd535d..c4a09d6ff 100644
--- a/core/src/com/google/zxing/pdf417/detector/Detector.java
+++ b/core/src/com/google/zxing/pdf417/detector/Detector.java
@@ -30,11 +30,13 @@ import java.util.Hashtable;
* PDF417 Code is rotated or skewed, or partially obscured.
*
* @author SITA Lab (kevin.osullivan@sita.aero)
+ * @author dswitkin@google.com (Daniel Switkin)
*/
public final class Detector {
- public static final int MAX_AVG_VARIANCE = (int) ((1 << 8) * 0.42f);
- public static final int MAX_INDIVIDUAL_VARIANCE = (int) ((1 << 8) * 0.8f);
+ private static final int MAX_AVG_VARIANCE = (int) ((1 << 8) * 0.42f);
+ private static final int MAX_INDIVIDUAL_VARIANCE = (int) ((1 << 8) * 0.8f);
+ private static final int SKEW_THRESHOLD = 2;
// B S B S B S B S Bar/Space pattern
// 11111111 0 1 0 1 0 1 000
@@ -90,6 +92,7 @@ public final class Detector {
throw ReaderException.getInstance();
}
+ correctCodeWordVertices(vertices);
int dimension = computeDimension(vertices[4], vertices[6],
vertices[5], vertices[7], moduleWidth);
@@ -262,6 +265,52 @@ public final class Detector {
return found ? result : null;
}
+ /**
+ * Because we scan horizontally to detect the start and stop patterns, the vertical component of
+ * the codeword coordinates will be slightly wrong if there is any skew or rotation in the image.
+ * This method moves those points back onto the edges of the theoretically perfect bounding
+ * quadrilateral if needed.
+ *
+ * FIXME: Make this work for 180 degree rotation.
+ *
+ * @param vertices The eight vertices located by findVertices().
+ */
+ private static void correctCodeWordVertices(ResultPoint[] vertices) {
+ float skew = vertices[4].getY() - vertices[6].getY();
+ if (skew > SKEW_THRESHOLD) {
+ // Fix v4
+ float length = vertices[4].getX() - vertices[0].getX();
+ float deltax = vertices[6].getX() - vertices[0].getX();
+ float deltay = vertices[6].getY() - vertices[0].getY();
+ float correction = length * deltay / deltax;
+ vertices[4] = new ResultPoint(vertices[4].getX(), vertices[4].getY() + correction);
+ } else if (-skew > SKEW_THRESHOLD) {
+ // Fix v6
+ float length = vertices[2].getX() - vertices[6].getX();
+ float deltax = vertices[2].getX() - vertices[4].getX();
+ float deltay = vertices[2].getY() - vertices[4].getY();
+ float correction = length * deltay / deltax;
+ vertices[6] = new ResultPoint(vertices[6].getX(), vertices[6].getY() - correction);
+ }
+
+ skew = vertices[7].getY() - vertices[5].getY();
+ if (skew > SKEW_THRESHOLD) {
+ // Fix v5
+ float length = vertices[5].getX() - vertices[1].getX();
+ float deltax = vertices[7].getX() - vertices[1].getX();
+ float deltay = vertices[7].getY() - vertices[1].getY();
+ float correction = length * deltay / deltax;
+ vertices[5] = new ResultPoint(vertices[5].getX(), vertices[5].getY() + correction);
+ } else if (-skew > SKEW_THRESHOLD) {
+ // Fix v7
+ float length = vertices[3].getX() - vertices[7].getX();
+ float deltax = vertices[3].getX() - vertices[5].getX();
+ float deltay = vertices[3].getY() - vertices[5].getY();
+ float correction = length * deltay / deltax;
+ vertices[7] = new ResultPoint(vertices[7].getX(), vertices[7].getY() - correction);
+ }
+ }
+
/**
* Estimates module size (pixels in a module) based on the Start and End
* finder patterns.
diff --git a/core/test/src/com/google/zxing/pdf417/PDF417BlackBox2TestCase.java b/core/test/src/com/google/zxing/pdf417/PDF417BlackBox2TestCase.java
index d63f1f94e..83a9cd0aa 100644
--- a/core/test/src/com/google/zxing/pdf417/PDF417BlackBox2TestCase.java
+++ b/core/test/src/com/google/zxing/pdf417/PDF417BlackBox2TestCase.java
@@ -33,7 +33,7 @@ public final class PDF417BlackBox2TestCase extends AbstractBlackBoxTestCase {
public PDF417BlackBox2TestCase() {
super("test/data/blackbox/pdf417-2", new MultiFormatReader(), BarcodeFormat.PDF417);
- addTest(8, 8, 0.0f);
+ addTest(11, 11, 0.0f);
addTest(9, 9, 180.0f);
}