Making EAN/UPC/Code128 Readers more restrictive; Added alternative Method for binarizing Scanline

pull/40/head
Christoph Oberhofer 10 years ago
parent 0da82b05c8
commit eb9d5ba8dc

198
dist/quagga.js vendored

@ -437,7 +437,7 @@ define("almond", function(){});
define( define(
'barcode_reader',[],function() { 'barcode_reader',[],function() {
"use strict";
function BarcodeReader() { function BarcodeReader() {
this._row = []; this._row = [];
@ -460,12 +460,19 @@ define(
BarcodeReader.prototype._matchPattern = function(counter, code) { BarcodeReader.prototype._matchPattern = function(counter, code) {
var i, var i,
error = 0; error = 0,
singleError = 0,
modulo = this.MODULO,
maxSingleError = 0.9;
for (i = 0; i < counter.length; i++) { for (i = 0; i < counter.length; i++) {
error += Math.abs(code[i] - counter[i]); singleError = Math.abs(code[i] - counter[i]);
if (singleError > maxSingleError) {
return Number.MAX_VALUE;
}
error += singleError;
} }
return error; return error/modulo;
}; };
BarcodeReader.prototype._nextSet = function(line, offset) { BarcodeReader.prototype._nextSet = function(line, offset) {
@ -631,7 +638,7 @@ define(
"./barcode_reader" "./barcode_reader"
], ],
function(BarcodeReader) { function(BarcodeReader) {
"use strict";
function Code128Reader() { function Code128Reader() {
BarcodeReader.call(this); BarcodeReader.call(this);
@ -1079,7 +1086,7 @@ define(
"./barcode_reader" "./barcode_reader"
], ],
function(BarcodeReader) { function(BarcodeReader) {
"use strict";
function EANReader() { function EANReader() {
BarcodeReader.call(this); BarcodeReader.call(this);
@ -1155,6 +1162,9 @@ define(
} }
} }
bestMatch.end = i; bestMatch.end = i;
if (bestMatch.error > 0.5) {
return null;
}
return bestMatch; return bestMatch;
} else { } else {
counterPos++; counterPos++;
@ -1195,7 +1205,7 @@ define(
} }
if ( epsilon === undefined) { if ( epsilon === undefined) {
epsilon = 1.5; epsilon = 0.5;
} }
for ( i = 0; i < pattern.length; i++) { for ( i = 0; i < pattern.length; i++) {
@ -1279,13 +1289,29 @@ define(
return self._verifyTrailingWhitespace(endInfo); return self._verifyTrailingWhitespace(endInfo);
}; };
EANReader.prototype._calculateFirstDigit = function(codeFrequency) {
var i,
self = this;
for ( i = 0; i < self.CODE_FREQUENCY.length; i++) {
if (codeFrequency === self.CODE_FREQUENCY[i]) {
return i;
}
}
return null;
};
EANReader.prototype._decodePayload = function(code, result, decodedCodes) { EANReader.prototype._decodePayload = function(code, result, decodedCodes) {
var i, var i,
self = this, self = this,
codeFrequency = 0x0; codeFrequency = 0x0,
firstDigit;
for ( i = 0; i < 6; i++) { for ( i = 0; i < 6; i++) {
code = self._decodeCode(code.end); code = self._decodeCode(code.end);
if (!code) {
return null;
}
if (code.code >= self.CODE_G_START) { if (code.code >= self.CODE_G_START) {
code.code = code.code - self.CODE_G_START; code.code = code.code - self.CODE_G_START;
codeFrequency |= 1 << (5 - i); codeFrequency |= 1 << (5 - i);
@ -1296,12 +1322,11 @@ define(
decodedCodes.push(code); decodedCodes.push(code);
} }
for ( i = 0; i < self.CODE_FREQUENCY.length; i++) { firstDigit = self._calculateFirstDigit(codeFrequency);
if (codeFrequency === self.CODE_FREQUENCY[i]) { if (firstDigit === null) {
result.unshift(i); return null;
break;
}
} }
result.unshift(firstDigit);
code = self._findPattern(self.MIDDLE_PATTERN, code.end, true, false); code = self._findPattern(self.MIDDLE_PATTERN, code.end, true, false);
if (code === null) { if (code === null) {
@ -1379,7 +1404,7 @@ define(
/* global define */ /* global define */
define('image_loader',[],function() { define('image_loader',[],function() {
"use strict";
var ImageLoader = {}; var ImageLoader = {};
ImageLoader.load = function(directory, callback, offset, size, sequence) { ImageLoader.load = function(directory, callback, offset, size, sequence) {
@ -1443,7 +1468,7 @@ define('image_loader',[],function() {
/* global define */ /* global define */
define('input_stream',["image_loader"], function(ImageLoader) { define('input_stream',["image_loader"], function(ImageLoader) {
"use strict";
var InputStream = {}; var InputStream = {};
InputStream.createVideoStream = function(video) { InputStream.createVideoStream = function(video) {
@ -1732,7 +1757,7 @@ define("typedefs", (function (global) {
/* global define */ /* global define */
define('subImage',["typedefs"], function() { define('subImage',["typedefs"], function() {
"use strict";
/** /**
* Construct representing a part of another {ImageWrapper}. Shares data * Construct representing a part of another {ImageWrapper}. Shares data
@ -1829,7 +1854,7 @@ define('subImage',["typedefs"], function() {
/* global define, vec2 */ /* global define, vec2 */
define('cluster',[],function() { define('cluster',[],function() {
"use strict";
/** /**
* Creates a cluster for grouping similar orientations of datapoints * Creates a cluster for grouping similar orientations of datapoints
@ -4174,7 +4199,7 @@ define("glMatrixAddon", ["glMatrix"], (function (global) {
/* global define */ /* global define */
define('array_helper',[],function() { define('array_helper',[],function() {
"use strict";
return { return {
init : function(arr, val) { init : function(arr, val) {
@ -4261,7 +4286,7 @@ define('array_helper',[],function() {
define('cv_utils',['cluster', 'glMatrixAddon', "array_helper"], function(Cluster2, glMatrixAddon, ArrayHelper) { define('cv_utils',['cluster', 'glMatrixAddon', "array_helper"], function(Cluster2, glMatrixAddon, ArrayHelper) {
"use strict";
/* /*
* cv_utils.js * cv_utils.js
* Collection of CV functions and libraries * Collection of CV functions and libraries
@ -4377,22 +4402,46 @@ define('cv_utils',['cluster', 'glMatrixAddon', "array_helper"], function(Cluster
} }
}; };
CVUtils.computeHistogram = function(imageWrapper) { CVUtils.computeHistogram = function(imageWrapper, bitsPerPixel) {
var imageData = imageWrapper.data, length = imageData.length, i, hist = new Int32Array(256); if (!bitsPerPixel) {
bitsPerPixel = 8;
// init histogram
for ( i = 0; i < 256; i++) {
hist[i] = 0;
} }
var imageData = imageWrapper.data,
length = imageData.length,
bitShift = 8 - bitsPerPixel,
bucketCnt = 1 << bitsPerPixel,
hist = new Int32Array(bucketCnt);
while (length--) { while (length--) {
hist[imageData[length]]++; hist[imageData[length] >> bitShift]++;
} }
return hist; return hist;
}; };
CVUtils.otsuThreshold = function(imageWrapper, targetWrapper) { CVUtils.sharpenLine = function(line) {
var hist, threshold; var i,
length = line.length,
left = line[0],
center = line[1],
right;
for (i = 1; i < length - 1; i++) {
right = line[i + 1];
// -1 4 -1 kernel
line[i-1] = (((center * 2) - left - right)) & 255;
left = center;
center = right;
}
return line;
};
CVUtils.determineOtsuThreshold = function(imageWrapper, bitsPerPixel) {
if (!bitsPerPixel) {
bitsPerPixel = 8;
}
var hist,
threshold,
bitShift = 8 - bitsPerPixel;
function px(init, end) { function px(init, end) {
var sum = 0, i; var sum = 0, i;
@ -4413,18 +4462,19 @@ define('cv_utils',['cluster', 'glMatrixAddon', "array_helper"], function(Cluster
} }
function determineThreshold() { function determineThreshold() {
var vet = [0], p1, p2, p12, k, m1, m2, m12; var vet = [0], p1, p2, p12, k, m1, m2, m12,
max = (1 << bitsPerPixel) - 1;
hist = CVUtils.computeHistogram(imageWrapper); hist = CVUtils.computeHistogram(imageWrapper, bitsPerPixel);
for ( k = 1; k < 255; k++) { for ( k = 1; k < max; k++) {
p1 = px(0, k); p1 = px(0, k);
p2 = px(k + 1, 255); p2 = px(k + 1, max);
p12 = p1 * p2; p12 = p1 * p2;
if (p12 === 0) { if (p12 === 0) {
p12 = 1; p12 = 1;
} }
m1 = mx(0, k) * p2; m1 = mx(0, k) * p2;
m2 = mx(k + 1, 255) * p1; m2 = mx(k + 1, max) * p1;
m12 = m1 - m2; m12 = m1 - m2;
vet[k] = m12 * m12 / p12; vet[k] = m12 * m12 / p12;
} }
@ -4432,6 +4482,12 @@ define('cv_utils',['cluster', 'glMatrixAddon', "array_helper"], function(Cluster
} }
threshold = determineThreshold(); threshold = determineThreshold();
return threshold << bitShift;
};
CVUtils.otsuThreshold = function(imageWrapper, targetWrapper) {
var threshold = CVUtils.determineOtsuThreshold(imageWrapper);
CVUtils.thresholdImage(imageWrapper, threshold, targetWrapper); CVUtils.thresholdImage(imageWrapper, threshold, targetWrapper);
return threshold; return threshold;
}; };
@ -4904,7 +4960,7 @@ define('image_wrapper',[
], ],
function(SubImage, CVUtils, ArrayHelper) { function(SubImage, CVUtils, ArrayHelper) {
'use strict';
/** /**
* Represents a basic image combining the data and size. * Represents a basic image combining the data and size.
@ -5325,7 +5381,7 @@ define('image_wrapper',[
* http://www.codeproject.com/Tips/407172/Connected-Component-Labeling-and-Vectorization * http://www.codeproject.com/Tips/407172/Connected-Component-Labeling-and-Vectorization
*/ */
define('tracer',[],function() { define('tracer',[],function() {
"use strict";
var Tracer = { var Tracer = {
searchDirections : [[0, 1], [1, 1], [1, 0], [1, -1], [0, -1], [-1, -1], [-1, 0], [-1, 1]], searchDirections : [[0, 1], [1, 1], [1, 0], [1, -1], [0, -1], [-1, -1], [-1, 0], [-1, 1]],
@ -5434,7 +5490,7 @@ define('tracer',[],function() {
* http://www.codeproject.com/Tips/407172/Connected-Component-Labeling-and-Vectorization * http://www.codeproject.com/Tips/407172/Connected-Component-Labeling-and-Vectorization
*/ */
define('rasterizer',["tracer"], function(Tracer) { define('rasterizer',["tracer"], function(Tracer) {
"use strict";
var Rasterizer = { var Rasterizer = {
createContour2D : function() { createContour2D : function() {
@ -5630,7 +5686,7 @@ define('rasterizer',["tracer"], function(Tracer) {
/* global define */ /* global define */
define('skeletonizer',[],function() { define('skeletonizer',[],function() {
"use strict";
/* @preserve ASM BEGIN */ /* @preserve ASM BEGIN */
function Skeletonizer(stdlib, foreign, buffer) { function Skeletonizer(stdlib, foreign, buffer) {
@ -5835,7 +5891,7 @@ define('skeletonizer',[],function() {
/* global define */ /* global define */
define('image_debug',[],function() { define('image_debug',[],function() {
"use strict";
return { return {
drawRect: function(pos, size, ctx, style){ drawRect: function(pos, size, ctx, style){
@ -6203,16 +6259,24 @@ function(ImageWrapper, CVUtils, Rasterizer, Tracer, skeletonizer, ArrayHelper, I
* @returns {Array} list of patches * @returns {Array} list of patches
*/ */
function describePatch(moments, patchPos, x, y) { function describePatch(moments, patchPos, x, y) {
var k, avg, sum = 0, eligibleMoments = [], matchingMoments, patch, patchesFound = []; var k,
avg,
sum = 0,
eligibleMoments = [],
matchingMoments,
patch,
patchesFound = [],
minComponentWeight = Math.ceil(_patchSize.x/3);
if (moments.length >= 2) { if (moments.length >= 2) {
// only collect moments which's area covers at least 6 pixels. // only collect moments which's area covers at least minComponentWeight pixels.
for ( k = 0; k < moments.length; k++) { for ( k = 0; k < moments.length; k++) {
if (moments[k].m00 > 6) { if (moments[k].m00 > minComponentWeight) {
eligibleMoments.push(moments[k]); eligibleMoments.push(moments[k]);
} }
} }
// if at least 2 moments are found which have 6pixels covered // if at least 2 moments are found which have at least minComponentWeights covered
if (eligibleMoments.length >= 2) { if (eligibleMoments.length >= 2) {
sum = eligibleMoments.length; sum = eligibleMoments.length;
matchingMoments = similarMoments(eligibleMoments); matchingMoments = similarMoments(eligibleMoments);
@ -6379,8 +6443,8 @@ function(ImageWrapper, CVUtils, Rasterizer, Tracer, skeletonizer, ArrayHelper, I
/* jshint undef: true, unused: true, browser:true, devel: true */ /* jshint undef: true, unused: true, browser:true, devel: true */
/* global define */ /* global define */
define('bresenham',[],function() { define('bresenham',["cv_utils", "image_wrapper"], function(CVUtils, ImageWrapper) {
"use strict";
var Bresenham = {}; var Bresenham = {};
var Slope = { var Slope = {
@ -6470,6 +6534,20 @@ define('bresenham',[],function() {
}; };
}; };
Bresenham.toOtsuBinaryLine = function(result) {
var line = result.line,
image = new ImageWrapper({x: line.length - 1, y: 1}, line),
threshold = CVUtils.determineOtsuThreshold(image, 5);
line = CVUtils.sharpenLine(line);
CVUtils.thresholdImage(image, threshold);
return {
line: line,
threshold: threshold
};
};
/** /**
* Converts the result from getBarcodeLine into a binary representation * Converts the result from getBarcodeLine into a binary representation
* also considering the frequency and slope of the signal for more robust results * also considering the frequency and slope of the signal for more robust results
@ -6586,7 +6664,7 @@ define(
"./array_helper" "./array_helper"
], ],
function(BarcodeReader, ArrayHelper) { function(BarcodeReader, ArrayHelper) {
"use strict";
function Code39Reader() { function Code39Reader() {
BarcodeReader.call(this); BarcodeReader.call(this);
@ -6788,7 +6866,7 @@ define(
"./code_39_reader" "./code_39_reader"
], ],
function(Code39Reader) { function(Code39Reader) {
"use strict";
function Code39VINReader() { function Code39VINReader() {
Code39Reader.call(this); Code39Reader.call(this);
@ -6848,7 +6926,7 @@ define(
"./barcode_reader" "./barcode_reader"
], ],
function(BarcodeReader) { function(BarcodeReader) {
"use strict";
function CodabarReader() { function CodabarReader() {
BarcodeReader.call(this); BarcodeReader.call(this);
@ -7161,7 +7239,7 @@ define(
"./ean_reader" "./ean_reader"
], ],
function(EANReader) { function(EANReader) {
"use strict";
function UPCReader() { function UPCReader() {
EANReader.call(this); EANReader.call(this);
@ -7192,7 +7270,7 @@ define(
"./ean_reader" "./ean_reader"
], ],
function(EANReader) { function(EANReader) {
"use strict";
function EAN8Reader() { function EAN8Reader() {
EANReader.call(this); EANReader.call(this);
@ -7237,7 +7315,7 @@ define(
"./ean_reader" "./ean_reader"
], ],
function(EANReader) { function(EANReader) {
"use strict";
function UPCEReader() { function UPCEReader() {
EANReader.call(this); EANReader.call(this);
@ -7363,7 +7441,7 @@ define('barcode_decoder',[
UPCReader, UPCReader,
EAN8Reader, EAN8Reader,
UPCEReader) { UPCEReader) {
"use strict";
var readers = { var readers = {
code_128_reader: Code128Reader, code_128_reader: Code128Reader,
@ -7642,7 +7720,7 @@ define('barcode_decoder',[
/* global define */ /* global define */
define('frame_grabber',["cv_utils"], function(CVUtils) { define('frame_grabber',["cv_utils"], function(CVUtils) {
"use strict";
var FrameGrabber = {}; var FrameGrabber = {};
@ -7724,7 +7802,7 @@ define('frame_grabber',["cv_utils"], function(CVUtils) {
/* global define */ /* global define */
define('html_utils',[], function() { define('html_utils',[], function() {
"use strict";
function createNode(htmlStr) { function createNode(htmlStr) {
var temp = document.createElement('div'); var temp = document.createElement('div');
@ -7771,8 +7849,8 @@ define('config',[],function(){
constraints: { constraints: {
width: 640, width: 640,
height: 480, height: 480,
minAspectRatio: 1, minAspectRatio: 0,
maxAspectRatio: 1, maxAspectRatio: 100,
facing: "environment" // or user facing: "environment" // or user
} }
}, },
@ -7818,7 +7896,7 @@ define('config',[],function(){
/* global define */ /* global define */
define('events',[],function() { define('events',[],function() {
"use strict";
var _events = function() { var _events = function() {
var events = {}; var events = {};
@ -7909,7 +7987,7 @@ define('events',[],function() {
/* global define, MediaStreamTrack */ /* global define, MediaStreamTrack */
define('camera_access',["html_utils"], function(HtmlUtils) { define('camera_access',["html_utils"], function(HtmlUtils) {
"use strict";
var streamRef, var streamRef,
loadedDataHandler; loadedDataHandler;
@ -7981,8 +8059,8 @@ define('camera_access',["html_utils"], function(HtmlUtils) {
videoConstraints = HtmlUtils.mergeObjects({ videoConstraints = HtmlUtils.mergeObjects({
width: 640, width: 640,
height: 480, height: 480,
minAspectRatio: 1, minAspectRatio: 0,
maxAspectRatio: 1, maxAspectRatio: 100,
facing: "environment" facing: "environment"
}, config); }, config);
@ -8076,7 +8154,7 @@ function(Code128Reader,
CameraAccess, CameraAccess,
ImageDebug, ImageDebug,
CVUtils) { CVUtils) {
"use strict";
var _inputStream, var _inputStream,
_framegrabber, _framegrabber,

@ -44,6 +44,7 @@
<select name="decoder_readers"> <select name="decoder_readers">
<option value="code_128" selected="selected">Code 128</option> <option value="code_128" selected="selected">Code 128</option>
<option value="code_39">Code 39</option> <option value="code_39">Code 39</option>
<option value="code_39_vin">Code 39 VIN</option>
<option value="ean">EAN</option> <option value="ean">EAN</option>
<option value="ean_8">EAN-8</option> <option value="ean_8">EAN-8</option>
<option value="upc">UPC</option> <option value="upc">UPC</option>

@ -340,16 +340,24 @@ function(ImageWrapper, CVUtils, Rasterizer, Tracer, skeletonizer, ArrayHelper, I
* @returns {Array} list of patches * @returns {Array} list of patches
*/ */
function describePatch(moments, patchPos, x, y) { function describePatch(moments, patchPos, x, y) {
var k, avg, sum = 0, eligibleMoments = [], matchingMoments, patch, patchesFound = []; var k,
avg,
sum = 0,
eligibleMoments = [],
matchingMoments,
patch,
patchesFound = [],
minComponentWeight = Math.ceil(_patchSize.x/3);
if (moments.length >= 2) { if (moments.length >= 2) {
// only collect moments which's area covers at least 6 pixels. // only collect moments which's area covers at least minComponentWeight pixels.
for ( k = 0; k < moments.length; k++) { for ( k = 0; k < moments.length; k++) {
if (moments[k].m00 > 6) { if (moments[k].m00 > minComponentWeight) {
eligibleMoments.push(moments[k]); eligibleMoments.push(moments[k]);
} }
} }
// if at least 2 moments are found which have 6pixels covered // if at least 2 moments are found which have at least minComponentWeights covered
if (eligibleMoments.length >= 2) { if (eligibleMoments.length >= 2) {
sum = eligibleMoments.length; sum = eligibleMoments.length;
matchingMoments = similarMoments(eligibleMoments); matchingMoments = similarMoments(eligibleMoments);

@ -26,12 +26,19 @@ define(
BarcodeReader.prototype._matchPattern = function(counter, code) { BarcodeReader.prototype._matchPattern = function(counter, code) {
var i, var i,
error = 0; error = 0,
singleError = 0,
modulo = this.MODULO,
maxSingleError = 0.9;
for (i = 0; i < counter.length; i++) { for (i = 0; i < counter.length; i++) {
error += Math.abs(code[i] - counter[i]); singleError = Math.abs(code[i] - counter[i]);
if (singleError > maxSingleError) {
return Number.MAX_VALUE;
}
error += singleError;
} }
return error; return error/modulo;
}; };
BarcodeReader.prototype._nextSet = function(line, offset) { BarcodeReader.prototype._nextSet = function(line, offset) {

@ -1,7 +1,7 @@
/* jshint undef: true, unused: true, browser:true, devel: true */ /* jshint undef: true, unused: true, browser:true, devel: true */
/* global define */ /* global define */
define(function() { define(["cv_utils", "image_wrapper"], function(CVUtils, ImageWrapper) {
"use strict"; "use strict";
var Bresenham = {}; var Bresenham = {};
@ -92,6 +92,20 @@ define(function() {
}; };
}; };
Bresenham.toOtsuBinaryLine = function(result) {
var line = result.line,
image = new ImageWrapper({x: line.length - 1, y: 1}, line),
threshold = CVUtils.determineOtsuThreshold(image, 5);
line = CVUtils.sharpenLine(line);
CVUtils.thresholdImage(image, threshold);
return {
line: line,
threshold: threshold
};
};
/** /**
* Converts the result from getBarcodeLine into a binary representation * Converts the result from getBarcodeLine into a binary representation
* also considering the frequency and slope of the signal for more robust results * also considering the frequency and slope of the signal for more robust results

@ -119,22 +119,46 @@ define(['cluster', 'glMatrixAddon', "array_helper"], function(Cluster2, glMatrix
} }
}; };
CVUtils.computeHistogram = function(imageWrapper) { CVUtils.computeHistogram = function(imageWrapper, bitsPerPixel) {
var imageData = imageWrapper.data, length = imageData.length, i, hist = new Int32Array(256); if (!bitsPerPixel) {
bitsPerPixel = 8;
// init histogram
for ( i = 0; i < 256; i++) {
hist[i] = 0;
} }
var imageData = imageWrapper.data,
length = imageData.length,
bitShift = 8 - bitsPerPixel,
bucketCnt = 1 << bitsPerPixel,
hist = new Int32Array(bucketCnt);
while (length--) { while (length--) {
hist[imageData[length]]++; hist[imageData[length] >> bitShift]++;
} }
return hist; return hist;
}; };
CVUtils.otsuThreshold = function(imageWrapper, targetWrapper) { CVUtils.sharpenLine = function(line) {
var hist, threshold; var i,
length = line.length,
left = line[0],
center = line[1],
right;
for (i = 1; i < length - 1; i++) {
right = line[i + 1];
// -1 4 -1 kernel
line[i-1] = (((center * 2) - left - right)) & 255;
left = center;
center = right;
}
return line;
};
CVUtils.determineOtsuThreshold = function(imageWrapper, bitsPerPixel) {
if (!bitsPerPixel) {
bitsPerPixel = 8;
}
var hist,
threshold,
bitShift = 8 - bitsPerPixel;
function px(init, end) { function px(init, end) {
var sum = 0, i; var sum = 0, i;
@ -155,18 +179,19 @@ define(['cluster', 'glMatrixAddon', "array_helper"], function(Cluster2, glMatrix
} }
function determineThreshold() { function determineThreshold() {
var vet = [0], p1, p2, p12, k, m1, m2, m12; var vet = [0], p1, p2, p12, k, m1, m2, m12,
max = (1 << bitsPerPixel) - 1;
hist = CVUtils.computeHistogram(imageWrapper); hist = CVUtils.computeHistogram(imageWrapper, bitsPerPixel);
for ( k = 1; k < 255; k++) { for ( k = 1; k < max; k++) {
p1 = px(0, k); p1 = px(0, k);
p2 = px(k + 1, 255); p2 = px(k + 1, max);
p12 = p1 * p2; p12 = p1 * p2;
if (p12 === 0) { if (p12 === 0) {
p12 = 1; p12 = 1;
} }
m1 = mx(0, k) * p2; m1 = mx(0, k) * p2;
m2 = mx(k + 1, 255) * p1; m2 = mx(k + 1, max) * p1;
m12 = m1 - m2; m12 = m1 - m2;
vet[k] = m12 * m12 / p12; vet[k] = m12 * m12 / p12;
} }
@ -174,6 +199,12 @@ define(['cluster', 'glMatrixAddon', "array_helper"], function(Cluster2, glMatrix
} }
threshold = determineThreshold(); threshold = determineThreshold();
return threshold << bitShift;
};
CVUtils.otsuThreshold = function(imageWrapper, targetWrapper) {
var threshold = CVUtils.determineOtsuThreshold(imageWrapper);
CVUtils.thresholdImage(imageWrapper, threshold, targetWrapper); CVUtils.thresholdImage(imageWrapper, threshold, targetWrapper);
return threshold; return threshold;
}; };

@ -82,6 +82,9 @@ define(
} }
} }
bestMatch.end = i; bestMatch.end = i;
if (bestMatch.error > 0.5) {
return null;
}
return bestMatch; return bestMatch;
} else { } else {
counterPos++; counterPos++;
@ -122,7 +125,7 @@ define(
} }
if ( epsilon === undefined) { if ( epsilon === undefined) {
epsilon = 1.5; epsilon = 0.5;
} }
for ( i = 0; i < pattern.length; i++) { for ( i = 0; i < pattern.length; i++) {
@ -206,13 +209,29 @@ define(
return self._verifyTrailingWhitespace(endInfo); return self._verifyTrailingWhitespace(endInfo);
}; };
EANReader.prototype._calculateFirstDigit = function(codeFrequency) {
var i,
self = this;
for ( i = 0; i < self.CODE_FREQUENCY.length; i++) {
if (codeFrequency === self.CODE_FREQUENCY[i]) {
return i;
}
}
return null;
};
EANReader.prototype._decodePayload = function(code, result, decodedCodes) { EANReader.prototype._decodePayload = function(code, result, decodedCodes) {
var i, var i,
self = this, self = this,
codeFrequency = 0x0; codeFrequency = 0x0,
firstDigit;
for ( i = 0; i < 6; i++) { for ( i = 0; i < 6; i++) {
code = self._decodeCode(code.end); code = self._decodeCode(code.end);
if (!code) {
return null;
}
if (code.code >= self.CODE_G_START) { if (code.code >= self.CODE_G_START) {
code.code = code.code - self.CODE_G_START; code.code = code.code - self.CODE_G_START;
codeFrequency |= 1 << (5 - i); codeFrequency |= 1 << (5 - i);
@ -223,12 +242,11 @@ define(
decodedCodes.push(code); decodedCodes.push(code);
} }
for ( i = 0; i < self.CODE_FREQUENCY.length; i++) { firstDigit = self._calculateFirstDigit(codeFrequency);
if (codeFrequency === self.CODE_FREQUENCY[i]) { if (firstDigit === null) {
result.unshift(i); return null;
break;
}
} }
result.unshift(firstDigit);
code = self._findPattern(self.MIDDLE_PATTERN, code.end, true, false); code = self._findPattern(self.MIDDLE_PATTERN, code.end, true, false);
if (code === null) { if (code === null) {

Loading…
Cancel
Save