#49: configuration of i2of5 reader; still issues with high-density

pull/55/head
Christoph Oberhofer 10 years ago
parent f99b4a3e64
commit 86f085039e

210
dist/quagga.js vendored

@ -5861,8 +5861,9 @@ define(
'barcode_reader',[],function() { 'barcode_reader',[],function() {
"use strict"; "use strict";
function BarcodeReader() { function BarcodeReader(config) {
this._row = []; this._row = [];
this.config = config || {};
return this; return this;
} }
@ -6079,6 +6080,8 @@ define(
PatternNotFoundException : "Pattern could not be found!" PatternNotFoundException : "Pattern could not be found!"
}; };
BarcodeReader.CONFIG_KEYS = {};
return (BarcodeReader); return (BarcodeReader);
} }
); );
@ -7625,15 +7628,71 @@ define(
/* jshint undef: true, unused: true, browser:true, devel: true */ /* jshint undef: true, unused: true, browser:true, devel: true */
/* global define */ /* global define */
define('html_utils',[], function() {
"use strict";
function createNode(htmlStr) {
var temp = document.createElement('div');
temp.innerHTML = htmlStr;
while (temp.firstChild) {
return temp.firstChild;
}
}
function mergeObjects(obj1, obj2) {
for (var p in obj2) {
try {
if (obj2[p].constructor == Object) {
obj1[p] = mergeObjects(obj1[p], obj2[p]);
} else {
obj1[p] = obj2[p];
}
} catch(e) {
obj1[p] = obj2[p];
}
}
return obj1;
}
return {
createNode : function(htmlStr) {
return createNode(htmlStr);
},
mergeObjects : function(obj1, obj2) {
return mergeObjects(obj1, obj2);
}
};
});
/* jshint undef: true, unused: true, browser:true, devel: true */
/* global define */
define( define(
'i2of5_reader',[ 'i2of5_reader',[
"./barcode_reader" "./barcode_reader",
"./html_utils"
], ],
function(BarcodeReader) { function(BarcodeReader, HTMLUtils) {
"use strict"; "use strict";
function I2of5Reader(opts) { function I2of5Reader(opts) {
opts = HTMLUtils.mergeObjects(getDefaulConfig(), opts);
BarcodeReader.call(this, opts); BarcodeReader.call(this, opts);
this.barSpaceRatio = [1, 1];
if (opts.normalizeBarSpaceWidth) {
this.SINGLE_CODE_ERROR = 0.38;
this.AVG_CODE_ERROR = 0.09;
}
}
function getDefaulConfig() {
var config = {};
Object.keys(I2of5Reader.CONFIG_KEYS).forEach(function(key) {
config[key] = I2of5Reader.CONFIG_KEYS[key]['default'];
});
return config;
} }
var N = 1, var N = 1,
@ -7654,15 +7713,42 @@ define(
[W, N, N, W, N], [W, N, N, W, N],
[N, W, N, W, N] [N, W, N, W, N]
]}, ]},
SINGLE_CODE_ERROR: {value: 1}, SINGLE_CODE_ERROR: {value: 0.78, writable: true},
AVG_CODE_ERROR: {value: 0.38}, AVG_CODE_ERROR: {value: 0.38, writable: true},
FORMAT: {value: "i2of5", writeable: false} MAX_CORRECTION_FACTOR: {value: 5},
FORMAT: {value: "i2of5"}
}; };
I2of5Reader.prototype = Object.create(BarcodeReader.prototype, properties); I2of5Reader.prototype = Object.create(BarcodeReader.prototype, properties);
I2of5Reader.prototype.constructor = I2of5Reader; I2of5Reader.prototype.constructor = I2of5Reader;
I2of5Reader.prototype._findPattern = function(pattern, offset) { I2of5Reader.prototype._matchPattern = function(counter, code) {
if (this.config.normalizeBarSpaceWidth) {
var i,
counterSum = [0, 0],
codeSum = [0, 0],
correction = [0, 0],
correctionRatio = this.MAX_CORRECTION_FACTOR,
correctionRatioInverse = 1 / correctionRatio;
for (i = 0; i < counter.length; i++) {
counterSum[i % 2] += counter[i];
codeSum[i % 2] += code[i];
}
correction[0] = codeSum[0] / counterSum[0];
correction[1] = codeSum[1] / counterSum[1];
correction[0] = Math.max(Math.min(correction[0], correctionRatio), correctionRatioInverse);
correction[1] = Math.max(Math.min(correction[1], correctionRatio), correctionRatioInverse);
this.barSpaceRatio = correction;
for (i = 0; i < counter.length; i++) {
counter[i] *= this.barSpaceRatio[i % 2];
}
}
return BarcodeReader.prototype._matchPattern.call(this, counter, code);
};
I2of5Reader.prototype._findPattern = function(pattern, offset, isWhite, tryHarder) {
var counter = [], var counter = [],
self = this, self = this,
i, i,
@ -7677,9 +7763,11 @@ define(
j, j,
sum, sum,
normalized, normalized,
isWhite = false,
epsilon = self.AVG_CODE_ERROR; epsilon = self.AVG_CODE_ERROR;
isWhite = isWhite || false;
tryHarder = tryHarder || false;
if (!offset) { if (!offset) {
offset = self._nextSet(self._row); offset = self._nextSet(self._row);
} }
@ -7708,12 +7796,16 @@ define(
return bestMatch; return bestMatch;
} }
} }
for ( j = 0; j < counter.length - 2; j++) { if (tryHarder) {
for (j = 0; j < counter.length - 2; j++) {
counter[j] = counter[j + 2]; counter[j] = counter[j + 2];
} }
counter[counter.length - 2] = 0; counter[counter.length - 2] = 0;
counter[counter.length - 1] = 0; counter[counter.length - 1] = 0;
counterPos--; counterPos--;
} else {
return null;
}
} else { } else {
counterPos++; counterPos++;
} }
@ -7728,17 +7820,18 @@ define(
var self = this, var self = this,
leadingWhitespaceStart, leadingWhitespaceStart,
offset = self._nextSet(self._row), offset = self._nextSet(self._row),
startInfo; startInfo,
narrowBarWidth = 1;
while(!startInfo) { while(!startInfo) {
startInfo = self._findPattern(self.START_PATTERN, offset); startInfo = self._findPattern(self.START_PATTERN, offset, false, true);
if (!startInfo) { if (!startInfo) {
return null; return null;
} }
leadingWhitespaceStart = startInfo.start - (startInfo.end - startInfo.start); narrowBarWidth = Math.floor((startInfo.end - startInfo.start) / 4);
leadingWhitespaceStart = startInfo.start - narrowBarWidth*10;
if (leadingWhitespaceStart >= 0) { if (leadingWhitespaceStart >= 0) {
if (self._matchRange(leadingWhitespaceStart, startInfo.start, 0)) { if (self._matchRange(leadingWhitespaceStart, startInfo.start, 0)) {
startInfo.narrowBarWidth = Math.floor((startInfo.end - startInfo.start) / 4);
return startInfo; return startInfo;
} }
} }
@ -7751,7 +7844,7 @@ define(
var self = this, var self = this,
trailingWhitespaceEnd; trailingWhitespaceEnd;
trailingWhitespaceEnd = endInfo.end + (endInfo.end - endInfo.start); trailingWhitespaceEnd = endInfo.end + ((endInfo.end - endInfo.start) / 2);
if (trailingWhitespaceEnd < self._row.length) { if (trailingWhitespaceEnd < self._row.length) {
if (self._matchRange(endInfo.end, trailingWhitespaceEnd, 0)) { if (self._matchRange(endInfo.end, trailingWhitespaceEnd, 0)) {
return endInfo; return endInfo;
@ -7841,8 +7934,8 @@ define(
while (pos < counterLength) { while (pos < counterLength) {
for (i = 0; i < 5; i++) { for (i = 0; i < 5; i++) {
counterPair[0][i] = counters[pos]; counterPair[0][i] = counters[pos]*this.barSpaceRatio[0];
counterPair[1][i] = counters[pos + 1]; counterPair[1][i] = counters[pos + 1]*this.barSpaceRatio[1];
pos += 2; pos += 2;
} }
codes = self._decodePair(counterPair); codes = self._decodePair(counterPair);
@ -7874,20 +7967,12 @@ define(
if (!startInfo) { if (!startInfo) {
return null; return null;
} }
decodedCodes.push(startInfo);
endInfo = self._findEnd(); endInfo = self._findEnd();
if (!endInfo) { if (!endInfo) {
return null; return null;
} }
console.log(startInfo);
console.log(endInfo);
code = {
code : startInfo.code,
start : startInfo.start,
end : startInfo.end
};
decodedCodes.push(code);
counters = self._fillCounters(startInfo.end, endInfo.start, false); counters = self._fillCounters(startInfo.end, endInfo.start, false);
if (!self._verifyCounterLength(counters)) { if (!self._verifyCounterLength(counters)) {
@ -7897,21 +7982,30 @@ define(
if (!code) { if (!code) {
return null; return null;
} }
if (result.length % 2 !== 0 ||
// Checksum result.length < 6) {
if (!self._checksum(result)) {
return null; return null;
} }
decodedCodes.push(endInfo);
return { return {
code : result.join(""), code : result.join(""),
start : startInfo.start, start : startInfo.start,
end : code.end, end : endInfo.end,
startInfo : startInfo, startInfo : startInfo,
decodedCodes : decodedCodes decodedCodes : decodedCodes
}; };
}; };
I2of5Reader.CONFIG_KEYS = {
normalizeBarSpaceWidth: {
'type': 'boolean',
'default': false,
'description': 'If true, the reader tries to normalize the' +
'width-difference between bars and spaces'
}
};
return (I2of5Reader); return (I2of5Reader);
} }
); );
@ -8006,11 +8100,21 @@ define('barcode_decoder',[
} }
function initReaders() { function initReaders() {
var i; config.readers.forEach(function(readerConfig) {
for ( i = 0; i < config.readers.length; i++) { var reader,
console.log(config.readers[i]); config = {};
_barcodeReaders.push(new readers[config.readers[i]]());
if (typeof readerConfig === 'object') {
reader = readerConfig.format;
config = readerConfig.config;
} else if (typeof readerConfig === 'string') {
reader = readerConfig;
} }
_barcodeReaders.push(new readers[reader](config));
});
console.log("Registered Readers: " + _barcodeReaders
.map(function(reader) {return JSON.stringify({format: reader.FORMAT, config: reader.config});})
.join(', '));
} }
function initConfig() { function initConfig() {
@ -8290,46 +8394,6 @@ define('frame_grabber',["cv_utils"], function(CVUtils) {
return (FrameGrabber); return (FrameGrabber);
}); });
/* jshint undef: true, unused: true, browser:true, devel: true */
/* global define */
define('html_utils',[], function() {
"use strict";
function createNode(htmlStr) {
var temp = document.createElement('div');
temp.innerHTML = htmlStr;
while (temp.firstChild) {
return temp.firstChild;
}
}
function mergeObjects(obj1, obj2) {
for (var p in obj2) {
try {
if (obj2[p].constructor == Object) {
obj1[p] = mergeObjects(obj1[p], obj2[p]);
} else {
obj1[p] = obj2[p];
}
} catch(e) {
obj1[p] = obj2[p];
}
}
return obj1;
}
return {
createNode : function(htmlStr) {
return createNode(htmlStr);
},
mergeObjects : function(obj1, obj2) {
return mergeObjects(obj1, obj2);
}
};
});
/** /**
* The basic configuration * The basic configuration
*/ */

11
dist/quagga.min.js vendored

File diff suppressed because one or more lines are too long

@ -41,6 +41,7 @@
<option value="upc">UPC</option> <option value="upc">UPC</option>
<option value="upc_e">UPC-E</option> <option value="upc_e">UPC-E</option>
<option value="codabar">Codabar</option> <option value="codabar">Codabar</option>
<option value="i2of5">I2of5</option>
</select> </select>
</label> </label>
<label> <label>

@ -2,7 +2,7 @@ $(function() {
var resultCollector = Quagga.ResultCollector.create({ var resultCollector = Quagga.ResultCollector.create({
capture: true, capture: true,
capacity: 20, capacity: 20,
blacklist: [{code: "3574660239843", format: "ean_13"}], blacklist: [{code: "2167361334", format: "i2of5"}],
filter: function(codeResult) { filter: function(codeResult) {
// only store results which match this constraint // only store results which match this constraint
// e.g.: codeResult // e.g.: codeResult
@ -127,7 +127,7 @@ $(function() {
}, },
numOfWorkers: 4, numOfWorkers: 4,
decoder: { decoder: {
readers : ["code_128_reader"] readers : [ "code_128_reader"]
}, },
locate: true locate: true
}, },

@ -225,12 +225,7 @@ define(['quagga', 'async'], function(Quagga, async) {
}, },
numOfWorkers: 0, numOfWorkers: 0,
decoder: { decoder: {
readers: [{ readers: ["i2of5_reader"],
format: "i2of5_reader",
config: {
normalizeBarSpaceWidth: true
}
}],
}, },
locate: true, locate: true,
src: null src: null
@ -239,7 +234,8 @@ define(['quagga', 'async'], function(Quagga, async) {
{"name": "image-002.jpg", "result": "2167361334"}, {"name": "image-002.jpg", "result": "2167361334"},
{"name": "image-003.jpg", "result": "2167361334"}, {"name": "image-003.jpg", "result": "2167361334"},
{"name": "image-004.jpg", "result": "2167361334"}, {"name": "image-004.jpg", "result": "2167361334"},
{"name": "image-005.jpg", "result": "2167361334"} {"name": "image-005.jpg", "result": "2167361334"},
{"name": "image-006.jpg", "result": "2167361334"}
]; ];
testSet.forEach(function(sample) { testSet.forEach(function(sample) {

@ -101,8 +101,8 @@ define([
} }
_barcodeReaders.push(new readers[reader](config)); _barcodeReaders.push(new readers[reader](config));
}); });
console.log("Registered Readers:" + _barcodeReaders console.log("Registered Readers: " + _barcodeReaders
.map(function(reader) {return reader.FORMAT;}) .map(function(reader) {return JSON.stringify({format: reader.FORMAT, config: reader.config});})
.join(', ')); .join(', '));
} }

@ -3,14 +3,29 @@
define( define(
[ [
"./barcode_reader" "./barcode_reader",
"./html_utils"
], ],
function(BarcodeReader) { function(BarcodeReader, HTMLUtils) {
"use strict"; "use strict";
function I2of5Reader(opts) { function I2of5Reader(opts) {
opts = HTMLUtils.mergeObjects(getDefaulConfig(), opts);
BarcodeReader.call(this, opts); BarcodeReader.call(this, opts);
this.barSpaceRatio = [1, 1]; this.barSpaceRatio = [1, 1];
if (opts.normalizeBarSpaceWidth) {
this.SINGLE_CODE_ERROR = 0.38;
this.AVG_CODE_ERROR = 0.09;
}
}
function getDefaulConfig() {
var config = {};
Object.keys(I2of5Reader.CONFIG_KEYS).forEach(function(key) {
config[key] = I2of5Reader.CONFIG_KEYS[key]['default'];
});
return config;
} }
var N = 1, var N = 1,
@ -31,10 +46,10 @@ define(
[W, N, N, W, N], [W, N, N, W, N],
[N, W, N, W, N] [N, W, N, W, N]
]}, ]},
SINGLE_CODE_ERROR: {value: 0.50}, SINGLE_CODE_ERROR: {value: 0.78, writable: true},
AVG_CODE_ERROR: {value: 0.14}, AVG_CODE_ERROR: {value: 0.38, writable: true},
MAX_CORRECTION_FACTOR: {value: 1.9}, MAX_CORRECTION_FACTOR: {value: 5},
FORMAT: {value: "i2of5", writeable: false} FORMAT: {value: "i2of5"}
}; };
I2of5Reader.prototype = Object.create(BarcodeReader.prototype, properties); I2of5Reader.prototype = Object.create(BarcodeReader.prototype, properties);
@ -51,7 +66,7 @@ define(
for (i = 0; i < counter.length; i++) { for (i = 0; i < counter.length; i++) {
counterSum[i % 2] += counter[i]; counterSum[i % 2] += counter[i];
codeSum[i % 2] += code[i] codeSum[i % 2] += code[i];
} }
correction[0] = codeSum[0] / counterSum[0]; correction[0] = codeSum[0] / counterSum[0];
correction[1] = codeSum[1] / counterSum[1]; correction[1] = codeSum[1] / counterSum[1];

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 MiB

Loading…
Cancel
Save