diff --git a/README.md b/README.md index cbfb31f..ca3578d 100755 --- a/README.md +++ b/README.md @@ -13,31 +13,31 @@ You'll need OpenCV 2.3.1 installed. Then: - - npm install opencv - +```bash +$ npm install opencv +``` Or to build the repo: - - node-gyp rebuild - +```bash +$ node-gyp rebuild +``` ## Examples ### Face Detection - - cv.readImage("./examples/test.jpg", function(err, im){ - im.detectObject(cv.FACE_CASCADE, {}, function(err, faces){ - for (var i=0;i>", x, ":" , rec) if (x % 10 == 0){ m2.rectangle([rec[0], rec[1]], [rec[2], rec[3]]) diff --git a/examples/take-face-pics.js b/examples/take-face-pics.js index 616a02d..419bfdf 100644 --- a/examples/take-face-pics.js +++ b/examples/take-face-pics.js @@ -4,7 +4,7 @@ var vid = new cv.VideoCapture(0) var snap = function(){ - vid.read(function(im){ + vid.read(function(err, im){ im.detectObject(cv.FACE_CASCADE, {}, function(err, faces){ if (!faces){ console.log("No Faces") diff --git a/lib/opencv.js b/lib/opencv.js index 48a4284..edd51ec 100755 --- a/lib/opencv.js +++ b/lib/opencv.js @@ -50,14 +50,14 @@ util.inherits(cv.ImageDataStream, Stream); var imagedatastream = cv.ImageDataStream.prototype; imagedatastream.write = function(buf){ - this.data.push(buf) + this.data.push(buf) return true; } imagedatastream.end = function(b){ var self = this; - + if (b) imagestream.write.call(this,b); @@ -98,7 +98,7 @@ var ods = cv.ObjectDetectionStream.prototype; ods.write = function(m){ var self = this; - this.classifier.detectMultiScale(m, + this.classifier.detectMultiScale(m, function(e, objs){ if (e) { throw e } self.emit('data', objs, m); @@ -111,7 +111,7 @@ ods.write = function(m){ cv.VideoStream = function(src){ if (src instanceof cv.VideoCapture){ this.video = src - } else { + } else { this.video = new cv.VideoCapture(src); } this.readable = true; @@ -128,7 +128,7 @@ videostream.read = function(){ var self = this; var frame = function(){ - self.video.read(function(mat){ + self.video.read(function(err, mat){ self.emit('data', mat) if (!self.paused){ process.nextTick(frame) diff --git a/src/Matrix.cc b/src/Matrix.cc index 5a9bc52..8a254b2 100755 --- a/src/Matrix.cc +++ b/src/Matrix.cc @@ -46,6 +46,7 @@ Matrix::Init(Handle target) { NODE_SET_PROTOTYPE_METHOD(constructor, "save", Save); NODE_SET_PROTOTYPE_METHOD(constructor, "saveAsync", SaveAsync); NODE_SET_PROTOTYPE_METHOD(constructor, "resize", Resize); + NODE_SET_PROTOTYPE_METHOD(constructor, "rotate", Rotate); NODE_SET_PROTOTYPE_METHOD(constructor, "pyrDown", PyrDown); NODE_SET_PROTOTYPE_METHOD(constructor, "pyrUp", PyrUp); NODE_SET_PROTOTYPE_METHOD(constructor, "channels", Channels); @@ -54,6 +55,8 @@ Matrix::Init(Handle target) { NODE_SET_PROTOTYPE_METHOD(constructor, "convertHSVscale", ConvertHSVscale); NODE_SET_PROTOTYPE_METHOD(constructor, "gaussianBlur", GaussianBlur); NODE_SET_PROTOTYPE_METHOD(constructor, "copy", Copy); + NODE_SET_PROTOTYPE_METHOD(constructor, "flip", Flip); + NODE_SET_PROTOTYPE_METHOD(constructor, "roi", ROI); NODE_SET_PROTOTYPE_METHOD(constructor, "ptr", Ptr); NODE_SET_PROTOTYPE_METHOD(constructor, "addWeighted", AddWeighted); NODE_SET_PROTOTYPE_METHOD(constructor, "split", Split); @@ -73,6 +76,7 @@ Matrix::Init(Handle target) { NODE_SET_PROTOTYPE_METHOD(constructor, "locateROI", LocateROI); NODE_SET_PROTOTYPE_METHOD(constructor, "threshold", Threshold); + NODE_SET_PROTOTYPE_METHOD(constructor, "meanStdDev", MeanStdDev); NODE_SET_METHOD(constructor, "Eye", Eye); @@ -696,6 +700,54 @@ Matrix::Copy(const v8::Arguments& args) { } +Handle +Matrix::Flip(const v8::Arguments& args) { + HandleScope scope; + + Matrix *self = ObjectWrap::Unwrap(args.This()); + + if ( args.Length() < 1 || !args[0]->IsInt32() ) { + return v8::ThrowException(Exception::TypeError(String::New( + "Flip requires an integer flipCode argument (0 = X axis, positive = Y axis, negative = both axis)"))); + } + + int flipCode = args[0]->ToInt32()->Value(); + + Local img_to_return = Matrix::constructor->GetFunction()->NewInstance(); + Matrix *img = ObjectWrap::Unwrap(img_to_return); + cv::flip(self->mat, img->mat, flipCode); + + return scope.Close(img_to_return); +} + + +Handle +Matrix::ROI(const v8::Arguments& args) { + HandleScope scope; + + Matrix *self = ObjectWrap::Unwrap(args.This()); + + if ( args.Length() != 4 ) { + return v8::ThrowException(Exception::TypeError(String::New( + "ROI requires x,y,w,h arguments"))); + } + + // although it's an image to return, it is in fact a pointer to ROI of parent matrix + Local img_to_return = Matrix::constructor->GetFunction()->NewInstance(); + Matrix *img = ObjectWrap::Unwrap(img_to_return); + + int x = args[0]->IntegerValue(); + int y = args[1]->IntegerValue(); + int w = args[2]->IntegerValue(); + int h = args[3]->IntegerValue(); + + cv::Mat roi(self->mat, cv::Rect(x,y,w,h)); + img->mat = roi; + + return scope.Close(img_to_return); +} + + Handle Matrix::Ptr(const v8::Arguments& args) { HandleScope scope; @@ -927,6 +979,30 @@ Matrix::Resize(const v8::Arguments& args){ return scope.Close(Undefined()); } + +Handle +Matrix::Rotate(const v8::Arguments& args){ + HandleScope scope; + + Matrix *self = ObjectWrap::Unwrap(args.This()); + cv::Mat rotMatrix(2, 3, CV_32FC1); + cv::Mat res; + + float angle = args[0]->ToNumber()->Value(); + int x = args[1]->IsUndefined() ? round(self->mat.size().width / 2) : args[1]->Uint32Value(); + int y = args[1]->IsUndefined() ? round(self->mat.size().height / 2) : args[2]->Uint32Value(); + + cv::Point center = cv::Point(x,y); + + rotMatrix = getRotationMatrix2D(center, angle, 1.0); + + cv::warpAffine(self->mat, res, rotMatrix, self->mat.size()); + ~self->mat; + self->mat = res; + + return scope.Close(Undefined()); +} + Handle Matrix::PyrDown(const v8::Arguments& args){ SETUP_FUNCTION(Matrix) @@ -1040,3 +1116,22 @@ Matrix::Threshold(const v8::Arguments& args) { return scope.Close(img_to_return); } + +Handle +Matrix::MeanStdDev(const v8::Arguments& args) { + HandleScope scope; + + Matrix *self = ObjectWrap::Unwrap(args.This()); + + Local mean = Matrix::constructor->GetFunction()->NewInstance(); + Matrix *m_mean = ObjectWrap::Unwrap(mean); + Local stddev = Matrix::constructor->GetFunction()->NewInstance(); + Matrix *m_stddev = ObjectWrap::Unwrap(stddev); + + cv::meanStdDev(self->mat, m_mean->mat, m_stddev->mat); + + Local data = Object::New(); + data->Set(String::NewSymbol("mean"), mean); + data->Set(String::NewSymbol("stddev"), stddev); + return scope.Close(data); +} diff --git a/src/Matrix.h b/src/Matrix.h index 22ec85d..5fe490a 100755 --- a/src/Matrix.h +++ b/src/Matrix.h @@ -42,6 +42,7 @@ class Matrix: public node::ObjectWrap { JSFUNC(ToBufferAsync) JSFUNC(Resize) + JSFUNC(Rotate) JSFUNC(PyrDown) JSFUNC(PyrUp) @@ -49,6 +50,8 @@ class Matrix: public node::ObjectWrap { JSFUNC(ConvertHSVscale) JSFUNC(GaussianBlur) JSFUNC(Copy) + JSFUNC(Flip) + JSFUNC(ROI) JSFUNC(Ptr) JSFUNC(AddWeighted) JSFUNC(Split) @@ -70,6 +73,7 @@ class Matrix: public node::ObjectWrap { JSFUNC(AdjustROI) JSFUNC(Threshold) + JSFUNC(MeanStdDev) /* static Handle Val(const Arguments& args); static Handle RowRange(const Arguments& args);