Permalink
Browse files

Merge github.com:talvarez/node-opencv

Conflicts:
	src/Matrix.cc
	src/Matrix.h
  • Loading branch information...
2 parents efbae5b + a030813 commit 4d1ea2867b5e3eb3efb9928437fdb7bec08a1ae9 @raichuk raichuk committed Jun 19, 2012
Showing with 847 additions and 184 deletions.
  1. 0 .gitignore
  2. 0 .travis.yml
  3. 0 README.md
  4. +1 −1 TODO
  5. 0 binding.gyp
  6. +6 −0 build.sh
  7. 0 data/haarcascade_eye.xml
  8. 0 data/haarcascade_eye_tree_eyeglasses.xml
  9. 0 data/haarcascade_frontalface_alt.xml
  10. 0 data/haarcascade_frontalface_alt2.xml
  11. 0 data/haarcascade_frontalface_alt_tree.xml
  12. 0 data/haarcascade_frontalface_default.xml
  13. 0 data/haarcascade_fullbody.xml
  14. 0 data/haarcascade_lefteye_2splits.xml
  15. 0 data/haarcascade_lowerbody.xml
  16. 0 data/haarcascade_mcs_eyepair_big.xml
  17. 0 data/haarcascade_mcs_eyepair_small.xml
  18. 0 data/haarcascade_mcs_lefteye.xml
  19. 0 data/haarcascade_mcs_mouth.xml
  20. 0 data/haarcascade_mcs_nose.xml
  21. 0 data/haarcascade_mcs_righteye.xml
  22. 0 data/haarcascade_mcs_upperbody.xml
  23. 0 data/haarcascade_profileface.xml
  24. 0 data/haarcascade_righteye_2splits.xml
  25. 0 data/haarcascade_upperbody.xml
  26. +61 −0 doc
  27. +16 −0 examples/addweighted.js
  28. +13 −0 examples/camera.js
  29. +36 −0 examples/contours.js
  30. +18 −0 examples/convert_image.js
  31. 0 examples/face-proxy.js
  32. +18 −0 examples/face_detection.js
  33. BIN examples/mona.jpg
  34. BIN examples/mona.png
  35. BIN examples/over_text.png
  36. +27 −0 examples/salt.js
  37. BIN examples/stuff.png
  38. 0 index.html
  39. 0 lib/bindings.js
  40. +1 −1 lib/opencv.js
  41. 0 package.json
  42. +1 −1 smoketest.js
  43. +24 −15 src/CascadeClassifierWrap.cc
  44. +1 −1 src/CascadeClassifierWrap.h
  45. +73 −0 src/Contours.cc
  46. +18 −0 src/Contours.h
  47. +386 −132 src/Matrix.cc
  48. +14 −0 src/Matrix.h
  49. 0 src/OpenCV.cc
  50. +1 −0 src/OpenCV.h
  51. 0 src/Point.cc
  52. 0 src/Point.h
  53. +82 −32 src/VideoCaptureWrap.cc
  54. +3 −1 src/VideoCaptureWrap.h
  55. +2 −0 src/init.cc
  56. 0 test/unit.js
  57. +45 −0 todo
  58. 0 wscript
