UNPKG

fv

Version:

FormVision is a node.js library for extracting data from scanned forms

92 lines (85 loc) 3.29 kB
// Generated by CoffeeScript 2.3.1 var QUIETZONE_WIDTH, boundingBox, cloneWithQuietZone, detectCandidates, dv; dv = require('dv'); ({boundingBox} = require('./math')); // Width of the quiet zone around a barcode. QUIETZONE_WIDTH = 35; // Find potential barcodes in *image*. detectCandidates = function(image) { var blobImage, blobMap, blobMask; blobImage = image.thin('bg', 8, 5).dilate(5, 3); blobMap = blobImage.distanceFunction(8); blobMask = blobMap.threshold(10).invert().dilate(42, 22); return blobMask.connectedComponents(8); }; // Clone image with artificial quiet zone. cloneWithQuietZone = function(image, rect) { var clone, cropped; cropped = image.crop(rect); clone = new dv.Image(cropped.width + QUIETZONE_WIDTH * 2, cropped.height + QUIETZONE_WIDTH * 2, cropped.depth); clone.clearBox(0, 0, clone.width, clone.height); clone.drawImage(cropped, QUIETZONE_WIDTH, QUIETZONE_WIDTH, cropped.width, cropped.height); return clone; }; // Find all barcodes in *image* using the given *zxing* instance. // Always returns an array; see `zxing.findCode()` for format. module.exports.findBarcodes = function(image, zxing) { var candidate, clearedImage, code, codes, couldBeRotated, grayImage, i, len, point, ref; clearedImage = new dv.Image(image); grayImage = image.toGray(); codes = []; ref = detectCandidates(grayImage); for (i = 0, len = ref.length; i < len; i++) { candidate = ref[i]; try { couldBeRotated = candidate.height * 1.75 > candidate.width; zxing.image = cloneWithQuietZone(grayImage, candidate); zxing.tryHarder = couldBeRotated; code = zxing.findCode(); // Test if its worth a retry using some image morphing magic. if ((code == null) && candidate.width < 0.3 * grayImage.width) { // Apply some magic image morphing and retry. zxing.image = zxing.image.scale(2).open(5, 3).scale(0.5).otsuAdaptiveThreshold(400, 400, 0, 0, 0.1).image; code = zxing.findCode(); } if (code != null) { // Test if removal is sane. if (candidate.width < 0.3 * grayImage.width) { clearedImage.clearBox(candidate); } code.box = boundingBox((function() { var j, len1, ref1, results; ref1 = code.points; results = []; for (j = 0, len1 = ref1.length; j < len1; j++) { point = ref1[j]; results.push({ x: point.x, y: point.y, width: 1, height: 1 }); } return results; })()); if (code.box.width < 20) { code.box.y -= QUIETZONE_WIDTH; code.box.x -= Math.round(candidate.width / 2); code.box.width += candidate.width; code.box.height += QUIETZONE_WIDTH * 2; } if (code.box.height < 20) { code.box.x -= QUIETZONE_WIDTH; code.box.y -= Math.round(candidate.height / 2); code.box.height += candidate.height; code.box.width += QUIETZONE_WIDTH * 2; } code.box.x += candidate.x - QUIETZONE_WIDTH; code.box.y += candidate.y - QUIETZONE_WIDTH; delete code.points; codes.push(code); } } catch (error) {} } return [codes, clearedImage]; };