28 Commits

Autor SHA1 Mensagem Data
Peter Braden 45846cd3b2 Open Source Bridge Live coding - woohoo 2013-06-19 11:21:59 -07:00
Peter Braden ca87972037 test it 2013-05-16 19:02:52 -07:00
Peter Braden bae7a1bfd9 threshold 2013-05-16 18:57:26 -07:00
Peter Braden 769d6ebf77 v0.1.0 2013-05-01 11:53:17 -07:00
Peter Braden 21917f3f17 Merge branch 'master' of github.com:peterbraden/node-opencv 2013-05-01 11:49:50 -07:00
Peter Braden 67abbf4c24 Merge pull request #45 from shykes/dockerfile
Build instructions for docker
2013-04-23 10:26:37 -07:00
Solomon Hykes d364f64b84 Added a Dockerfile describing how to build node-opencv and all its dependencies into a ready-to-use linux container 2013-04-21 11:35:29 -07:00
Peter Braden 440a72c38e Merge branch 'master' of github.com:peterbraden/node-opencv into beta 2013-04-09 21:34:41 -07:00
Peter Braden 865962c845 videocapture read now uses err, im convention 2013-04-09 21:34:00 -07:00
Peter Braden a347ab682e add adjustROI 2013-04-06 18:34:08 -07:00
Peter Braden f1d629bfb3 Merge pull request #43 from carter-thaxton/master
Add async save method
2013-03-28 10:21:40 -07:00
Carter Thaxton 507ecbf832 Add async save, triggering off existence of callback 2013-03-28 01:01:55 -07:00
Peter Braden f0461db126 Merge pull request #42 from mrnugget/patch-1
Fix travis.yml to run with correct Node.js version
2013-03-25 10:55:31 -07:00
Thorsten Ball 3c6028e0e3 Fix travis.yml to run with correct Node.js version
This changes the `.travis.yml` to use the correct Node.js version
by using strings as version numbers.

Relevant Travis CI documentation page: http://about.travis-ci.org/docs/user/languages/javascript-with-nodejs/#Choosing-Node-versions-to-test-against

