Merge pull request #179 from marcbachmann/js-improvements

Use this.emit(‘error’) in streams
This commit is contained in:
Peter Braden 2014-10-15 19:38:17 +02:00
commit 40ad8ab2ae

View File

@ -1,157 +1,138 @@
var Stream = require('stream').Stream var Stream = require('stream').Stream
, Buffers = require('buffers') , Buffers = require('buffers')
, util = require('util') , util = require('util')
, path = require('path') , path = require('path');
var bindings = require('./bindings') var cv = module.exports = require('./bindings');
var Matrix = cv.Matrix, VideoCapture = cv.VideoCapture,
var cv = module.exports = {}; ImageStream, ImageDataStream, ObjectDetectionStream, VideoStream;
cv.__proto__ = bindings;
/*
# Matrix #
The matrix is one of opencv's most core datatypes.
*/
var matrix = cv.Matrix.prototype; Matrix.prototype.detectObject = function(classifier, opts, cb){
var face_cascade;
opts = opts || {};
cv._detectObjectClassifiers = cv._detectObjectClassifiers || {};
matrix.detectObject = function(classifier, opts, cb){ if (!(face_cascade = cv._detectObjectClassifiers[classifier])){
opts = opts || {} face_cascade = new cv.CascadeClassifier(classifier);
cv._detectObjectClassifiers = cv._detectObjectClassifiers || {}
if (cv._detectObjectClassifiers[classifier]){
var face_cascade = cv._detectObjectClassifiers[classifier];
} else{
var face_cascade = new cv.CascadeClassifier(classifier);
cv._detectObjectClassifiers[classifier] = face_cascade; cv._detectObjectClassifiers[classifier] = face_cascade;
} }
face_cascade.detectMultiScale(this, cb, opts.scale, opts.neighbors face_cascade.detectMultiScale(this, cb, opts.scale, opts.neighbors
, opts.min && opts.min[0], opts.min && opts.min[1]); , opts.min && opts.min[0], opts.min && opts.min[1]);
}
matrix.inspect = function(){
var size = this.size() ? (this.size()[0] + 'x' + this.size()[1]) : '';
return "[Matrix " + size + " ]";
}
cv.ImageDataStream = function(){
this.data = Buffers([])
this.writable = true
}
util.inherits(cv.ImageDataStream, Stream);
var imagedatastream = cv.ImageDataStream.prototype;
imagedatastream.write = function(buf){
this.data.push(buf)
return true;
} }
imagedatastream.end = function(b){ Matrix.prototype.inspect = function(){
var self = this; var size = (this.size()||[]).join('x');
return "[ Matrix " + size + " ]";
if (b)
imagestream.write.call(this,b);
var buf = this.data.toBuffer();
cv.readImage(buf, function(err, im){
self.emit('load', im);
});
} }
ImageStream =
cv.ImageStream = function(){ cv.ImageStream = function(){
this.writable = true this.writable = true;
}
util.inherits(ImageStream, Stream);
ImageStream.prototype.write = function(buf){
var self = this;
cv.readImage(buf, function(err, matrix){
if (err) return self.emit('error', err);
self.emit('data', matrix);
});
} }
util.inherits(cv.ImageStream, Stream);
var imagestream = cv.ImageStream.prototype;
imagestream.write = function(buf){ ImageDataStream =
var self = this; cv.ImageDataStream = function(){
cv.readImage(buf, function(err, matrix){ this.data = Buffers([]);
self.emit('data', matrix); this.writable = true;
}); }
util.inherits(ImageDataStream, Stream);
ImageDataStream.prototype.write = function(buf){
this.data.push(buf);
return true;
} }
// Object detect stream
ImageDataStream.prototype.end = function(b){
var self = this;
if (b) ImageStream.prototype.write.call(this, b);
var buf = this.data.toBuffer();
cv.readImage(buf, function(err, im){
if (err) return self.emit('error', err);
self.emit('load', im);
});
}
ObjectDetectionStream =
cv.ObjectDetectionStream = function(cascade, opts){ cv.ObjectDetectionStream = function(cascade, opts){
this.classifier = new cv.CascadeClassifier(cascade); this.classifier = new cv.CascadeClassifier(cascade);
this.opts = opts || {} this.opts = opts || {};
this.readable = true; this.readable = true;
this.writable = true; this.writable = true;
} }
util.inherits(ObjectDetectionStream, Stream);
util.inherits(cv.ObjectDetectionStream, Stream);
var ods = cv.ObjectDetectionStream.prototype;
ods.write = function(m){ ObjectDetectionStream.prototype.write = function(m){
var self = this; var self = this;
this.classifier.detectMultiScale(m, function(err, objs){
this.classifier.detectMultiScale(m, if (err) return self.emit('error', err);
function(e, objs){ self.emit('data', objs, m);
if (e) { throw e } }
self.emit('data', objs, m); , this.opts.scale
} , this.opts.neighbors
, this.opts.scale, this.opts.neighbors , this.opts.min && this.opts.min[0]
, this.opts.min && this.opts.min[0], this.opts.min && this.opts.min[1]); , this.opts.min && this.opts.min[1]);
} }
// == Video Stream ==
VideoStream =
cv.VideoStream = function(src){ cv.VideoStream = function(src){
if (src instanceof cv.VideoCapture){ if (!(src instanceof VideoCapture)) src = new VideoCapture(src);
this.video = src this.video = src;
} else {
this.video = new cv.VideoCapture(src);
}
this.readable = true; this.readable = true;
this.paused = false; this.paused = false;
} }
util.inherits(VideoStream, Stream);
util.inherits(cv.VideoStream, Stream);
var videostream = cv.VideoStream.prototype;
cv.VideoCapture.prototype.toStream = function(){
return new cv.VideoStream(this);
}
videostream.read = function(){ VideoStream.prototype.read = function(){
var self = this; var self = this;
var frame = function(){ var frame = function(){
self.video.read(function(err, mat){ self.video.read(function(err, mat){
self.emit('data', mat) if (err) return self.emit('error', err);
if (!self.paused){ self.emit('data', mat);
process.nextTick(frame) if (!self.paused) process.nextTick(frame);
}
}) })
} }
frame(); frame();
} }
videostream.pause = function(){
this.paused = true VideoStream.prototype.pause = function(){
this.paused = true;
} }
videostream.resume = function(){
this.paused = false VideoStream.prototype.resume = function(){
this.read() this.paused = false;
this.read();
} }
VideoCapture.prototype.toStream = function(){
return new VideoStream(this);
}
// Provide cascade data for faces etc. // Provide cascade data for faces etc.
cv.FACE_CASCADE = path.resolve(__dirname, '../data/haarcascade_frontalface_alt.xml') cv.FACE_CASCADE = path.resolve(__dirname, '../data/haarcascade_frontalface_alt.xml')