Improving EAN-Reader, Barcode-Line extension, ToBinaryLine

pull/29/head
Christoph Oberhofer 10 years ago
parent f75da96040
commit 566c10b7d2

78
dist/quagga.js vendored

@ -1240,6 +1240,39 @@ define(
throw BarcodeReader.PatternNotFoundException; throw BarcodeReader.PatternNotFoundException;
}; };
EANReader.prototype._findStart = function() {
var self = this,
leadingWhitespaceStart,
offset = self._nextSet(self._row),
startInfo;
while(!startInfo) {
startInfo = self._findPattern(self.START_PATTERN, offset);
leadingWhitespaceStart = startInfo.start - (startInfo.end - startInfo.start);
if (leadingWhitespaceStart >= 0) {
if (self._matchRange(leadingWhitespaceStart, startInfo.start, 0)) {
return startInfo;
}
}
offset = startInfo.end;
startInfo = null;
}
};
EANReader.prototype._findEnd = function(offset) {
var self = this,
trailingWhitespaceEnd,
endInfo = self._findPattern(self.STOP_PATTERN, offset);
trailingWhitespaceEnd = endInfo.end + (endInfo.end - endInfo.start);
if (trailingWhitespaceEnd < self._row.length) {
if (self._matchRange(endInfo.end, trailingWhitespaceEnd, 0)) {
return endInfo;
}
}
return null;
};
EANReader.prototype._decode = function() { EANReader.prototype._decode = function() {
var startInfo, var startInfo,
self = this, self = this,
@ -1250,7 +1283,7 @@ define(
decodedCodes = []; decodedCodes = [];
try { try {
startInfo = self._findPattern(self.START_PATTERN); startInfo = self._findStart();
code = { code = {
code : startInfo.code, code : startInfo.code,
start : startInfo.start, start : startInfo.start,
@ -1288,7 +1321,11 @@ define(
result.push(code.code); result.push(code.code);
} }
code = self._findPattern(self.STOP_PATTERN, code.end); code = self._findEnd(code.end);
if (code === null){
return null;
}
decodedCodes.push(code); decodedCodes.push(code);
// Checksum // Checksum
@ -6384,23 +6421,23 @@ define('bresenham',[],function() {
extrema = [], extrema = [],
currentDir, currentDir,
dir, dir,
threshold = (max - min) / 8, threshold = (max - min) / 12,
rThreshold = -threshold, rThreshold = -threshold,
i, i,
j; j;
// 1. find extrema // 1. find extrema
currentDir = line[0] > center ? Slope.DIR.DOWN : Slope.DIR.UP; currentDir = line[0] > center ? Slope.DIR.UP : Slope.DIR.DOWN;
extrema.push({ extrema.push({
pos : 0, pos : 0,
val : line[0] val : line[0]
}); });
for ( i = 0; i < line.length - 1; i++) { for ( i = 0; i < line.length - 1; i++) {
slope = (line[i + 1] - line[i]); slope = (line[i + 1] - line[i]);
if (slope < rThreshold) { if (slope < rThreshold && line[i + 1] < (center*1.5)) {
dir = Slope.DIR.UP;
} else if (slope > threshold) {
dir = Slope.DIR.DOWN; dir = Slope.DIR.DOWN;
} else if (slope > threshold && line[i + 1] > (center*0.5)) {
dir = Slope.DIR.UP;
} else { } else {
dir = currentDir; dir = currentDir;
} }
@ -7090,18 +7127,25 @@ define('barcode_decoder',["bresenham", "image_debug", 'code_128_reader', 'ean_re
* @param {Number} angle * @param {Number} angle
*/ */
function getExtendedLine(line, angle, ext) { function getExtendedLine(line, angle, ext) {
function extendLine(amount) {
var extension = { var extension = {
y : ext * Math.sin(angle), y : amount * Math.sin(angle),
x : ext * Math.cos(angle) x : amount * Math.cos(angle)
}; };
line[0].y -= extension.y; line[0].y -= extension.y;
line[0].x -= extension.x; line[0].x -= extension.x;
line[1].y += extension.y; line[1].y += extension.y;
line[1].x += extension.x; line[1].x += extension.x;
}
// check if inside image // check if inside image
if (!inputImageWrapper.inImageWithBorder(line[0], 0) || !inputImageWrapper.inImageWithBorder(line[1], 0)) { extendLine(ext);
while (ext > 1 && !inputImageWrapper.inImageWithBorder(line[0], 0) || !inputImageWrapper.inImageWithBorder(line[1], 0)) {
ext -= Math.floor(ext/2);
extendLine(-ext);
}
if (ext <= 1) {
return null; return null;
} }
return line; return line;
@ -7181,6 +7225,12 @@ define('barcode_decoder',["bresenham", "image_debug", 'code_128_reader', 'ean_re
return result; return result;
} }
function getLineLength(line) {
return Math.sqrt(
Math.pow(Math.abs(line[1].y - line[0].y), 2) +
Math.pow(Math.abs(line[1].x - line[0].x), 2));
}
/** /**
* With the help of the configured readers (Code128 or EAN) this function tries to detect a * With the help of the configured readers (Code128 or EAN) this function tries to detect a
* valid barcode pattern within the given area. * valid barcode pattern within the given area.
@ -7191,15 +7241,17 @@ define('barcode_decoder',["bresenham", "image_debug", 'code_128_reader', 'ean_re
var line, var line,
lineAngle, lineAngle,
ctx = _canvas.ctx.overlay, ctx = _canvas.ctx.overlay,
result; result,
lineLength;
if (config.drawBoundingBox && ctx) { if (config.drawBoundingBox && ctx) {
ImageDebug.drawPath(box, {x: 0, y: 1}, ctx, {color: "blue", lineWidth: 2}); ImageDebug.drawPath(box, {x: 0, y: 1}, ctx, {color: "blue", lineWidth: 2});
} }
line = getLine(box); line = getLine(box);
lineLength = getLineLength(line);
lineAngle = Math.atan2(line[1].y - line[0].y, line[1].x - line[0].x); lineAngle = Math.atan2(line[1].y - line[0].y, line[1].x - line[0].x);
line = getExtendedLine(line, lineAngle, 10); line = getExtendedLine(line, lineAngle, Math.floor(lineLength*0.07));
if(line === null){ if(line === null){
return null; return null;
} }
@ -7402,7 +7454,7 @@ define('config',[],function(){
debug: false, debug: false,
controls: false, controls: false,
locate: true, locate: true,
numOfWorkers: 4, numOfWorkers: 0,
visual: { visual: {
show: true show: true
}, },

@ -42,9 +42,9 @@
<label> <label>
<span>Barcode-Type</span> <span>Barcode-Type</span>
<select name="decoder_readers"> <select name="decoder_readers">
<option value="code_128" selected="selected">Code 128</option> <option value="code_128">Code 128</option>
<option value="code_39">Code 39</option> <option value="code_39">Code 39</option>
<option value="ean">EAN</option> <option value="ean" selected="selected">EAN</option>
<option value="codabar">Codabar</option> <option value="codabar">Codabar</option>
</select> </select>
</label> </label>
@ -52,8 +52,8 @@
<span>Resolution (long side)</span> <span>Resolution (long side)</span>
<select name="input-stream_size"> <select name="input-stream_size">
<option value="320">320px</option> <option value="320">320px</option>
<option value="640">640px</option> <option selected="selected" value="640">640px</option>
<option selected="selected" value="800">800px</option> <option value="800">800px</option>
<option value="1280">1280px</option> <option value="1280">1280px</option>
<option value="1600">1600px</option> <option value="1600">1600px</option>
<option value="1920">1920px</option> <option value="1920">1920px</option>
@ -64,8 +64,8 @@
<select name="locator_patch-size"> <select name="locator_patch-size">
<option value="x-small">x-small</option> <option value="x-small">x-small</option>
<option value="small">small</option> <option value="small">small</option>
<option selected="selected" value="medium">medium</option> <option value="medium">medium</option>
<option value="large">large</option> <option selected="selected" value="large">large</option>
<option value="x-large">x-large</option> <option value="x-large">x-large</option>
</select> </select>
</label> </label>
@ -76,8 +76,8 @@
<label> <label>
<span>Workers</span> <span>Workers</span>
<select name="numOfWorkers"> <select name="numOfWorkers">
<option value="0">0</option> <option selected="selected" value="0">0</option>
<option value="1" selected="selected">1</option> <option value="1">1</option>
<option value="2">2</option> <option value="2">2</option>
<option value="4">4</option> <option value="4">4</option>
<option value="8">8</option> <option value="8">8</option>

@ -92,15 +92,17 @@ $(function() {
}, },
state: { state: {
inputStream: { inputStream: {
size: 800 size: 640
}, },
locator: { locator: {
patchSize: "medium", patchSize: "large",
halfSample: false halfSample: false
}, },
numOfWorkers: 1, numOfWorkers: 0,
decoder: { decoder: {
readers: ["code_128_reader"] readers: ["ean_reader"],
showFrequency: true,
showPattern: true
}, },
locate: true, locate: true,
src: null src: null

@ -32,13 +32,13 @@
<button class="next">Next</button> <button class="next">Next</button>
<fieldset class="reader-group"> <fieldset class="reader-group">
<label>Codabar</label> <label>Codabar</label>
<input type="radio" name="reader" value="codabar" checked /> <input type="radio" name="reader" value="codabar" />
<label>Code39</label> <label>Code39</label>
<input type="radio" name="reader" value="code_39" /> <input type="radio" name="reader" value="code_39" />
<label>Code128</label> <label>Code128</label>
<input type="radio" name="reader" value="code_128" /> <input type="radio" name="reader" value="code_128" />
<label>EAN</label> <label>EAN</label>
<input type="radio" name="reader" value="ean" /> <input type="radio" name="reader" value="ean" checked />
</fieldset> </fieldset>
</div> </div>
<div id="result_strip"> <div id="result_strip">

@ -16,7 +16,7 @@ $(function() {
}); });
}, },
config: { config: {
reader: "codabar", reader: "ean",
length: 10 length: 10
}, },
attachListeners: function() { attachListeners: function() {

@ -96,18 +96,25 @@ define(["bresenham", "image_debug", 'code_128_reader', 'ean_reader', 'code_39_re
* @param {Number} angle * @param {Number} angle
*/ */
function getExtendedLine(line, angle, ext) { function getExtendedLine(line, angle, ext) {
function extendLine(amount) {
var extension = { var extension = {
y : ext * Math.sin(angle), y : amount * Math.sin(angle),
x : ext * Math.cos(angle) x : amount * Math.cos(angle)
}; };
line[0].y -= extension.y; line[0].y -= extension.y;
line[0].x -= extension.x; line[0].x -= extension.x;
line[1].y += extension.y; line[1].y += extension.y;
line[1].x += extension.x; line[1].x += extension.x;
}
// check if inside image // check if inside image
if (!inputImageWrapper.inImageWithBorder(line[0], 0) || !inputImageWrapper.inImageWithBorder(line[1], 0)) { extendLine(ext);
while (ext > 1 && !inputImageWrapper.inImageWithBorder(line[0], 0) || !inputImageWrapper.inImageWithBorder(line[1], 0)) {
ext -= Math.floor(ext/2);
extendLine(-ext);
}
if (ext <= 1) {
return null; return null;
} }
return line; return line;
@ -187,6 +194,12 @@ define(["bresenham", "image_debug", 'code_128_reader', 'ean_reader', 'code_39_re
return result; return result;
} }
function getLineLength(line) {
return Math.sqrt(
Math.pow(Math.abs(line[1].y - line[0].y), 2) +
Math.pow(Math.abs(line[1].x - line[0].x), 2));
}
/** /**
* With the help of the configured readers (Code128 or EAN) this function tries to detect a * With the help of the configured readers (Code128 or EAN) this function tries to detect a
* valid barcode pattern within the given area. * valid barcode pattern within the given area.
@ -197,15 +210,17 @@ define(["bresenham", "image_debug", 'code_128_reader', 'ean_reader', 'code_39_re
var line, var line,
lineAngle, lineAngle,
ctx = _canvas.ctx.overlay, ctx = _canvas.ctx.overlay,
result; result,
lineLength;
if (config.drawBoundingBox && ctx) { if (config.drawBoundingBox && ctx) {
ImageDebug.drawPath(box, {x: 0, y: 1}, ctx, {color: "blue", lineWidth: 2}); ImageDebug.drawPath(box, {x: 0, y: 1}, ctx, {color: "blue", lineWidth: 2});
} }
line = getLine(box); line = getLine(box);
lineLength = getLineLength(line);
lineAngle = Math.atan2(line[1].y - line[0].y, line[1].x - line[0].x); lineAngle = Math.atan2(line[1].y - line[0].y, line[1].x - line[0].x);
line = getExtendedLine(line, lineAngle, 10); line = getExtendedLine(line, lineAngle, Math.floor(lineLength*0.07));
if(line === null){ if(line === null){
return null; return null;
} }

@ -107,23 +107,23 @@ define(function() {
extrema = [], extrema = [],
currentDir, currentDir,
dir, dir,
threshold = (max - min) / 8, threshold = (max - min) / 12,
rThreshold = -threshold, rThreshold = -threshold,
i, i,
j; j;
// 1. find extrema // 1. find extrema
currentDir = line[0] > center ? Slope.DIR.DOWN : Slope.DIR.UP; currentDir = line[0] > center ? Slope.DIR.UP : Slope.DIR.DOWN;
extrema.push({ extrema.push({
pos : 0, pos : 0,
val : line[0] val : line[0]
}); });
for ( i = 0; i < line.length - 1; i++) { for ( i = 0; i < line.length - 1; i++) {
slope = (line[i + 1] - line[i]); slope = (line[i + 1] - line[i]);
if (slope < rThreshold) { if (slope < rThreshold && line[i + 1] < (center*1.5)) {
dir = Slope.DIR.UP;
} else if (slope > threshold) {
dir = Slope.DIR.DOWN; dir = Slope.DIR.DOWN;
} else if (slope > threshold && line[i + 1] > (center*0.5)) {
dir = Slope.DIR.UP;
} else { } else {
dir = currentDir; dir = currentDir;
} }

@ -167,6 +167,39 @@ define(
throw BarcodeReader.PatternNotFoundException; throw BarcodeReader.PatternNotFoundException;
}; };
EANReader.prototype._findStart = function() {
var self = this,
leadingWhitespaceStart,
offset = self._nextSet(self._row),
startInfo;
while(!startInfo) {
startInfo = self._findPattern(self.START_PATTERN, offset);
leadingWhitespaceStart = startInfo.start - (startInfo.end - startInfo.start);
if (leadingWhitespaceStart >= 0) {
if (self._matchRange(leadingWhitespaceStart, startInfo.start, 0)) {
return startInfo;
}
}
offset = startInfo.end;
startInfo = null;
}
};
EANReader.prototype._findEnd = function(offset) {
var self = this,
trailingWhitespaceEnd,
endInfo = self._findPattern(self.STOP_PATTERN, offset);
trailingWhitespaceEnd = endInfo.end + (endInfo.end - endInfo.start);
if (trailingWhitespaceEnd < self._row.length) {
if (self._matchRange(endInfo.end, trailingWhitespaceEnd, 0)) {
return endInfo;
}
}
return null;
};
EANReader.prototype._decode = function() { EANReader.prototype._decode = function() {
var startInfo, var startInfo,
self = this, self = this,
@ -177,7 +210,7 @@ define(
decodedCodes = []; decodedCodes = [];
try { try {
startInfo = self._findPattern(self.START_PATTERN); startInfo = self._findStart();
code = { code = {
code : startInfo.code, code : startInfo.code,
start : startInfo.start, start : startInfo.start,
@ -215,7 +248,11 @@ define(
result.push(code.code); result.push(code.code);
} }
code = self._findPattern(self.STOP_PATTERN, code.end); code = self._findEnd(code.end);
if (code === null){
return null;
}
decodedCodes.push(code); decodedCodes.push(code);
// Checksum // Checksum

Binary file not shown.

Before

Width:  |  Height:  |  Size: 570 KiB

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 710 KiB

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 674 KiB

After

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 797 KiB

After

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 736 KiB

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 774 KiB

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 748 KiB

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 741 KiB

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 570 KiB

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 562 KiB

After

Width:  |  Height:  |  Size: 115 KiB

Loading…
Cancel
Save