Skip to content

Commit

Permalink
Initial version for node.js
Browse files Browse the repository at this point in the history
  • Loading branch information
serratus committed Jun 2, 2015
1 parent 89da5cc commit a042422
Show file tree
Hide file tree
Showing 12 changed files with 350 additions and 81 deletions.
15 changes: 15 additions & 0 deletions example/node-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
var Quagga = require('../lib/quagga');

Quagga.decodeSingle({
src: "../test/fixtures/code_128/image-001.jpg",
numOfWorkers: 0,
inputStream: {
size: 640
}
}, function(result) {
if(result.codeResult) {
console.log("result", result.codeResult.code);
} else {
console.log("not detected");
}
});
75 changes: 75 additions & 0 deletions lib/frame_grabber.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/* jshint undef: true, unused: true, browser:true, devel: true */
/* global define */

define(["cv_utils"], function(CVUtils) {
"use strict";

var FrameGrabber = {};

FrameGrabber.create = function(inputStream) {
var _that = {},
_streamConfig = inputStream.getConfig(),
_video_size = CVUtils.imageRef(inputStream.getRealWidth(), inputStream.getRealHeight()),
_size =_streamConfig.size ? CVUtils.imageRef(inputStream.getWidth(), inputStream.getHeight()) : _video_size,
_sx = 0,
_sy = 0,
_dx = 0,
_dy = 0,
_sWidth,
_dWidth,
_sHeight,
_dHeight,
_canvas = null,
_ctx = null,
_data = null;

_sWidth = _video_size.x;
_dWidth = _size.x;
_sHeight = _video_size.y;
_dHeight = _size.y;

_data = new Uint8Array(_size.x * _size.y);

/**
* Uses the given array as frame-buffer
*/
_that.attachData = function(data) {
_data = data;
};

/**
* Returns the used frame-buffer
*/
_that.getData = function() {
return _data;
};

/**
* Fetches a frame from the input-stream and puts into the frame-buffer.
* The image-data is converted to gray-scale and then half-sampled if configured.
*/
_that.grab = function() {
var doHalfSample = _streamConfig.halfSample,
frame = inputStream.getFrame();

if (frame) {
if(doHalfSample){
CVUtils.grayAndHalfSampleFromCanvasData(frame.data, _size, _data);
} else {
CVUtils.computeGray(frame.data, _data);
}
return true;
} else {
return false;
}
};

_that.getSize = function() {
return _size;
};

return _that;
};

return (FrameGrabber);
});
138 changes: 138 additions & 0 deletions lib/input_stream.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
/* jshint undef: true, unused: true, browser:true, devel: true */
/* global define */

define(function() {
"use strict";

var GetPixels = require("get-pixels");

var InputStream = {};

InputStream.createImageStream = function() {
var that = {};
var _config = null;

var width = 0,
height = 0,
frameIdx = 0,
paused = true,
loaded = false,
frame = null,
baseUrl,
ended = false,
size,
calculatedWidth,
calculatedHeight,
_eventNames = ['canrecord', 'ended'],
_eventHandlers = {};

function loadImages() {
loaded = false;
GetPixels(baseUrl, function(err, pixels) {
if (err) {
console.log(err);
exit(1);
}
loaded = true;
console.log(pixels.shape);
frame = pixels;
width = pixels.shape[0];
height = pixels.shape[1];
calculatedWidth = _config.size ? width/height > 1 ? _config.size : Math.floor((width/height) * _config.size) : width;
calculatedHeight = _config.size ? width/height > 1 ? Math.floor((height/width) * _config.size) : _config.size : height;


setTimeout(function() {
publishEvent("canrecord", []);
}, 0);
});
}

function publishEvent(eventName, args) {
var j,
handlers = _eventHandlers[eventName];

if (handlers && handlers.length > 0) {
for ( j = 0; j < handlers.length; j++) {
handlers[j].apply(that, args);
}
}
}


that.trigger = publishEvent;

that.getWidth = function() {
return calculatedWidth;
};

that.getHeight = function() {
return calculatedHeight;
};

that.setWidth = function(width) {
calculatedWidth = width;
};

that.setHeight = function(height) {
calculatedHeight = height;
};

that.getRealWidth = function() {
return width;
};

that.getRealHeight = function() {
return height;
};

that.setInputStream = function(stream) {
_config = stream;
baseUrl = _config.src;
size = 1;
loadImages();
};

that.ended = function() {
return ended;
};

that.setAttribute = function() {};

that.getConfig = function() {
return _config;
};

that.pause = function() {
paused = true;
};

that.play = function() {
paused = false;
};

that.setCurrentTime = function(time) {
frameIdx = time;
};

that.addEventListener = function(event, f) {
if (_eventNames.indexOf(event) !== -1) {
if (!_eventHandlers[event]) {
_eventHandlers[event] = [];
}
_eventHandlers[event].push(f);
}
};

that.getFrame = function() {
if (!loaded){
return null;
}
return frame;
};

return that;
};

return (InputStream);
});
12 changes: 12 additions & 0 deletions lib/quagga.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
var requirejs = require('requirejs');

requirejs.config({
"baseUrl" : "../src",
"paths" : {
"typedefs" : "typedefs",
"input_stream": "../lib/input_stream",
"frame_grabber": "../lib/frame_grabber"
}
});

