ISSUE: http://code.google.com/p/zxing/issues/detail?id=110
authorkev.sully <kev.sully@59b500cc-1b3d-0410-9834-0bbf25fbcc57>
Fri, 21 Nov 2008 11:25:45 +0000 (11:25 +0000)
committerkev.sully <kev.sully@59b500cc-1b3d-0410-9834-0bbf25fbcc57>
Fri, 21 Nov 2008 11:25:45 +0000 (11:25 +0000)
Changes to fix high nbr of false positives.
- Fixed up the quiet zone checks.
- Validate that the barcode fills the viewfinder
- Check that decoded barcode is min 6 digits

git-svn-id: http://zxing.googlecode.com/svn/trunk@755 59b500cc-1b3d-0410-9834-0bbf25fbcc57

core/src/com/google/zxing/oned/ITFReader.java

index 1ac10db..1dddbab 100644 (file)
@@ -93,7 +93,11 @@ public class ITFReader extends AbstractOneDReader {
                decodeMiddle(row, startRange[1], endRange[0], result);\r
 \r
                String resultString = result.toString();\r
-               if (resultString.length() == 0 || resultString.length() % 2 == 1)\r
+               /**\r
+                * To avoid false positives with 2D barcodes, make\r
+                * an assumption that the decoded string must be at least 6 digits.\r
+                */\r
+               if (resultString.length() < 6 || resultString.length() % 2 == 1)\r
                        throw ReaderException.getInstance();\r
 \r
                return new Result(resultString,\r
@@ -164,20 +168,58 @@ public class ITFReader extends AbstractOneDReader {
                 */\r
                this.narrowLineWidth = (startPattern[1] - startPattern[0]) / 4;\r
 \r
-               /**\r
-                * The start & end patterns must be pre/post fixed by a quiet zone. This\r
-                * zone must be at least 10 times the width of a narrow line.\r
-                * \r
-                * ref: http://www.barcode-1.net/i25code.html\r
-                */\r
-               if (this.narrowLineWidth * 10 > startPattern[0]) {\r
-                       // Unable to find the quiet zone preceeding the start sequence.\r
-                       throw ReaderException.getInstance();\r
-               }\r
+               validateQuietZone(row, startPattern[0]);\r
 \r
                return startPattern;\r
        }\r
 \r
+       /**\r
+        * \r
+        * \r
+        */\r
+       /**\r
+        * \r
+        *      The start & end patterns must be pre/post fixed by a quiet zone. This\r
+        * zone must be at least 10 times the width of a narrow line.  Scan back until\r
+        * we either get to the start of the barcode or match the necessary number of \r
+        * quiet zone pixels.\r
+        * \r
+        * Note: Its assumed the row is reversed when using this method to find\r
+        * quiet zone after the end pattern.\r
+        * \r
+        * ref: http://www.barcode-1.net/i25code.html\r
+        * \r
+        * @param row                                   - The bit array representing the scanned barcode. \r
+        * @param startPattern          - The index into row of the start or end pattern.\r
+        * @throws ReaderException - If the quiet zone cannot be found, a ReaderException is thrown.\r
+        */\r
+       private void validateQuietZone(BitArray row, int startPattern) throws ReaderException {\r
+\r
+               int quietCount=this.narrowLineWidth * 10;       // expect to find this many pixels of quiet zone\r
+               \r
+               int i=0;\r
+               for (i=startPattern-1; quietCount>0 && i>=0; i--)\r
+               {\r
+                       if (row.get(i)==true)\r
+                               break;\r
+                       quietCount--;\r
+               }\r
+               if (quietCount!=0)\r
+               {\r
+                       // Unable to find the necessary number of quiet zone pixels.\r
+                       throw ReaderException.getInstance();\r
+               }\r
+               \r
+               if (i>this.narrowLineWidth*20)\r
+               {\r
+                       // The distance from the image edge to the start of the quiet zone \r
+                       // is twice the size of the quiet zone. \r
+                       // This is unrealistic as the barcode should mostly fill the camera viewfinder.\r
+                       // This implies that this is a false positive.\r
+                       throw ReaderException.getInstance();\r
+               }\r
+       }\r
+\r
        /**\r
         * Skip all whitespace until we get to the first black line.\r
         * \r
@@ -234,10 +276,8 @@ public class ITFReader extends AbstractOneDReader {
                 * \r
                 * ref: http://www.barcode-1.net/i25code.html\r
                 */\r
-               if (this.narrowLineWidth * 10 > endPattern[0]) {\r
-                       // Unable to find the quiet zone preceeding the start sequence.\r
-                       throw ReaderException.getInstance();\r
-               }\r
+               \r
+               validateQuietZone(row, endPattern[0]);\r
 \r
                // Now recalc the indicies of where the 'endblock' starts & stops to\r
                // accomodate\r