View
0 .gitignore 100644 → 100755
File mode changed.
View
0 .travis.yml 100644 → 100755
File mode changed.
View
0 README.md 100644 → 100755
File mode changed.
View
2 TODO 100644 → 100755
@@ -42,4 +42,4 @@ cv.loadImage('test.jpg', function(err, im){
http://www.athile.net/library/wiki/index.php?title=Library/V8/Tutorial#Wrapping_a_Javascript_function_as_a_std::function.3C.3E
-https://www.cloudkick.com/blog/2010/aug/23/writing-nodejs-native-extensions/
+https://www.cloudkick.com/blog/2010/aug/23/writing-nodejs-native-extensions/
View
0 binding.gyp 100644 → 100755
File mode changed.
View
6 build.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+node-waf configure build &&
+cd examples &&
+#node face_detection.js
+node $1
View
0 data/haarcascade_eye.xml 100644 → 100755
File mode changed.
View
0 data/haarcascade_eye_tree_eyeglasses.xml 100644 → 100755
File mode changed.
View
0 data/haarcascade_frontalface_alt.xml 100644 → 100755
File mode changed.
View
0 data/haarcascade_frontalface_alt2.xml 100644 → 100755
File mode changed.
View
0 data/haarcascade_frontalface_alt_tree.xml 100644 → 100755
File mode changed.
View
0 data/haarcascade_frontalface_default.xml 100644 → 100755
File mode changed.
View
0 data/haarcascade_fullbody.xml 100644 → 100755
File mode changed.
View
0 data/haarcascade_lefteye_2splits.xml 100644 → 100755
File mode changed.
View
0 data/haarcascade_lowerbody.xml 100644 → 100755
File mode changed.
View
0 data/haarcascade_mcs_eyepair_big.xml 100644 → 100755
File mode changed.
View
0 data/haarcascade_mcs_eyepair_small.xml 100644 → 100755
File mode changed.
View
0 data/haarcascade_mcs_lefteye.xml 100644 → 100755
File mode changed.
View
0 data/haarcascade_mcs_mouth.xml 100644 → 100755
File mode changed.
View
0 data/haarcascade_mcs_nose.xml 100644 → 100755
File mode changed.
View
0 data/haarcascade_mcs_righteye.xml 100644 → 100755
File mode changed.
View
0 data/haarcascade_mcs_upperbody.xml 100644 → 100755
File mode changed.
View
0 data/haarcascade_profileface.xml 100644 → 100755
File mode changed.
View
0 data/haarcascade_righteye_2splits.xml 100644 → 100755
File mode changed.
View
0 data/haarcascade_upperbody.xml 100644 → 100755
File mode changed.
View
61 doc
@@ -0,0 +1,61 @@
+Examples
+Face Detection
+
+ cv.readImage("./examples/test.jpg", function(err, im){
+ im.detectObject("./examples/haarcascade_frontalface_alt.xml", {}, function(err, faces){
+ for (var i=0;i<faces.length; i++){
+ var x = faces[i]
+ im.ellipse(x.x + x.width/2, x.y + x.height/2, x.width/2, x.height/2);
+ }
+ im.save('./out.jpg');
+
+ });
+ })
+
+API Documentation
+Matrix
+
+The matrix is the most useful base datastructure in OpenCV. Things like images are just matrices of pixels.
+Creation
+
+ new Matrix(width, height)
+
+Or you can use opencv to read in image files. Supported formats are in the OpenCV docs, but jpgs etc are supported.
+
+ cv.readImage(filename, function(mat){
+ ...
+ })
+
+ cv.readImage(buffer, function(mat){
+ ...
+ })
+
+If you need to pipe data into an image, you can use an imagestream:
+
+ var s = new cv.ImageStream()
+
+ s.on('load', function(matrix){
+ ...
+ })
+
+ fs.createReadStream('./examples/test.jpg').pipe(s);
+
+Accessors
+
+ var mat = new cv.Matrix.Eye(4,4); // Create identity matrix
+
+ mat.get(0,0) // 1
+
+ mat.row(0) // [1,0,0,0]
+ mat.col(4) // [0,0,0,1]
+
+Image Processing
+Object Detection
+
+There is a shortcut method for Viola-Jones Haar Cascade object detection. This can be used for face detection etc.
+
+ mat.detectObject(haar_cascade_xml, opts, function(err, matches){})
+
+WIP
+
+This is a WIP. I've never written C++ before so the code may be interesting - if I'm doing stuff wrong please feel free to correct me.
View
16 examples/addweighted.js
@@ -0,0 +1,16 @@
+var cv = require('../lib/opencv');
+
+
+cv.readImage("./mona.png", function(err, orig) {
+
+ cv.readImage("./over_text.png", function(err, over_text) {
+
+ var result = new cv.Matrix(orig.width(), orig.height());
+
+ result.addWeighted(orig, 0.7, over_text, 0.9);
+ result.save("/tmp/weighted.png");
+ });
+
+});
+
+
View
13 examples/camera.js
@@ -0,0 +1,13 @@
+var cv = require('../lib/opencv');
+
+var camera = new cv.VideoCapture(0);
+
+
+setInterval(function() {
+
+ camera.read(function(im) {
+
+ im.save('/tmp/cam.png');
+ });
+
+}, 1000);
View
36 examples/contours.js
@@ -0,0 +1,36 @@
+var cv = require('../lib/opencv');
+
+var lowThresh = 0;
+var highThresh = 100;
+var nIters = 2;
+var maxArea = 2500;
+
+var GREEN = [0, 255, 0]; //B, G, R
+var WHITE = [255, 255, 255]; //B, G, R
+
+
+cv.readImage('./stuff.png', function(err, im) {
+
+ var big = new cv.Matrix(im.width(), im.height());
+ var all = new cv.Matrix(im.width(), im.height());
+
+ im.convertGrayscale();
+ im_canny = im.copy();
+
+ im_canny.canny(lowThresh, highThresh);
+ im_canny.dilate(nIters);
+
+ contours = im_canny.findContours();
+
+ for(i = 0; i < contours.size(); i++) {
+ if(contours.area(i) > maxArea) {
+ big.drawContour(contours, i, GREEN);
+ }
+ }
+
+ all.drawAllContours(contours, WHITE);
+
+
+ big.save('/tmp/big.png');
+ all.save('/tmp/all.png');
+});
View
18 examples/convert_image.js
@@ -0,0 +1,18 @@
+var cv = require('../lib/opencv');
+
+
+cv.readImage("./mona.png", function(err, im) {
+
+ img_hsv = im.copy();
+ img_gray = im.copy();
+
+ img_hsv.convertHSVscale();
+ img_gray.convertGrayscale();
+
+ im.save("/tmp/nor.png");
+ img_hsv.save("/tmp/hsv.png");
+ img_gray.save("/tmp/gray.png");
+
+ console.log("Guardado");
+});
+
View
0 examples/face-proxy.js 100644 → 100755
File mode changed.
View
18 examples/face_detection.js
@@ -0,0 +1,18 @@
+var cv = require('../lib/opencv')
+ , assert = require('assert')
+ , fs =require('fs')
+
+
+//console.log(cv.version)
+cv.readImage("./mona.png", function(err, im){
+
+ im.detectObject("./haarcascade_frontalface_alt.xml", {}, function(err, faces){
+
+ for (var i=0;i<faces.length; i++){
+ var x = faces[i];
+ im.ellipse(x.x + x.width/2, x.y + x.height/2, x.width/2, x.height/2);
+ }
+
+ im.save('./out.png');
+ });
+});
View
BIN examples/mona.jpg
Deleted file not rendered
View
BIN examples/mona.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN examples/over_text.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
27 examples/salt.js
@@ -0,0 +1,27 @@
+var cv = require('../lib/opencv');
+
+
+cv.readImage("./mona.png", function(err, im) {
+ salt(im, 3000);
+ im.save("/tmp/salt.png");
+});
+
+
+
+function salt(img, n) {
+
+
+ if (img.channels() == 1) {
+
+ console.log("1 Canales");
+ } else if (img.channels() == 3) {
+
+ for(k = 0; k < n; k ++) {
+ i = Math.random() * img.width();
+ j = Math.random() * img.height();
+
+ img.set(j, i, 255);
+ }
+ }
+
+}
View
BIN examples/stuff.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
0 index.html 100644 → 100755
File mode changed.
View
0 lib/bindings.js 100644 → 100755
File mode changed.
View
2 lib/opencv.js 100644 → 100755
@@ -1,5 +1,5 @@
var Stream = require('stream').Stream
- , Buffers = require('buffers')
+ , Buffers = require('buffer')
, util = require('util');
var bindings = require('./bindings')
View
0 package.json 100644 → 100755
File mode changed.
View
2 smoketest.js
@@ -14,4 +14,4 @@ var cv = require('./lib/opencv')
im.save('./out.jpg');
});
-})
+})
View
39 src/CascadeClassifierWrap.cc 100644 → 100755
@@ -3,6 +3,8 @@
#include "Matrix.h"
+void AsyncDetectMultiScale(uv_work_t *req);
+void AfterAsyncDetectMultiScale(uv_work_t *req);
Persistent<FunctionTemplate> CascadeClassifierWrap::constructor;
@@ -61,6 +63,8 @@ struct classifier_baton_t {
int minh;
int sleep_for;
std::vector<cv::Rect> res;
+
+ uv_work_t request;
};
@@ -102,42 +106,47 @@ CascadeClassifierWrap::DetectMultiScale(const v8::Arguments& args){
baton->minw = minw;
baton->minh = minh;
baton->sleep_for = 1;
- self->Ref();
+ baton->request.data = baton;
+// self->Ref();
+
+// eio_custom(EIO_DetectMultiScale, EIO_PRI_DEFAULT, EIO_AfterDetectMultiScale, baton);
+// ev_ref(EV_DEFAULT_UC);
- eio_custom(EIO_DetectMultiScale, EIO_PRI_DEFAULT, EIO_AfterDetectMultiScale, baton);
- ev_ref(EV_DEFAULT_UC);
+ uv_queue_work(uv_default_loop(), &baton->request, AsyncDetectMultiScale, AfterAsyncDetectMultiScale);
return Undefined();
}
-
-void
-CascadeClassifierWrap::EIO_DetectMultiScale(eio_req *req){
- classifier_baton_t *baton = static_cast<classifier_baton_t *>(req->data);
- sleep(baton->sleep_for);
+void AsyncDetectMultiScale(uv_work_t *req) {
+ classifier_baton_t *baton = static_cast<classifier_baton_t *>(req->data);
+// sleep(baton->sleep_for);
std::vector<cv::Rect> objects;
cv::Mat gray;
- cvtColor( baton->im->mat, gray, CV_BGR2GRAY );
- equalizeHist( gray, gray);
+ if(baton->im->mat.channels() != 1)
+ cvtColor(baton->im->mat, gray, CV_BGR2GRAY);
+
+ equalizeHist( gray, gray);
baton->cc->cc.detectMultiScale(gray, objects, baton->scale, baton->neighbors, 0, cv::Size(baton->minw, baton->minh));
baton->res = objects;
+
+
}
-int
-CascadeClassifierWrap::EIO_AfterDetectMultiScale(eio_req *req){
+void AfterAsyncDetectMultiScale(uv_work_t *req) {
+
HandleScope scope;
classifier_baton_t *baton = static_cast<classifier_baton_t *>(req->data);
- ev_unref(EV_DEFAULT_UC);
- baton->cc->Unref();
+// ev_unref(EV_DEFAULT_UC);
+// baton->cc->Unref();
Local<Value> argv[2];
@@ -169,6 +178,6 @@ CascadeClassifierWrap::EIO_AfterDetectMultiScale(eio_req *req){
delete baton;
- return 0;
+// return 0;
}
View
2 src/CascadeClassifierWrap.h 100644 → 100755
@@ -16,4 +16,4 @@ class CascadeClassifierWrap: public node::ObjectWrap {
static void EIO_DetectMultiScale(eio_req *req);
static int EIO_AfterDetectMultiScale(eio_req *req);
-};
+};
View
73 src/Contours.cc
@@ -0,0 +1,73 @@
+#include "Contours.h"
+#include "OpenCV.h"
+
+#include <iostream>
+
+v8::Persistent<FunctionTemplate> Contour::constructor;
+
+
+void
+Contour::Init(Handle<Object> target) {
+ HandleScope scope;
+
+ //Class
+ v8::Local<v8::FunctionTemplate> m = v8::FunctionTemplate::New(New);
+ m->SetClassName(v8::String::NewSymbol("Contours"));
+
+ // Constructor
+ constructor = Persistent<FunctionTemplate>::New(m);
+ constructor->InstanceTemplate()->SetInternalFieldCount(1);
+ constructor->SetClassName(String::NewSymbol("Contours"));
+
+ // Prototype
+ Local<ObjectTemplate> proto = constructor->PrototypeTemplate();
+
+
+ NODE_SET_PROTOTYPE_METHOD(constructor, "size", Size);
+ NODE_SET_PROTOTYPE_METHOD(constructor, "area", Area);
+ target->Set(String::NewSymbol("Contours"), m->GetFunction());
+};
+
+
+Handle<Value>
+Contour::New(const Arguments &args) {
+ HandleScope scope;
+
+ if (args.This()->InternalFieldCount() == 0)
+ return v8::ThrowException(v8::Exception::TypeError(v8::String::New("Cannot instantiate without new")));
+
+ Contour *contours;
+ contours = new Contour;
+
+ contours->Wrap(args.Holder());
+ return scope.Close(args.Holder());
+}
+
+
+Contour::Contour(): ObjectWrap() {
+}
+
+
+Handle<Value>
+Contour::Size(const Arguments &args) {
+ HandleScope scope;
+
+ Contour *self = ObjectWrap::Unwrap<Contour>(args.This());
+
+ return scope.Close(Number::New(self->contours.size()));
+
+}
+
+
+Handle<Value>
+Contour::Area(const Arguments &args) {
+ HandleScope scope;
+
+ Contour *self = ObjectWrap::Unwrap<Contour>(args.This());
+ int pos = args[0]->NumberValue();
+
+ //return scope.Close(Number::New(contourArea(self->contours)));
+ return scope.Close(Number::New(contourArea(cv::Mat(self->contours[pos]))));
+
+
+}
View
18 src/Contours.h
@@ -0,0 +1,18 @@
+#include "OpenCV.h"
+
+class Contour: public node::ObjectWrap {
+ public:
+
+ cv::Mat mat;
+ vector<vector<cv::Point> > contours;
+ static Persistent<FunctionTemplate> constructor;
+ static void Init(Handle<Object> target);
+ static Handle<Value> New(const Arguments &args);
+
+ Contour();
+
+ //JSFUNC(Size)
+ static Handle<Value> Size(const v8::Arguments&);
+ static Handle<Value> Area(const v8::Arguments&);
+};
+
View
518 src/Matrix.cc 100644 → 100755
@@ -1,162 +1,199 @@
+#include "Contours.h"
#include "Matrix.h"
#include "OpenCV.h"
v8::Persistent<FunctionTemplate> Matrix::constructor;
+cv::Scalar setColor(Local<Object> objColor);
+
+//
void
Matrix::Init(Handle<Object> target) {
- HandleScope scope;
+ HandleScope scope;
+
+ //Class
+ v8::Local<v8::FunctionTemplate> m = v8::FunctionTemplate::New(New);
+ m->SetClassName(v8::String::NewSymbol("Matrix"));
+
+ // Constructor
+ constructor = Persistent<FunctionTemplate>::New(m);
+ constructor->InstanceTemplate()->SetInternalFieldCount(1);
+ constructor->SetClassName(String::NewSymbol("Matrix"));
- //Class
- v8::Local<v8::FunctionTemplate> m = v8::FunctionTemplate::New(New);
- m->SetClassName(v8::String::NewSymbol("Matrix"));
+ // Prototype
+ Local<ObjectTemplate> proto = constructor->PrototypeTemplate();
- // Constructor
- constructor = Persistent<FunctionTemplate>::New(m);
- constructor->InstanceTemplate()->SetInternalFieldCount(1);
- constructor->SetClassName(String::NewSymbol("Matrix"));
- // Prototype
- Local<ObjectTemplate> proto = constructor->PrototypeTemplate();
+ NODE_SET_PROTOTYPE_METHOD(constructor, "row", Row);
+ NODE_SET_PROTOTYPE_METHOD(constructor, "col", Col);
+ NODE_SET_PROTOTYPE_METHOD(constructor, "pixelRow", PixelRow);
+ NODE_SET_PROTOTYPE_METHOD(constructor, "pixelCol", PixelCol);
- NODE_SET_PROTOTYPE_METHOD(constructor, "row", Row);
- NODE_SET_PROTOTYPE_METHOD(constructor, "col", Col);
+ NODE_SET_PROTOTYPE_METHOD(constructor, "empty", Empty);
+ NODE_SET_PROTOTYPE_METHOD(constructor, "get", Get);
+ NODE_SET_PROTOTYPE_METHOD(constructor, "set", Set);
+ NODE_SET_PROTOTYPE_METHOD(constructor, "width", Width);
+ NODE_SET_PROTOTYPE_METHOD(constructor, "height", Height);
+ NODE_SET_PROTOTYPE_METHOD(constructor, "size", Size);
+ NODE_SET_PROTOTYPE_METHOD(constructor, "toBuffer", ToBuffer);
+ NODE_SET_PROTOTYPE_METHOD(constructor, "ellipse", Ellipse);
+ NODE_SET_PROTOTYPE_METHOD(constructor, "save", Save);
+ NODE_SET_PROTOTYPE_METHOD(constructor, "resize", Resize);
+ NODE_SET_PROTOTYPE_METHOD(constructor, "channels", Channels);
- NODE_SET_PROTOTYPE_METHOD(constructor, "pixelRow", PixelRow);
- NODE_SET_PROTOTYPE_METHOD(constructor, "pixelCol", PixelCol);
+ NODE_SET_PROTOTYPE_METHOD(constructor, "convertGrayscale", ConvertGrayscale);
+ NODE_SET_PROTOTYPE_METHOD(constructor, "convertHSVscale", ConvertHSVscale);
+ NODE_SET_PROTOTYPE_METHOD(constructor, "copy", Copy);
+ NODE_SET_PROTOTYPE_METHOD(constructor, "ptr", Ptr);
+ NODE_SET_PROTOTYPE_METHOD(constructor, "addWeighted", AddWeighted);
+ NODE_SET_PROTOTYPE_METHOD(constructor, "split", Split);
+ NODE_SET_PROTOTYPE_METHOD(constructor, "bla", Bla);
+ NODE_SET_PROTOTYPE_METHOD(constructor, "canny", Canny);
+ NODE_SET_PROTOTYPE_METHOD(constructor, "dilate", Dilate);
- NODE_SET_PROTOTYPE_METHOD(constructor, "empty", Empty);
- NODE_SET_PROTOTYPE_METHOD(constructor, "get", Get);
- NODE_SET_PROTOTYPE_METHOD(constructor, "set", Set);
- NODE_SET_PROTOTYPE_METHOD(constructor, "width", Width);
- NODE_SET_PROTOTYPE_METHOD(constructor, "height", Height);
- NODE_SET_PROTOTYPE_METHOD(constructor, "size", Size);
- NODE_SET_PROTOTYPE_METHOD(constructor, "toBuffer", ToBuffer);
- NODE_SET_PROTOTYPE_METHOD(constructor, "ellipse", Ellipse);
- NODE_SET_PROTOTYPE_METHOD(constructor, "save", Save);
- NODE_SET_PROTOTYPE_METHOD(constructor, "resize", Resize);
+ NODE_SET_PROTOTYPE_METHOD(constructor, "findContours", FindContours);
+ NODE_SET_PROTOTYPE_METHOD(constructor, "drawContour", DrawContour);
+ NODE_SET_PROTOTYPE_METHOD(constructor, "drawAllContours", DrawAllContours);
- NODE_SET_METHOD(constructor, "Eye", Eye);
+ NODE_SET_METHOD(constructor, "Eye", Eye);
- target->Set(String::NewSymbol("Matrix"), m->GetFunction());
-};
+ target->Set(String::NewSymbol("Matrix"), m->GetFunction());
+};
Handle<Value>
Matrix::New(const Arguments &args) {
- HandleScope scope;
+ HandleScope scope;
+
+ if (args.This()->InternalFieldCount() == 0)
+ return v8::ThrowException(v8::Exception::TypeError(v8::String::New("Cannot instantiate without new")));
- if (args.This()->InternalFieldCount() == 0)
- return v8::ThrowException(v8::Exception::TypeError(v8::String::New("Cannot instantiate without new")));
+ Matrix *mat;
- Matrix *mat;
+ if (args.Length() == 0){
+ mat = new Matrix;
+ } else if (args.Length() == 2 && args[0]->IsInt32() && args[1]->IsInt32()){
+ mat = new Matrix(args[0]->IntegerValue(), args[1]->IntegerValue());
+ }
- if (args.Length() == 0){
- mat = new Matrix;
- } else if (args.Length() == 2 && args[0]->IsInt32() && args[1]->IsInt32()){
- mat = new Matrix(args[0]->IntegerValue(), args[1]->IntegerValue());
- }
- mat->Wrap(args.Holder());
- return scope.Close(args.Holder());
+ mat->Wrap(args.Holder());
+ return scope.Close(args.Holder());
}
+
Matrix::Matrix(): ObjectWrap() {
- mat = cv::Mat();
+ mat = cv::Mat();
}
+
Matrix::Matrix(int w, int h): ObjectWrap() {
mat = cv::Mat(w, h, CV_32FC3);
+ //TODO:Parametrizar esto
+ //mat = cv::Mat(h, w, CV_8UC3);
}
-Handle<Value>
+
+Handle<Value>
Matrix::Empty(const Arguments& args){
- SETUP_FUNCTION(Matrix)
+ SETUP_FUNCTION(Matrix)
- return scope.Close(Boolean::New(self->mat.empty()));
+ return scope.Close(Boolean::New(self->mat.empty()));
}
-Handle<Value>
+Handle<Value>
Matrix::Get(const Arguments& args){
- SETUP_FUNCTION(Matrix)
+ SETUP_FUNCTION(Matrix)
- int i = args[0]->IntegerValue();
- int j = args[1]->IntegerValue();
+ int i = args[0]->IntegerValue();
+ int j = args[1]->IntegerValue();
- return scope.Close(Number::New(self->mat.at<double>(i,j)));
+ return scope.Close(Number::New(self->mat.at<double>(i,j)));
}
Handle<Value>
Matrix::Set(const Arguments& args){
- SETUP_FUNCTION(Matrix)
+ SETUP_FUNCTION(Matrix)
- int i = args[0]->IntegerValue();
- int j = args[1]->IntegerValue();
- double val = args[2]->NumberValue();
+ int i = args[0]->IntegerValue();
+ int j = args[1]->IntegerValue();
+ double val = args[2]->NumberValue();
- self->mat.at<double>(i,j) = val;
+ if(args.Length() == 4) {
+ self->mat.at<cv::Vec3b>(i,j)[args[3]->NumberValue()] = val;
- return scope.Close(Undefined());
+ } else if(args.Length() == 3) {
+ self->mat.at<cv::Vec3b>(i,j)[0] = val;
+ self->mat.at<cv::Vec3b>(i,j)[1] = val;
+ self->mat.at<cv::Vec3b>(i,j)[2] = val;
+
+ } else {
+ return ThrowException(Exception::TypeError(String::New("Invalid number of arguments")));
+ }
+
+ return scope.Close(Undefined());
}
Handle<Value>
Matrix::Size(const Arguments& args){
- SETUP_FUNCTION(Matrix)
+ SETUP_FUNCTION(Matrix)
- v8::Local<v8::Array> arr = v8::Array::New(2);
- arr->Set(0, Number::New(self->mat.size().height));
- arr->Set(1, Number::New(self->mat.size().width));
+ v8::Local<v8::Array> arr = v8::Array::New(2);
+ arr->Set(0, Number::New(self->mat.size().height));
+ arr->Set(1, Number::New(self->mat.size().width));
- return scope.Close(arr);
+ return scope.Close(arr);
}
Handle<Value>
Matrix::Row(const Arguments& args){
- SETUP_FUNCTION(Matrix)
-
- int width = self->mat.size().width;
- int y = args[0]->IntegerValue();
- v8::Local<v8::Array> arr = v8::Array::New(width);
-
- for (int x=0; x<width; x++){
- double v = 0;
- if (self->mat.channels() == 1){
- v = self->mat.at<float>(y, x);
- } else {
- // Assume 3 channel RGB
- unsigned int val = 0;
- cv::Vec3b pixel = self->mat.at<cv::Vec3b>(y, x);
- val &= (uchar) pixel.val[2];
- val &= ((uchar) pixel.val[1]) << 8;
- val &= ((uchar) pixel.val[0]) << 16;
- v = (double) val;
- }
- arr->Set(x, Number::New(v));
- }
- return scope.Close(arr);
+ SETUP_FUNCTION(Matrix)
+
+ int width = self->mat.size().width;
+ int y = args[0]->IntegerValue();
+ v8::Local<v8::Array> arr = v8::Array::New(width);
+
+ for (int x=0; x<width; x++){
+ double v = 0;
+ if (self->mat.channels() == 1){
+ v = self->mat.at<float>(y, x);
+ } else {
+ // Assume 3 channel RGB
+ unsigned int val = 0;
+ cv::Vec3b pixel = self->mat.at<cv::Vec3b>(y, x);
+ val &= (uchar) pixel.val[2];
+ val &= ((uchar) pixel.val[1]) << 8;
+ val &= ((uchar) pixel.val[0]) << 16;
+ v = (double) val;
+ }
+ arr->Set(x, Number::New(v));
+ }
+
+ return scope.Close(arr);
}
Handle<Value>
-Matrix::PixelRow(const Arguments& args){
- SETUP_FUNCTION(Matrix)
-
- int width = self->mat.size().width;
- int y = args[0]->IntegerValue();
- v8::Local<v8::Array> arr = v8::Array::New(width * 3);
+ Matrix::PixelRow(const Arguments& args){
+ SETUP_FUNCTION(Matrix)
+
+ int width = self->mat.size().width;
+ int y = args[0]->IntegerValue();
+ v8::Local<v8::Array> arr = v8::Array::New(width * 3);
+
+ for (int x=0; x<width; x++){
+ cv::Vec3b pixel = self->mat.at<cv::Vec3b>(y, x);
+ int offset = x * 3;
+ arr->Set(offset , Number::New((double)pixel.val[0]));
+ arr->Set(offset + 1, Number::New((double)pixel.val[1]));
+ arr->Set(offset + 2, Number::New((double)pixel.val[2]));
+}
- for (int x=0; x<width; x++){
- cv::Vec3b pixel = self->mat.at<cv::Vec3b>(y, x);
- int offset = x * 3;
- arr->Set(offset , Number::New((double)pixel.val[0]));
- arr->Set(offset + 1, Number::New((double)pixel.val[1]));
- arr->Set(offset + 2, Number::New((double)pixel.val[2]));
- }
- return scope.Close(arr);
+ return scope.Close(arr);
}
Handle<Value>
@@ -206,46 +243,51 @@ Matrix::PixelCol(const Arguments& args){
Handle<Value>
Matrix::Width(const Arguments& args){
- SETUP_FUNCTION(Matrix)
+ SETUP_FUNCTION(Matrix)
- return scope.Close(Number::New(self->mat.size().width));
+ return scope.Close(Number::New(self->mat.size().width));
}
Handle<Value>
Matrix::Height(const Arguments& args){
- SETUP_FUNCTION(Matrix)
+ SETUP_FUNCTION(Matrix)
- return scope.Close(Number::New(self->mat.size().height));
-}
+ return scope.Close(Number::New(self->mat.size().height));
+}
+Handle<Value>
+Matrix::Channels(const Arguments& args){
+ SETUP_FUNCTION(Matrix)
+
+ return scope.Close(Number::New(self->mat.channels()));
+}
Handle<Value>
Matrix::ToBuffer(const v8::Arguments& args){
- SETUP_FUNCTION(Matrix)
-
- std::vector<uchar> vec(0);
- std::vector<int> params(0);//CV_IMWRITE_JPEG_QUALITY 90
+ SETUP_FUNCTION(Matrix)
- cv::imencode(".jpg", self->mat, vec, params);
+ std::vector<uchar> vec(0);
+ std::vector<int> params(0);//CV_IMWRITE_JPEG_QUALITY 90
- node::Buffer *buf = node::Buffer::New(vec.size());
- uchar* data = (uchar*) Buffer::Data(buf);
- memcpy(data, &vec[0], vec.size());
+ cv::imencode(".jpg", self->mat, vec, params);
- v8::Local<v8::Object> globalObj = v8::Context::GetCurrent()->Global();
- v8::Local<v8::Function> bufferConstructor = v8::Local<v8::Function>::Cast(globalObj->Get(v8::String::New("Buffer")));
- v8::Handle<v8::Value> constructorArgs[3] = {buf->handle_, v8::Integer::New(vec.size()), v8::Integer::New(0)};
- v8::Local<v8::Object> actualBuffer = bufferConstructor->NewInstance(3, constructorArgs);
+ node::Buffer *buf = node::Buffer::New(vec.size());
+ uchar* data = (uchar*) Buffer::Data(buf);
+ memcpy(data, &vec[0], vec.size());
- return scope.Close(actualBuffer);
-}
+ v8::Local<v8::Object> globalObj = v8::Context::GetCurrent()->Global();
+ v8::Local<v8::Function> bufferConstructor = v8::Local<v8::Function>::Cast(globalObj->Get(v8::String::New("Buffer")));
+ v8::Handle<v8::Value> constructorArgs[3] = {buf->handle_, v8::Integer::New(vec.size()), v8::Integer::New(0)};
+ v8::Local<v8::Object> actualBuffer = bufferConstructor->NewInstance(3, constructorArgs);
+
+ return scope.Close(actualBuffer);
+}
- // ellipse(x, y, wid, height, angle, startangle, endangle, color, thickness, linetype, shift)
Handle<Value>
Matrix::Ellipse(const v8::Arguments& args){
- SETUP_FUNCTION(Matrix)
+ SETUP_FUNCTION(Matrix)
int x = args[0]->Uint32Value();
int y = args[1]->Uint32Value();
@@ -256,38 +298,250 @@ Matrix::Ellipse(const v8::Arguments& args){
cv::ellipse(self->mat, cv::Point(x, y), cv::Size(width, height), 0, 0, 360,
cv::Scalar( (color >> 16) & 0xff , (color >> 8) & 0xff, color & 0xff ), 4, 8, 0);
return scope.Close(v8::Null());
-}
+ }
Handle<Value>
Matrix::Save(const v8::Arguments& args){
- HandleScope scope;
+ HandleScope scope;
- if (!args[0]->IsString())
- return ThrowException(Exception::TypeError(String::New("filename required")));
-
- Matrix *self = ObjectWrap::Unwrap<Matrix>(args.This());
- String::AsciiValue filename(args[0]);
- int res = cv::imwrite(*filename, self->mat);
- return scope.Close(Number::New(res));
+ if (!args[0]->IsString())
+ return ThrowException(Exception::TypeError(String::New("filename required")));
+
+ Matrix *self = ObjectWrap::Unwrap<Matrix>(args.This());
+ String::AsciiValue filename(args[0]);
+ int res = cv::imwrite(*filename, self->mat);
+ return scope.Close(Number::New(res));
}
+
Handle<Value>
Matrix::Eye(const v8::Arguments& args){
- HandleScope scope;
+ HandleScope scope;
+
+ int w = args[0]->Uint32Value();
+ int h = args[1]->Uint32Value();
+
+ Local<Object> im_h = Matrix::constructor->GetFunction()->NewInstance();
+ Matrix *img = ObjectWrap::Unwrap<Matrix>(im_h);
+ cv::Mat mat = cv::Mat::eye(w, h, CV_64FC1);
+
+ img->mat = mat;
+ return scope.Close(im_h);
+}
+
+
+Handle<Value>
+Matrix::ConvertGrayscale(const v8::Arguments& args) {
+ HandleScope scope;
+
+ Matrix *self = ObjectWrap::Unwrap<Matrix>(args.This());
+ if(self->mat.channels() != 3)
+ return ThrowException(String::New("Image is no 3-channel"));
+
+ cv::Mat gray;
+
+ cv::cvtColor(self->mat, gray, CV_BGR2GRAY);
+ gray.copyTo(self->mat);
+
+
+ return scope.Close(v8::Null());
+}
+
+
+Handle<Value>
+Matrix::ConvertHSVscale(const v8::Arguments& args) {
+ HandleScope scope;
+
+ Matrix *self = ObjectWrap::Unwrap<Matrix>(args.This());
+ if(self->mat.channels() != 3)
+ return ThrowException(String::New("Image is no 3-channel"));
+
+ cv::Mat hsv;
+
+ cv::cvtColor(self->mat, hsv, CV_BGR2HSV);
+ hsv.copyTo(self->mat);
- int w = args[0]->Uint32Value();
- int h = args[1]->Uint32Value();
+ return scope.Close(v8::Null());
+}
+
+
+Handle<Value>
+Matrix::Copy(const v8::Arguments& args) {
+ HandleScope scope;
+
+ Matrix *self = ObjectWrap::Unwrap<Matrix>(args.This());
+
+ Local<Object> img_to_return = Matrix::constructor->GetFunction()->NewInstance();
+ Matrix *img = ObjectWrap::Unwrap<Matrix>(img_to_return);
+ self->mat.copyTo(img->mat);
+
+ return scope.Close(img_to_return);
+}
+
+
+Handle<Value>
+Matrix::Ptr(const v8::Arguments& args) {
+ HandleScope scope;
+ Matrix *self = ObjectWrap::Unwrap<Matrix>(args.This());
+ int line = args[0]->Uint32Value();
+
+
+ char* data = self->mat.ptr<char>(line);
+ //uchar* data = self->mat.data;
+
+/*
+ char *mydata = "Random raw data\0";
+*/
+ node::Buffer *return_buffer = Buffer::New((char *)data, self->mat.step);
+ return scope.Close( return_buffer->handle_ );
+
+// return Undefined();
+}
+
+Handle<Value>
+Matrix::Bla(const v8::Arguments& args) {
+ HandleScope scope;
+ int i = args[1]->Uint32Value();
+
+ int div = 64;
+
+ if (Buffer::HasInstance(args[0])){
+
+ char *buf = (char *) Buffer::Data(args[0]->ToObject());
+ unsigned len = Buffer::Length(args[0]->ToObject());
+
+ }
+ return Undefined();
+
+}
+
+
+Handle<Value>
+Matrix::AddWeighted(const v8::Arguments& args) {
+ HandleScope scope;
+
+ Matrix *self = ObjectWrap::Unwrap<Matrix>(args.This());
+
+ Matrix *src1 = ObjectWrap::Unwrap<Matrix>(args[0]->ToObject());
+ Matrix *src2 = ObjectWrap::Unwrap<Matrix>(args[2]->ToObject());
+
+ float alpha = args[1]->NumberValue();
+ float beta = args[3]->NumberValue();
+ int gamma = 0;
+
+ cv::addWeighted(src1->mat, alpha, src2->mat, beta, gamma, self->mat);
+
+
+ return scope.Close(v8::Null());
+}
+
+
+Handle<Value>
+Matrix::Split(const v8::Arguments& args) {
+ HandleScope scope;
+
+ Matrix *self = ObjectWrap::Unwrap<Matrix>(args.This());
+
+ return scope.Close(v8::Null());
+}
+
+
+Handle<Value>
+Matrix::Canny(const v8::Arguments& args) {
+ HandleScope scope;
+
+ Matrix *self = ObjectWrap::Unwrap<Matrix>(args.This());
+ int lowThresh = args[0]->NumberValue();
+ int highThresh = args[1]->NumberValue();
- Local<Object> im_h = Matrix::constructor->GetFunction()->NewInstance();
- Matrix *img = ObjectWrap::Unwrap<Matrix>(im_h);
- cv::Mat mat = cv::Mat::eye(w, h, CV_32F);
+ cv::Canny(self->mat, self->mat, lowThresh, highThresh);
- img->mat = mat;
- return scope.Close(im_h);
+ return scope.Close(v8::Null());
}
+Handle<Value>
+Matrix::Dilate(const v8::Arguments& args) {
+ HandleScope scope;
+
+ Matrix *self = ObjectWrap::Unwrap<Matrix>(args.This());
+ int niters = args[0]->NumberValue();
+
+ cv::dilate(self->mat, self->mat, cv::Mat(), cv::Point(-1, -1), niters);
+
+ return scope.Close(v8::Null());
+}
+
+
+Handle<Value>
+Matrix::FindContours(const v8::Arguments& args) {
+ HandleScope scope;
+
+ Matrix *self = ObjectWrap::Unwrap<Matrix>(args.This());
+
+ Local<Object> conts_to_return= Contour::constructor->GetFunction()->NewInstance();
+ Contour *contours = ObjectWrap::Unwrap<Contour>(conts_to_return);
+
+ cv::findContours(self->mat, contours->contours, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);
+
+ return scope.Close(conts_to_return);
+
+}
+
+
+Handle<Value>
+Matrix::DrawContour(const v8::Arguments& args) {
+ HandleScope scope;
+
+ Matrix *self = ObjectWrap::Unwrap<Matrix>(args.This());
+ Contour *cont = ObjectWrap::Unwrap<Contour>(args[0]->ToObject());
+ int pos = args[1]->NumberValue();
+
+ cv::Scalar color(0, 0, 255);
+
+ if(args[2]->IsArray()) {
+ Local<Object> objColor = args[2]->ToObject();
+ color = setColor(objColor);
+ }
+
+ cv::drawContours(self->mat, cont->contours, pos, color, 1);
+
+ return Undefined();
+}
+
+
+Handle<Value>
+Matrix::DrawAllContours(const v8::Arguments& args) {
+ HandleScope scope;
+
+ Matrix *self = ObjectWrap::Unwrap<Matrix>(args.This());
+ Contour *cont = ObjectWrap::Unwrap<Contour>(args[0]->ToObject());
+
+ cv::Scalar color(0, 0, 255);
+
+ if(args[1]->IsArray()) {
+ Local<Object> objColor = args[1]->ToObject();
+ color = setColor(objColor);
+ }
+
+ cv::drawContours(self->mat, cont->contours, -1, color, 1);
+
+ return Undefined();
+}
+
+
+cv::Scalar setColor(Local<Object> objColor) {
+
+ Local<Value> valB = objColor->Get(0);
+ Local<Value> valG = objColor->Get(1);
+ Local<Value> valR = objColor->Get(2);
+
+ cv::Scalar color = cv::Scalar(valB->IntegerValue(), valG->IntegerValue(), valR->IntegerValue());
+ return color;
+
+}
+
Handle<Value>
Matrix::Resize(const v8::Arguments& args){
View
14 src/Matrix.h 100644 → 100755
@@ -61,13 +61,27 @@ class Matrix: public node::ObjectWrap {
JSFUNC(Size)
JSFUNC(Width)
JSFUNC(Height)
+ JSFUNC(Channels)
JSFUNC(ToBuffer)
JSFUNC(Ellipse)
JSFUNC(Empty)
JSFUNC(Save)
JSFUNC(Resize)
+ JSFUNC(ConvertGrayscale)
+ JSFUNC(ConvertHSVscale)
+ JSFUNC(Copy)
+ JSFUNC(Ptr)
+ JSFUNC(Bla)
+ JSFUNC(AddWeighted)
+ JSFUNC(Split)
+ JSFUNC(Canny)
+ JSFUNC(Dilate)
+
+ JSFUNC(FindContours)
+ JSFUNC(DrawContour)
+ JSFUNC(DrawAllContours)
};
View
0 src/OpenCV.cc 100644 → 100755
File mode changed.
View
1 src/OpenCV.h 100644 → 100755
@@ -10,6 +10,7 @@
#include <highgui.h>
#include <string.h>
+
using namespace v8;
using namespace node;
View
0 src/Point.cc 100644 → 100755
File mode changed.
View
0 src/Point.h 100644 → 100755
File mode changed.
View
114 src/VideoCaptureWrap.cc 100644 → 100755
@@ -2,64 +2,114 @@
#include "Matrix.h"
#include "OpenCV.h"
+
+void AsyncRead(uv_work_t *req);
+void AfterAsyncRead(uv_work_t *req);
+
v8::Persistent<FunctionTemplate> VideoCaptureWrap::constructor;
+struct videocapture_baton {
+
+ Persistent<Function> cb;
+ VideoCaptureWrap *vc;
+ Matrix *im;
+
+ uv_work_t request;
+};
+
+
void
VideoCaptureWrap::Init(Handle<Object> target) {
HandleScope scope;
- // Constructor
- constructor = Persistent<FunctionTemplate>::New(FunctionTemplate::New(VideoCaptureWrap::New));
- constructor->InstanceTemplate()->SetInternalFieldCount(1);
- constructor->SetClassName(String::NewSymbol("VideoCapture"));
+ // Constructor
+ constructor = Persistent<FunctionTemplate>::New(FunctionTemplate::New(VideoCaptureWrap::New));
+ constructor->InstanceTemplate()->SetInternalFieldCount(1);
+ constructor->SetClassName(String::NewSymbol("VideoCapture"));
+
+ // Prototype
+ Local<ObjectTemplate> proto = constructor->PrototypeTemplate();
- // Prototype
- Local<ObjectTemplate> proto = constructor->PrototypeTemplate();
-
- NODE_SET_PROTOTYPE_METHOD(constructor, "getFrame", GetFrame);
+ NODE_SET_PROTOTYPE_METHOD(constructor, "read", Read);
- target->Set(String::NewSymbol("VideoCapture"), constructor->GetFunction());
+ target->Set(String::NewSymbol("VideoCapture"), constructor->GetFunction());
};
Handle<Value>
VideoCaptureWrap::New(const Arguments &args) {
- HandleScope scope;
+ HandleScope scope;
if (args.This()->InternalFieldCount() == 0)
- return v8::ThrowException(v8::Exception::TypeError(v8::String::New("Cannot Instantiate without new")));
+ return v8::ThrowException(v8::Exception::TypeError(v8::String::New("Cannot Instantiate without new")));
- VideoCaptureWrap *v;
+ VideoCaptureWrap *v;
+
+ if (args[0]->IsNumber()){
+ v = new VideoCaptureWrap(args[0]->NumberValue());
+ } else {}
- if (args[0]->IsNumber()){
- v = new VideoCaptureWrap(args[0]->NumberValue());
- } else {}
- v->Wrap(args.This());
- return args.This();
-}
+ v->Wrap(args.This());
+
+ return args.This();
+}
VideoCaptureWrap::VideoCaptureWrap(int device){
- HandleScope scope;
- cv::VideoCapture cap(device);
+ HandleScope scope;
+ cap.open(device);
- if(!cap.isOpened()){
- ThrowException(Exception::Error(String::New("Camera could not be opened")));
- }
+ if(!cap.isOpened()){
+ ThrowException(Exception::Error(String::New("Camera could not be opened")));
+ }
}
Handle<Value>
-VideoCaptureWrap::GetFrame(const Arguments &args) {
- SETUP_FUNCTION(VideoCaptureWrap)
+VideoCaptureWrap::Read(const Arguments &args) {
+
+ HandleScope scope;
+ VideoCaptureWrap *v = ObjectWrap::Unwrap<VideoCaptureWrap>(args.This());
+
+ REQ_FUN_ARG(0, cb);
+
+ videocapture_baton *baton = new videocapture_baton();
+ baton->vc = v;
+ baton->cb = Persistent<Function>::New(cb);
+ baton->im = new Matrix();
+ baton->request.data = baton;
- cv::Mat frame;
- self->cap.retrieve(frame);
+ uv_queue_work(uv_default_loop(), &baton->request, AsyncRead, AfterAsyncRead);
+ return Undefined();
- Local<Object> im_h = Matrix::constructor->GetFunction()->NewInstance();
- Matrix *im = ObjectWrap::Unwrap<Matrix>(im_h);
- im->mat = frame;
- return scope.Close(im_h);
}
-
+void AsyncRead(uv_work_t *req) {
+ videocapture_baton *baton = static_cast<videocapture_baton *>(req->data);
+
+ baton->vc->cap.read(baton->im->mat);
+}
+
+
+void AfterAsyncRead(uv_work_t *req) {
+
+ HandleScope scope;
+
+ videocapture_baton *baton = static_cast<videocapture_baton *>(req->data);
+
+ Local<Object> im_to_return= Matrix::constructor->GetFunction()->NewInstance();
+ Matrix *img = ObjectWrap::Unwrap<Matrix>(im_to_return);
+ cv::Mat mat;
+ mat = baton->im->mat;
+
+ img->mat = mat;
+ Local<Value> argv[1];
+
+ argv[0] = im_to_return;
+
+ baton->cb->Call(Context::GetCurrent()->Global(), 1, argv);
+ baton->cb.Dispose();
+
+ delete baton;
+
+}
View
4 src/VideoCaptureWrap.h 100644 → 100755
@@ -11,7 +11,9 @@ class VideoCaptureWrap: public node::ObjectWrap {
VideoCaptureWrap(const std::string& filename);
VideoCaptureWrap(int device);
- static Handle<Value> GetFrame(const v8::Arguments&);
+ static Handle<Value> Read(const v8::Arguments&);
+
+
static Handle<Value> GetFrameAt(const v8::Arguments&);
};
View
2 src/init.cc 100644 → 100755
@@ -3,6 +3,7 @@
#include "Matrix.h"
#include "CascadeClassifierWrap.h"
#include "VideoCaptureWrap.h"
+#include "Contours.h"
extern "C" void
@@ -13,4 +14,5 @@ init(Handle<Object> target) {
Matrix::Init(target);
CascadeClassifierWrap::Init(target);
VideoCaptureWrap::Init(target);
+ Contour::Init(target);
};
View
0 test/unit.js 100644 → 100755
File mode changed.
View
45 todo
@@ -0,0 +1,45 @@
+
+im.calcHistograms(function(err, hist){})
+
+im.calcHistograms(mask, function(err, hist){})
+
+
+
+
+
+## Face recognition TODO
+
+
+// Load Database
+// TODO<
+
+
+
+cv.loadImage('test.jpg', function(err, im){
+ im.detectObject("front-face.xml", {}, function(err, faces){
+ _.each(faces, function(v){
+
+ // TODO {
+
+ var section = im.slice(v.x, v.y, v.x + v.width, v.y + v.height);
+ section.convertGrayscale()
+ section.resize(WID, HEIGHT);
+ section.equaliseHistogram();
+
+ // } TODO
+
+ })
+ })
+})
+
+
+
+
+
+
+-----
+
+
+http://www.athile.net/library/wiki/index.php?title=Library/V8/Tutorial#Wrapping_a_Javascript_function_as_a_std::function.3C.3E
+
+https://www.cloudkick.com/blog/2010/aug/23/writing-nodejs-native-extensions/
View
0 wscript 100644 → 100755
File mode changed.

0 comments on commit 4d1ea28

Please sign in to comment.