module.exports = requirejs('quagga');
9 changes: 7 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
"name": "quagga",
"version": "0.6.6",
"description": "An advanced barcode-scanner written in JavaScript",
"main": "dist/quagga.js",
"main": "lib/quagga.js",
"browser": "dist/quagga.js",
"devDependencies": {
"async": "^0.9.0",
"grunt": "~0.4.5",
Expand Down Expand Up @@ -46,5 +47,9 @@
"imageprocessing"
],
"author": "Christoph Oberhofer <[email protected]>",
"license": "MIT"
"license": "MIT",
"dependencies": {
"get-pixels": "^3.2.2",
"gl-matrix": "^2.1.0"
}
}
21 changes: 11 additions & 10 deletions src/barcode_locator.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/* jshint undef: true, unused: true, browser:true, devel: true */
/* global define, mat2, vec2 */

define("barcode_locator", ["image_wrapper", "cv_utils", "rasterizer", "tracer", "skeletonizer", "array_helper", "image_debug"],
function(ImageWrapper, CVUtils, Rasterizer, Tracer, skeletonizer, ArrayHelper, ImageDebug) {
define("barcode_locator", ["image_wrapper", "cv_utils", "rasterizer", "tracer", "skeletonizer", "array_helper", "image_debug", "gl-matrix"],
function(ImageWrapper, CVUtils, Rasterizer, Tracer, skeletonizer, ArrayHelper, ImageDebug, glMatrix) {

var _config,
_currentImageWrapper,
Expand All @@ -25,6 +25,8 @@ function(ImageWrapper, CVUtils, Rasterizer, Tracer, skeletonizer, ArrayHelper, I
_numPatches = {x: 0, y: 0},
_inputImageWrapper,
_skeletonizer,
vec2 = glMatrix.vec2,
mat2 = glMatrix.mat2,
self = this;

function initBuffers() {
Expand Down Expand Up @@ -100,15 +102,14 @@ function(ImageWrapper, CVUtils, Rasterizer, Tracer, skeletonizer, ArrayHelper, I
overAvg += 180;
}

//console.log(overAvg);
overAvg = (180 - overAvg) * Math.PI / 180;
transMat = mat2.create([Math.cos(overAvg), -Math.sin(overAvg), Math.sin(overAvg), Math.cos(overAvg)]);
transMat = mat2.clone([Math.cos(overAvg), Math.sin(overAvg), -Math.sin(overAvg), Math.cos(overAvg)]);

// iterate over patches and rotate by angle
for ( i = 0; i < patches.length; i++) {
patch = patches[i];
for ( j = 0; j < 4; j++) {
mat2.xVec2(transMat, patch.box[j]);
vec2.transformMat2(patch.box[j], patch.box[j], transMat);
}

if (_config.boxFromPatches.showTransformed) {
Expand Down Expand Up @@ -143,17 +144,17 @@ function(ImageWrapper, CVUtils, Rasterizer, Tracer, skeletonizer, ArrayHelper, I

scale = _config.halfSample ? 2 : 1;
// reverse rotation;
transMat = mat2.inverse(transMat);
transMat = mat2.invert(transMat, transMat);
for ( j = 0; j < 4; j++) {
mat2.xVec2(transMat, box[j]);
vec2.transformMat2(box[j], box[j], transMat);
}

if (_config.boxFromPatches.showBB) {
ImageDebug.drawPath(box, {x: 0, y: 1}, _canvasContainer.ctx.binary, {color: '#ff0000', lineWidth: 2});
}

for ( j = 0; j < 4; j++) {
vec2.scale(box[j], scale);
vec2.scale(box[j], box[j], scale);
}

return box;
Expand Down Expand Up @@ -377,10 +378,10 @@ function(ImageWrapper, CVUtils, Rasterizer, Tracer, skeletonizer, ArrayHelper, I
x : x,
y : y
},
box : [vec2.create([x, y]), vec2.create([x + _subImageWrapper.size.x, y]), vec2.create([x + _subImageWrapper.size.x, y + _subImageWrapper.size.y]), vec2.create([x, y + _subImageWrapper.size.y])],
box : [vec2.clone([x, y]), vec2.clone([x + _subImageWrapper.size.x, y]), vec2.clone([x + _subImageWrapper.size.x, y + _subImageWrapper.size.y]), vec2.clone([x, y + _subImageWrapper.size.y])],
moments : matchingMoments,
rad : avg,
vec : vec2.create([Math.cos(avg), Math.sin(avg)])
vec : vec2.clone([Math.cos(avg), Math.sin(avg)])
};
patchesFound.push(patch);
}
Expand Down
11 changes: 6 additions & 5 deletions src/cluster.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
/* jshint undef: true, unused: true, browser:true, devel: true */
/* global define, vec2 */
/* global define */

define(function() {
define(["gl-matrix"], function(glMatrix) {
"use strict";


var vec2 = glMatrix.vec2;
/**
* Creates a cluster for grouping similar orientations of datapoints
*/
var Cluster = {
create : function(point, threshold) {
var points = [], center = {
rad : 0,
vec : vec2.create([0, 0])
vec : vec2.clone([0, 0])
}, pointMap = {};

function init() {
Expand All @@ -30,7 +31,7 @@ define(function() {
sum += points[i].rad;
}
center.rad = sum / points.length;
center.vec = vec2.create([Math.cos(center.rad), Math.sin(center.rad)]);
center.vec = vec2.clone([Math.cos(center.rad), Math.sin(center.rad)]);
}

init();
Expand Down
Loading

0 comments on commit a042422

Please sign in to comment.