Without using strings to specify the desired versions Travis CI
runs on Node.js 0.1 instead of 0.10.
2013-03-25 10:49:20 +01:00
Peter Braden 95b2585838 Merge branch 'master' of github.com:peterbraden/node-opencv 2013-03-19 17:18:49 -07:00
Peter Braden 289c519362 add 0.10 to tests 2013-03-19 16:54:54 -07:00
Peter Braden 1d542bc056 Cast cb for node 0.10 2013-03-19 16:53:50 -07:00
Peter Braden 76f3847321 get mat etc 2013-03-15 15:28:58 -07:00
Peter Braden 8e55b380cd add updateSync 2013-03-15 15:07:16 -07:00
Peter Braden 0efbd11d0c Constructors for other algorithms 2013-03-15 14:48:43 -07:00
Peter Braden b8ce5d0def Correct basic case with feedback from jraadt 2013-03-15 13:55:01 -07:00
Peter Braden 053a693c9a Basic version of Face recognition working 2013-03-13 18:08:05 -07:00
Peter Braden 64f933f2a9 WIP on face recognition 2013-03-13 17:42:05 -07:00
Peter Braden b17fceca72 Initial work on face recognition using the FaceRecognizer class from opencv 2.4.4 2013-03-13 16:15:29 -07:00
Peter Braden e5be89c813 Merge pull request #40 from jraadt/master
Fixed pausing a video stream.
2013-03-12 21:43:41 -07:00
Jeremy Raadt fd25b58e43 Fixed an invalid reference to this for pausing a video stream. 2013-03-12 23:34:58 -05:00
Peter Braden ebd1f6e4e8 Merge branch 'waitkey' into beta 2013-03-11 15:41:58 -07:00
Peter Braden e88d2d6b8a Blocking waitKey for development 2013-03-11 15:41:36 -07:00
20 arquivos alterados com 602 adições e 67 exclusões
+3 -2
Ver Arquivo
@@ -1,7 +1,8 @@
language: node_js
node_js:
- 0.6
- 0.8
- "0.6"
- "0.8"
- "0.10"
before_install:
- sudo apt-get update
+18
Ver Arquivo
@@ -0,0 +1,18 @@
# This file describes how to build node-opencv into a runnable linux container with all dependencies installed
# To build:
# 1) Install docker (http://docker.io)
# 2) Build: wget https://raw.github.com/dotcloud/docker/v0.1.6/contrib/docker-build/docker-build && python docker-build $USER/node-opencv < Dockerfile
# 3) Test: docker run $USER/node-opencv node -e "console.log(require('opencv').version)"
#
# VERSION 0.1
# DOCKER-VERSION 0.1.6
from ubuntu:12.04
run echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list
run apt-get update
run apt-get install -q -y libcv-dev
run apt-get install -q -y libopencv-dev
run apt-get install -q -y libhighgui-dev
run apt-get install wget
run wget -O - http://nodejs.org/dist/v0.8.23/node-v0.8.23-linux-x64.tar.gz | tar -C /usr/local/ --strip-components=1 -zxv
run npm install opencv
+5
Ver Arquivo
@@ -185,6 +185,11 @@ doesn't work for you please get in touch.
## Changelog
#### 0.0.13
- V Early support for face recognition - API is _likely_ to change. Have fun!
- *API Change*: VideoCapture.read now calls callback(err, im) instead of callback(im)
#### 0.0.12
- Matrix clone()
- NamedWindow Support
+1
Ver Arquivo
@@ -11,6 +11,7 @@
, "src/VideoCaptureWrap.cc"
, "src/CamShift.cc"
, "src/HighGUI.cc"
, "src/FaceRecognizer.cc"
]
, 'libraries': [
'<!@(pkg-config --libs opencv)'
+1 -1
Ver Arquivo
@@ -5,7 +5,7 @@ var camera = new cv.VideoCapture(0);
setInterval(function() {
camera.read(function(im) {
camera.read(function(err, im) {
im.save('/tmp/cam.png');
});
+29
Ver Arquivo
@@ -0,0 +1,29 @@
var cv = require('../lib/opencv')
var vid = new cv.VideoCapture(0)
var snap = function(){
vid.read(function(im){
im.detectObject(cv.FACE_CASCADE, {}, function(err, faces){
if (!faces){
console.log("No Faces")
return;
}
var face = faces[0]
, ims = im.size()
im.adjustROI(
-face.y
, (face.y + face.height) - ims[0]
, -face.x
, (face.x + face.width) - ims[1])
console.log("!!", im.locateROI());
var im2 = im.clone()
})
});
}
snap()
+1 -1
Ver Arquivo
@@ -130,7 +130,7 @@ videostream.read = function(){
var frame = function(){
self.video.read(function(mat){
self.emit('data', mat)
if (!this.paused){
if (!self.paused){
process.nextTick(frame)
}
+1 -1
Ver Arquivo
@@ -5,7 +5,7 @@
"dependencies": {
"buffers": "0.1.1"
},
"version": "0.0.12",
"version": "0.1.0",
"devDependencies": {
"vows": "*"
},
+19 -38
Ver Arquivo
@@ -1,47 +1,28 @@
var cv = require('../lib/opencv')
var win = new cv.NamedWindow("foo");
cv.readImage('./examples/stuff.png', function(e, im){
im.pyrDown();
win.show(im);
setTimeout(function(){
win.destroy();
}, 1000)
})
var trainingData = []
/*
new cv.VideoCapture(0).read(function(mat){
for (var i = 1; i< 41; i++){
for (var j = 1; j<10; j++){
trainingData.push([i,"/Users/peterbraden/Downloads/orl_faces/s" + i + "/" + j + ".pgm" ])
}
}
mat.resize(200,100)
mat.save('./out.jpg')
cv.readImage("/Users/peterbraden/Downloads/orl_faces/s6/10.pgm", function(e, im){
var facerec = cv.FaceRecognizer.createEigenFaceRecognizer();
//facerec.trainSync(trainingData);
facerec.loadSync("/Users/peterbraden/Desktop/ORL")
console.log(facerec.predictSync(im));
mat.detectObject("./data/haarcascade_frontalface_alt.xml", {min : [30,30]}, function(err, faces){
for (var i=0;i<faces.length; i++){
var x = faces[i]
mat.ellipse(x.x + x.width/2, x.y + x.height/2, x.width/2, x.height/2);
}
console.log(faces.length ? (faces.length + " faces found") : "No faces")
mat.save('./out.jpg');
})
})
cv.readImage("./examples/stuff.png", function(err, im){
var i2 = im.copy()
i2.convertGrayscale()
i2.canny(5, 300)
var features = i2.houghLinesP();
for (var i=0;i<features.length; i++){
var x = features[i]
im.line([x[0], x[1]], [x[2], x[3]]);
im.ellipse(x[0], x[1]);
im.ellipse(x[2], x[3]);
}
console.log(features)
im.save('./out.jpg');
});
*/
cv.readImage("/Users/peterbraden/Desktop/repos/node-opencv/examples/mona.png", function(e, mat){
var th = mat.threshold(200, 200, "Threshold to Zero Inverted");
th.save('out.png')
})
+1 -1
Ver Arquivo
@@ -112,7 +112,7 @@ CascadeClassifierWrap::DetectMultiScale(const v8::Arguments& args){
// 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);
uv_queue_work(uv_default_loop(), &baton->request, AsyncDetectMultiScale, (uv_after_work_cb)AfterAsyncDetectMultiScale);
return Undefined();
+2 -2
Ver Arquivo
@@ -13,7 +13,7 @@ class CascadeClassifierWrap: public node::ObjectWrap {
//static Handle<Value> LoadHaarClassifierCascade(const v8::Arguments&);
static Handle<Value> DetectMultiScale(const v8::Arguments&);
static void EIO_DetectMultiScale(eio_req *req);
static int EIO_AfterDetectMultiScale(eio_req *req);
static void EIO_DetectMultiScale(uv_work_t *req);
static int EIO_AfterDetectMultiScale(uv_work_t *req);
};
+283
Ver Arquivo
@@ -0,0 +1,283 @@
#include "FaceRecognizer.h"
#include "OpenCV.h"
#if CV_MAJOR_VERSION >= 2 && CV_MINOR_VERSION >=4
#include "Matrix.h"
#define EIGEN 0
#define LBPH 1
#define FISHER 2
// Todo, move somewhere useful
cv::Mat fromMatrixOrFilename(Local<Value> v){
cv::Mat im;
if (v->IsString()){
std::string filename = std::string(*v8::String::AsciiValue(v->ToString()));
im = cv::imread(filename);
//std::cout<< im.size();
} else {
Matrix *img = ObjectWrap::Unwrap<Matrix>(v->ToObject());
im = img->mat;
}
return im;
}
void AsyncPredict(uv_work_t *req);
void AfterAsyncPredict(uv_work_t *req);
Persistent<FunctionTemplate> FaceRecognizerWrap::constructor;
void
FaceRecognizerWrap::Init(Handle<Object> target) {
HandleScope scope;
// Constructor
constructor = Persistent<FunctionTemplate>::New(FunctionTemplate::New(FaceRecognizerWrap::New));
constructor->InstanceTemplate()->SetInternalFieldCount(1);
constructor->SetClassName(String::NewSymbol("FaceRecognizer"));
NODE_SET_METHOD(constructor, "createLBPHFaceRecognizer", CreateLBPH);
NODE_SET_METHOD(constructor, "createEigenFaceRecognizer", CreateEigen);
NODE_SET_METHOD(constructor, "createFisherFaceRecognizer", CreateFisher);
NODE_SET_PROTOTYPE_METHOD(constructor, "trainSync", TrainSync);
NODE_SET_PROTOTYPE_METHOD(constructor, "updateSync", UpdateSync);
NODE_SET_PROTOTYPE_METHOD(constructor, "predictSync", PredictSync);
NODE_SET_PROTOTYPE_METHOD(constructor, "saveSync", SaveSync);
NODE_SET_PROTOTYPE_METHOD(constructor, "loadSync", LoadSync);
NODE_SET_PROTOTYPE_METHOD(constructor, "getMat", GetMat);
target->Set(String::NewSymbol("FaceRecognizer"), constructor->GetFunction());
};
Handle<Value>
FaceRecognizerWrap::New(const Arguments &args) {
HandleScope scope;
if (args.This()->InternalFieldCount() == 0)
JSTHROW_TYPE("Cannot Instantiate without new")
// By default initialize LBPH
cv::Ptr<cv::FaceRecognizer> f = cv::createLBPHFaceRecognizer(1, 8, 8, 8, 80.0);
FaceRecognizerWrap *pt = new FaceRecognizerWrap(f, LBPH);
pt->Wrap(args.This());
return args.This();
}
Handle<Value>
FaceRecognizerWrap::CreateLBPH(const Arguments &args) {
HandleScope scope;
int radius = 1;
int neighbors = 8;
int grid_x = 8;
int grid_y = 8;
double threshold = 80;
INT_FROM_ARGS(radius, 0)
INT_FROM_ARGS(neighbors, 1)
INT_FROM_ARGS(grid_x, 2)
INT_FROM_ARGS(grid_y, 3)
DOUBLE_FROM_ARGS(threshold, 4)
Local<Object> n = FaceRecognizerWrap::constructor->GetFunction()->NewInstance();
cv::Ptr<cv::FaceRecognizer> f = cv::createLBPHFaceRecognizer(
radius, neighbors, grid_x, grid_y, threshold
);
FaceRecognizerWrap *pt = new FaceRecognizerWrap(f, LBPH);
pt->Wrap(n);
return n;
}
Handle<Value>
FaceRecognizerWrap::CreateEigen(const Arguments &args) {
HandleScope scope;
int components = 0;
double threshold = DBL_MAX;
INT_FROM_ARGS(components, 0)
DOUBLE_FROM_ARGS(threshold, 1)
Local<Object> n = FaceRecognizerWrap::constructor->GetFunction()->NewInstance();
cv::Ptr<cv::FaceRecognizer> f = cv::createEigenFaceRecognizer(
components, threshold
);
FaceRecognizerWrap *pt = new FaceRecognizerWrap(f, EIGEN);
pt->Wrap(n);
return n;
}
Handle<Value>
FaceRecognizerWrap::CreateFisher(const Arguments &args) {
HandleScope scope;
int components = 0;
double threshold = DBL_MAX;
INT_FROM_ARGS(components, 0)
DOUBLE_FROM_ARGS(threshold, 1)
Local<Object> n = FaceRecognizerWrap::constructor->GetFunction()->NewInstance();
cv::Ptr<cv::FaceRecognizer> f = cv::createFisherFaceRecognizer(
components, threshold
);
FaceRecognizerWrap *pt = new FaceRecognizerWrap(f, FISHER);
pt->Wrap(n);
return n;
}
FaceRecognizerWrap::FaceRecognizerWrap(cv::Ptr<cv::FaceRecognizer> f, int type){
rec = f;
typ = type;
}
Handle<Value> UnwrapTrainingData(const Arguments& args, cv::vector<cv::Mat>* images, cv::vector<int>* labels){
if (args.Length() < 1 || !args[0]->IsArray()){
JSTHROW("FaceRecognizer.train takes a list of [<int> label, image] tuples")
}
// Iterate through [[label, image], ...] etc, and add matrix / label to vectors
const Local<Array> tuples = v8::Array::Cast(*args[0]);
const uint32_t length = tuples->Length();
for (uint32_t i=0 ; i<length ; ++i){
const Local<Value> val = tuples->Get(i);
if (!val->IsArray()){
JSTHROW("train takes a list of [label, image] tuples")
}
Local<Array> valarr = v8::Array::Cast(*val);
if (valarr->Length() != 2 || !valarr->Get(0)->IsInt32()){
JSTHROW("train takes a list of [label, image] tuples")
}
int label = valarr->Get(0)->Uint32Value();
cv::Mat im = fromMatrixOrFilename(valarr->Get(1));
im = im.clone();
cv::cvtColor(im, im, CV_RGB2GRAY);
labels->push_back(label);
images->push_back(im);
}
return v8::Undefined();
}
Handle<Value>
FaceRecognizerWrap::TrainSync(const Arguments& args){
SETUP_FUNCTION(FaceRecognizerWrap)
cv::vector<cv::Mat> images;
cv::vector<int> labels;
Handle<Value> exception = UnwrapTrainingData(args, &images, &labels);
if (!exception->IsUndefined()){
return exception;
}
self->rec->train(images, labels);
return scope.Close(v8::Undefined());
}
Handle<Value>
FaceRecognizerWrap::UpdateSync(const Arguments& args){
SETUP_FUNCTION(FaceRecognizerWrap)
if (self->typ == EIGEN){
JSTHROW("Eigen Recognizer does not support update")
}
if (self->typ == FISHER){
JSTHROW("Fisher Recognizer does not support update")
}
cv::vector<cv::Mat> images;
cv::vector<int> labels;
Handle<Value> exception = UnwrapTrainingData(args, &images, &labels);
if (!exception->IsUndefined()){
return exception;
}
self->rec->update(images, labels);
return scope.Close(v8::Undefined());
}
Handle<Value>
FaceRecognizerWrap::PredictSync(const Arguments& args){
SETUP_FUNCTION(FaceRecognizerWrap)
cv::Mat im = fromMatrixOrFilename(args[0]);//TODO CHECK!
cv::cvtColor(im, im, CV_RGB2GRAY);
// int predictedLabel = self->rec->predict(im);
int predictedLabel = -1;
double confidence = 0.0;
self->rec->predict(im, predictedLabel, confidence);
v8::Local<v8::Object> res = v8::Object::New();
res->Set(v8::String::New("id"), v8::Number::New(predictedLabel));
res->Set(v8::String::New("confidence"), v8::Number::New(confidence));
return scope.Close(res);
}
Handle<Value>
FaceRecognizerWrap::SaveSync(const Arguments& args){
SETUP_FUNCTION(FaceRecognizerWrap)
if (!args[0]->IsString()){
JSTHROW("Save takes a filename")
}
std::string filename = std::string(*v8::String::AsciiValue(args[0]->ToString()));
self->rec->save(filename);
return v8::Undefined();
}
Handle<Value>
FaceRecognizerWrap::LoadSync(const Arguments& args){
SETUP_FUNCTION(FaceRecognizerWrap)
if (!args[0]->IsString()){
JSTHROW("Load takes a filename")
}
std::string filename = std::string(*v8::String::AsciiValue(args[0]->ToString()));
self->rec->load(filename);
return v8::Undefined();
}
Handle<Value>
FaceRecognizerWrap::GetMat(const Arguments& args){
SETUP_FUNCTION(FaceRecognizerWrap)
if (!args[0]->IsString()){
JSTHROW("getMat takes a key")
}
std::string key = std::string(*v8::String::AsciiValue(args[0]->ToString()));
cv::Mat m = self->rec->getMat(key);
Local<Object> im = Matrix::constructor->GetFunction()->NewInstance();
Matrix *img = ObjectWrap::Unwrap<Matrix>(im);
img->mat = m;
return im;
}
#endif // End version > 2.4
+41
Ver Arquivo
@@ -0,0 +1,41 @@
#include "OpenCV.h"
#if CV_MAJOR_VERSION >= 2 && CV_MINOR_VERSION >=4
#include "opencv2/contrib/contrib.hpp"
class FaceRecognizerWrap: public node::ObjectWrap {
public:
cv::Ptr<cv::FaceRecognizer> rec;
int typ;
static Persistent<FunctionTemplate> constructor;
static void Init(Handle<Object> target);
static Handle<Value> New(const Arguments &args);
FaceRecognizerWrap(cv::Ptr<cv::FaceRecognizer> f, int type);
JSFUNC(CreateLBPH)
JSFUNC(CreateEigen)
JSFUNC(CreateFisher)
JSFUNC(TrainSync)
//JSFUNC(Train)
JSFUNC(UpdateSync)
//JSFUNC(Update)
JSFUNC(PredictSync)
// JSFUNC(Predict)
//static void EIO_Predict(eio_req *req);
//static int EIO_AfterPredict(eio_req *req);
JSFUNC(SaveSync)
JSFUNC(LoadSync)
JSFUNC(GetMat)
};
#endif
+14
Ver Arquivo
@@ -19,6 +19,7 @@ NamedWindow::Init(Handle<Object> target) {
NODE_SET_PROTOTYPE_METHOD(constructor, "show", Show);
NODE_SET_PROTOTYPE_METHOD(constructor, "destroy", Destroy);
NODE_SET_PROTOTYPE_METHOD(constructor, "blockingWaitKey", BlockingWaitKey);
target->Set(String::NewSymbol("NamedWindow"), constructor->GetFunction());
};
@@ -65,3 +66,16 @@ NamedWindow::Destroy(const v8::Arguments& args){
cv::destroyWindow(self->winname);
return scope.Close(args.Holder());
}
Handle<Value>
NamedWindow::BlockingWaitKey(const v8::Arguments& args){
HandleScope scope;
//SETUP_FUNCTION(NamedWindow)
int time = 0;
if (args.Length() > 0){
time = args[1]->IntegerValue();
}
int res = cv::waitKey(time);
return scope.Close(Number::New(res));
}
+1
Ver Arquivo
@@ -15,5 +15,6 @@ class NamedWindow: public node::ObjectWrap {
JSFUNC(Show);
JSFUNC(Destroy);
JSFUNC(BlockingWaitKey);
};
+152 -13
Ver Arquivo
@@ -44,6 +44,7 @@ Matrix::Init(Handle<Object> target) {
NODE_SET_PROTOTYPE_METHOD(constructor, "rectangle", Rectangle);
NODE_SET_PROTOTYPE_METHOD(constructor, "line", Line);
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, "pyrDown", PyrDown);
NODE_SET_PROTOTYPE_METHOD(constructor, "pyrUp", PyrUp);
@@ -68,6 +69,10 @@ Matrix::Init(Handle<Object> target) {
NODE_SET_PROTOTYPE_METHOD(constructor, "houghLinesP", HoughLinesP);
NODE_SET_PROTOTYPE_METHOD(constructor, "inRange", inRange);
NODE_SET_PROTOTYPE_METHOD(constructor, "adjustROI", AdjustROI);
NODE_SET_PROTOTYPE_METHOD(constructor, "locateROI", LocateROI);
NODE_SET_PROTOTYPE_METHOD(constructor, "threshold", Threshold);
NODE_SET_METHOD(constructor, "Eye", Eye);
@@ -348,9 +353,6 @@ struct matrixToBuffer_baton_t {
Matrix *mm;
Persistent<Function> cb;
std::vector<uchar> res;
int resSize;
int sleep_for;
uv_work_t request;
};
@@ -367,9 +369,8 @@ Matrix::ToBufferAsync(const v8::Arguments& args){
baton->mm = self;
baton->cb = Persistent<Function>::New(cb);
baton->request.data = baton;
baton->sleep_for = 1;
uv_queue_work(uv_default_loop(), &baton->request, AsyncToBufferAsync, AfterAsyncToBufferAsync);
uv_queue_work(uv_default_loop(), &baton->request, AsyncToBufferAsync, (uv_after_work_cb)AfterAsyncToBufferAsync);
return Undefined();
}
@@ -516,16 +517,83 @@ Matrix::Line(const Arguments& args) {
}
Handle<Value>
Matrix::Save(const v8::Arguments& args){
HandleScope scope;
Matrix::Save(const v8::Arguments& args) {
SETUP_FUNCTION(Matrix)
if (!args[0]->IsString())
return v8::ThrowException(v8::Exception::TypeError(String::New("filename required")));
if (args.Length() > 1) {
return SaveAsync(args);
}
if (!args[0]->IsString())
return v8::ThrowException(v8::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));
String::AsciiValue filename(args[0]);
int res = cv::imwrite(*filename, self->mat);
return scope.Close(Number::New(res));
}
struct save_baton_t {
Matrix *mm;
Persistent<Function> cb;
std::string filename;
int res;
uv_work_t request;
};
void DoSaveAsync(uv_work_t *req);
void AfterSaveAsync(uv_work_t *req);
Handle<Value>
Matrix::SaveAsync(const v8::Arguments& args){
SETUP_FUNCTION(Matrix)
if (!args[0]->IsString())
return v8::ThrowException(v8::Exception::TypeError(String::New("filename required")));
String::AsciiValue filename(args[0]);
REQ_FUN_ARG(1, cb);
save_baton_t *baton = new save_baton_t();
baton->mm = self;
baton->cb = Persistent<Function>::New(cb);
baton->filename = *filename;
baton->request.data = baton;
uv_queue_work(uv_default_loop(), &baton->request, DoSaveAsync, (uv_after_work_cb)AfterSaveAsync);
return Undefined();
}
void DoSaveAsync(uv_work_t *req) {
save_baton_t *baton = static_cast<save_baton_t *>(req->data);
int res = cv::imwrite(baton->filename.c_str(), baton->mm->mat);
baton->res = res;
}
void AfterSaveAsync(uv_work_t *req) {
HandleScope scope;
save_baton_t *baton = static_cast<save_baton_t *>(req->data);
Local<Value> argv[2]; // (err, result)
argv[0] = Local<Value>::New(Null());
argv[1] = Number::New(baton->res);
TryCatch try_catch;
baton->cb->Call(Context::GetCurrent()->Global(), 2, argv);
if (try_catch.HasCaught()) {
FatalException(try_catch);
}
baton->cb.Dispose();
delete baton;
}
@@ -901,3 +969,74 @@ Matrix::inRange(const v8::Arguments& args) {
return scope.Close(v8::Null());
}
Handle<Value>
Matrix::AdjustROI(const v8::Arguments& args) {
SETUP_FUNCTION(Matrix)
int dtop = args[0]->Uint32Value();
int dbottom = args[1]->Uint32Value();
int dleft = args[2]->Uint32Value();
int dright = args[3]->Uint32Value();
self->mat.adjustROI(dtop, dbottom, dleft, dright);
return scope.Close(v8::Null());
}
Handle<Value>
Matrix::LocateROI(const v8::Arguments& args) {
SETUP_FUNCTION(Matrix)
cv::Size wholeSize;
cv::Point ofs;
self->mat.locateROI(wholeSize, ofs);
v8::Local<v8::Array> arr = v8::Array::New(4);
arr->Set(0, Number::New(wholeSize.width));
arr->Set(1, Number::New(wholeSize.height));
arr->Set(2, Number::New(ofs.x));
arr->Set(3, Number::New(ofs.y));
return scope.Close(arr);
}
Handle<Value>
Matrix::Threshold(const v8::Arguments& args) {
SETUP_FUNCTION(Matrix)
double threshold = args[0]->NumberValue();
double maxVal = args[1]->NumberValue();
int typ = cv::THRESH_BINARY;
if (args.Length() == 3){
// typ = args[2]->IntegerValue();
String::AsciiValue typstr(args[2]);
if (strcmp(*typstr, "Binary") == 0){
typ=0;
}
if (strcmp(*typstr, "Binary Inverted") == 0){
typ=1;
}
if (strcmp(*typstr, "Threshold Truncated") == 0){
typ=2;
}
if (strcmp(*typstr, "Threshold to Zero") == 0){
typ=3;
}
if (strcmp(*typstr, "Threshold to Zero Inverted") == 0){
typ=4;
}
}
Local<Object> img_to_return = Matrix::constructor->GetFunction()->NewInstance();
Matrix *img = ObjectWrap::Unwrap<Matrix>(img_to_return);
self->mat.copyTo(img->mat);
cv::threshold(self->mat, img->mat, threshold, maxVal, typ);
return scope.Close(img_to_return);
}
+6 -3
Ver Arquivo
@@ -36,8 +36,9 @@ class Matrix: public node::ObjectWrap {
JSFUNC(Empty)
JSFUNC(Save)
JSFUNC(ToBuffer)
JSFUNC(SaveAsync)
JSFUNC(ToBuffer)
JSFUNC(ToBufferAsync)
JSFUNC(Resize)
@@ -65,6 +66,10 @@ class Matrix: public node::ObjectWrap {
JSFUNC(inRange)
JSFUNC(LocateROI)
JSFUNC(AdjustROI)
JSFUNC(Threshold)
/*
static Handle<Value> Val(const Arguments& args);
static Handle<Value> RowRange(const Arguments& args);
@@ -86,8 +91,6 @@ class Matrix: public node::ObjectWrap {
// create, increment, release
static Handle<Value> PushBack(const Arguments& args);
static Handle<Value> PopBack(const Arguments& args);
static Handle<Value> LocateROI(const Arguments& args);
static Handle<Value> AdjustROI(const Arguments& args);
static Handle<Value> Total(const Arguments& args);
static Handle<Value> IsContinous(const Arguments& args);
static Handle<Value> Type(const Arguments& args);
+13
Ver Arquivo
@@ -30,6 +30,19 @@ using namespace node;
#define JSTHROW_TYPE(ERR) \
return v8::ThrowException(v8::Exception::TypeError(v8::String::New(ERR)));
#define JSTHROW(ERR) \
return v8::ThrowException(v8::Exception::Error(v8::String::New(ERR)));
#define INT_FROM_ARGS(NAME, IND) \
if (args[IND]->IsInt32()){ \
NAME = args[IND]->Uint32Value(); \
}
#define DOUBLE_FROM_ARGS(NAME, IND) \
if (args[IND]->IsInt32()){ \
NAME = args[IND]->NumberValue(); \
}
class OpenCV: public node::ObjectWrap{
public:
+5 -4
Ver Arquivo
@@ -92,7 +92,7 @@ VideoCaptureWrap::Read(const Arguments &args) {
baton->im = new Matrix();
baton->request.data = baton;
uv_queue_work(uv_default_loop(), &baton->request, AsyncRead, AfterAsyncRead);
uv_queue_work(uv_default_loop(), &baton->request, AsyncRead, (uv_after_work_cb)AfterAsyncRead);
return Undefined();
}
@@ -116,11 +116,12 @@ void AfterAsyncRead(uv_work_t *req) {
mat = baton->im->mat;
img->mat = mat;
Local<Value> argv[1];
Local<Value> argv[2];
argv[0] = im_to_return;
argv[0] = Local<Value>::New(Null());
argv[1] = im_to_return;
baton->cb->Call(Context::GetCurrent()->Global(), 1, argv);
baton->cb->Call(Context::GetCurrent()->Global(), 2, argv);
baton->cb.Dispose();
delete baton;
+6 -1
Ver Arquivo
@@ -6,6 +6,7 @@
#include "Contours.h"
#include "CamShift.h"
#include "HighGUI.h"
#include "FaceRecognizer.h"
extern "C" void
@@ -18,8 +19,12 @@ init(Handle<Object> target) {
VideoCaptureWrap::Init(target);
Contour::Init(target);
TrackedObject::Init(target);
NamedWindow::Init(target);
#if CV_MAJOR_VERSION >= 2 && CV_MINOR_VERSION >=4
FaceRecognizerWrap::Init(target);
#endif
};
NODE_MODULE(opencv, init)