Fix WhiteRectangleDetector assumptions?

87 views
Skip to first unread message

Christoph Schulz

unread,
Mar 12, 2013, 3:02:02 PM3/12/13
to zx...@googlegroups.com
Hi,

I'm currently fiddling with DataMatrix codes and the assumption (centered bar code) made inside WhiteRectangleDetector is simply invalid for my use case: the bar code isn't near the center of my LuminanceSource at all (see datamatrix-3/scan1).

WhiteRectangleDetector searches for "one white line" from the center in all directions (center to right, center to left, ...). After it has located a "white working area" it scans diagonally for black pixels, extracting a "bar code area". The algorithm can be tricked very easily: put the bar code in a corner of a large white image and/or draw an intersecting ellipse around the barcode - voila nothing is detected. The Aztec detector suffers from the same problem. I've got several ideas how to fix this:
  1. Replace WhiteRectangleDetector with something more sophisticated as in Data Matrix Code Location Based on Finder Pattern Detection and Bar Code Border Fitting. Basically they locate all lines using region growing along with some tricky validation/matching. This obviously eliminates the "someone aiming with a camera" assumption, but its tricky to implement, slower and sort of expands the scope of ZXing.
  2. Close() = Erode(Dilate()) the hole image, find connected components and search the resulting rectangles for bar codes. This would be sort of a new MultipleBarcodeReader, that searches every plausible rectangle, that still could miss DataMatrix bar codes due to page layout/text/people connecting page layout to barcodes with pens (yep...!).

Any thoughts on this? Feedback is always welcome :)

Regards,
Christoph

Sean Owen

unread,
Mar 12, 2013, 3:27:00 PM3/12/13
to zx...@googlegroups.com
The assumption about the barcode being in the middle is pretty valid; the rest is not. A change that addresses at least the second point, and ideally both, would be great. The limiting factor is CPU to some extent, but these days a lot more is possible. Exhaustive search may still be too much. You can validate the effectiveness on the unit tests, and you can roughly judge the effect on CPU by watching the time taken. If you come up with a change that's great. Even a small simple improvement is worthwhile and maybe easier to identify.

Christoph Schulz

unread,
Mar 13, 2013, 10:29:24 AM3/13/13
to zx...@googlegroups.com
Sounds good. Solution to the first problem for scanned documents is below. Not sure if we need to deal with the second one at all, since pencil strokes can be effectively removed using Distance Transform + Thresholding.

Solution (using node-dv / JavaScript - see attached image):
var barcodes = new dv.Image('png', fs.readFileSync(__dirname + '/fixtures/barcodes.png'));
var open = barcodes.thin('bg', 8, 5).dilate(3, 3);
var openMap = open.distanceFunction(8);
var openMask = openMap.threshold(10).erode(11*2, 11*2);
writeImage('barcodes-open.png', open);
writeImage('barcodes-openMap.png', openMap.maxDynamicRange('log'));
writeImage('barcodes-openMask.png', openMask);
var boxes = openMask.invert().connectedComponents(8);
for (var i in boxes) {
    barcodes.drawBox(boxes[i].x, boxes[i].y,
                     boxes[i].width, boxes[i].height,
                     2, 'flip');
}
writeImage('barcodes-isolated.png', barcodes);


Regards,
Christoph
barcodes.png
Reply all
Reply to author
Forward
0 new messages