mirror of
https://github.com/serratus/quaggaJS.git
synced 2026-08-12 21:21:42 +08:00
#49: configuration of i2of5 reader; still issues with high-density
This commit is contained in:
Vendored
+136
-72
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (tryHarder) {
|
||||||
for (j = 0; j < counter.length - 2; j++) {
|
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
|
||||||
*/
|
*/
|
||||||
|
|||||||
Vendored
+6
-5
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
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ 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(', '));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+22
-7
@@ -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];
|
||||||
|
|||||||
Vendored
BIN
Binary file not shown.
|
After Width: | Height: | Size: 3.3 MiB |
Reference in New Issue
Block a user