Comparar commits
1 Commits
| Autor | SHA1 | Data | |
|---|---|---|---|
| 1322e58bd9 |
+2
-3
@@ -1,8 +1,7 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- "0.6"
|
||||
- "0.8"
|
||||
- "0.10"
|
||||
- 0.6
|
||||
- 0.8
|
||||
|
||||
before_install:
|
||||
- sudo apt-get update
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
# 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
|
||||
@@ -185,11 +185,6 @@ 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
-1
@@ -9,9 +9,9 @@
|
||||
, "src/Contours.cc"
|
||||
, "src/Point.cc"
|
||||
, "src/VideoCaptureWrap.cc"
|
||||
, "src/VideoWriter.cc"
|
||||
, "src/CamShift.cc"
|
||||
, "src/HighGUI.cc"
|
||||
, "src/FaceRecognizer.cc"
|
||||
]
|
||||
, 'libraries': [
|
||||
'<!@(pkg-config --libs opencv)'
|
||||
|
||||
@@ -5,7 +5,7 @@ var camera = new cv.VideoCapture(0);
|
||||
|
||||
setInterval(function() {
|
||||
|
||||
camera.read(function(err, im) {
|
||||
camera.read(function(im) {
|
||||
|
||||
im.save('/tmp/cam.png');
|
||||
});
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
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()
|
||||
+8
-4
@@ -129,10 +129,14 @@ videostream.read = function(){
|
||||
|
||||
var frame = function(){
|
||||
self.video.read(function(mat){
|
||||
self.emit('data', mat)
|
||||
if (!self.paused){
|
||||
process.nextTick(frame)
|
||||
}
|
||||
if (mat.width() && mat.height()){
|
||||
self.emit('data', mat)
|
||||
if (!this.paused){
|
||||
process.nextTick(frame)
|
||||
}
|
||||
} else {
|
||||
self.emit('end')
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
"dependencies": {
|
||||
"buffers": "0.1.1"
|
||||
},
|
||||
"version": "0.1.0",
|
||||
"version": "0.0.12",
|
||||
"devDependencies": {
|
||||
"vows": "*"
|
||||
},
|
||||
|
||||
+38
-19
@@ -1,28 +1,47 @@
|
||||
var cv = require('../lib/opencv')
|
||||
|
||||
var trainingData = []
|
||||
var win = new cv.NamedWindow("foo");
|
||||
cv.readImage('./examples/stuff.png', function(e, im){
|
||||
im.pyrDown();
|
||||
win.show(im);
|
||||
setTimeout(function(){
|
||||
win.destroy();
|
||||
}, 1000)
|
||||
})
|
||||
|
||||
|
||||
|
||||
/*
|
||||
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" ])
|
||||
}
|
||||
}
|
||||
new cv.VideoCapture(0).read(function(mat){
|
||||
|
||||
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.resize(200,100)
|
||||
mat.save('./out.jpg')
|
||||
|
||||
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')
|
||||
|
||||
})
|
||||
|
||||
|
||||
@@ -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, (uv_after_work_cb)AfterAsyncDetectMultiScale);
|
||||
uv_queue_work(uv_default_loop(), &baton->request, AsyncDetectMultiScale, AfterAsyncDetectMultiScale);
|
||||
|
||||
return Undefined();
|
||||
|
||||
|
||||
@@ -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(uv_work_t *req);
|
||||
static int EIO_AfterDetectMultiScale(uv_work_t *req);
|
||||
static void EIO_DetectMultiScale(eio_req *req);
|
||||
static int EIO_AfterDetectMultiScale(eio_req *req);
|
||||
|
||||
};
|
||||
|
||||
@@ -1,283 +0,0 @@
|
||||
#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
|
||||
@@ -1,41 +0,0 @@
|
||||
#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
|
||||
@@ -19,7 +19,6 @@ 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());
|
||||
};
|
||||
|
||||
@@ -66,16 +65,3 @@ 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));
|
||||
}
|
||||
|
||||
@@ -15,6 +15,5 @@ class NamedWindow: public node::ObjectWrap {
|
||||
|
||||
JSFUNC(Show);
|
||||
JSFUNC(Destroy);
|
||||
JSFUNC(BlockingWaitKey);
|
||||
|
||||
};
|
||||
|
||||
+13
-152
@@ -44,7 +44,6 @@ 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);
|
||||
@@ -69,10 +68,6 @@ 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);
|
||||
|
||||
@@ -353,6 +348,9 @@ struct matrixToBuffer_baton_t {
|
||||
Matrix *mm;
|
||||
Persistent<Function> cb;
|
||||
std::vector<uchar> res;
|
||||
int resSize;
|
||||
int sleep_for;
|
||||
|
||||
uv_work_t request;
|
||||
};
|
||||
|
||||
@@ -369,8 +367,9 @@ 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, (uv_after_work_cb)AfterAsyncToBufferAsync);
|
||||
uv_queue_work(uv_default_loop(), &baton->request, AsyncToBufferAsync, AfterAsyncToBufferAsync);
|
||||
|
||||
return Undefined();
|
||||
}
|
||||
@@ -517,83 +516,16 @@ Matrix::Line(const Arguments& args) {
|
||||
}
|
||||
|
||||
Handle<Value>
|
||||
Matrix::Save(const v8::Arguments& args) {
|
||||
SETUP_FUNCTION(Matrix)
|
||||
Matrix::Save(const v8::Arguments& args){
|
||||
HandleScope scope;
|
||||
|
||||
if (args.Length() > 1) {
|
||||
return SaveAsync(args);
|
||||
}
|
||||
|
||||
if (!args[0]->IsString())
|
||||
return v8::ThrowException(v8::Exception::TypeError(String::New("filename required")));
|
||||
if (!args[0]->IsString())
|
||||
return v8::ThrowException(v8::Exception::TypeError(String::New("filename required")));
|
||||
|
||||
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;
|
||||
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));
|
||||
}
|
||||
|
||||
|
||||
@@ -969,74 +901,3 @@ 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);
|
||||
}
|
||||
|
||||
+3
-6
@@ -36,9 +36,8 @@ class Matrix: public node::ObjectWrap {
|
||||
JSFUNC(Empty)
|
||||
|
||||
JSFUNC(Save)
|
||||
JSFUNC(SaveAsync)
|
||||
|
||||
JSFUNC(ToBuffer)
|
||||
|
||||
JSFUNC(ToBufferAsync)
|
||||
|
||||
JSFUNC(Resize)
|
||||
@@ -66,10 +65,6 @@ 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);
|
||||
@@ -91,6 +86,8 @@ 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);
|
||||
|
||||
@@ -30,19 +30,6 @@ 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:
|
||||
|
||||
@@ -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, (uv_after_work_cb)AfterAsyncRead);
|
||||
uv_queue_work(uv_default_loop(), &baton->request, AsyncRead, AfterAsyncRead);
|
||||
return Undefined();
|
||||
|
||||
}
|
||||
@@ -116,12 +116,11 @@ void AfterAsyncRead(uv_work_t *req) {
|
||||
mat = baton->im->mat;
|
||||
|
||||
img->mat = mat;
|
||||
Local<Value> argv[2];
|
||||
Local<Value> argv[1];
|
||||
|
||||
argv[0] = Local<Value>::New(Null());
|
||||
argv[1] = im_to_return;
|
||||
argv[0] = im_to_return;
|
||||
|
||||
baton->cb->Call(Context::GetCurrent()->Global(), 2, argv);
|
||||
baton->cb->Call(Context::GetCurrent()->Global(), 1, argv);
|
||||
baton->cb.Dispose();
|
||||
|
||||
delete baton;
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
#include "VideoWriter.h"
|
||||
#include "Matrix.h"
|
||||
#include "OpenCV.h"
|
||||
|
||||
v8::Persistent<FunctionTemplate> VideoWriterWrap::constructor;
|
||||
|
||||
void
|
||||
VideoWriterWrap::Init(Handle<Object> target) {
|
||||
HandleScope scope;
|
||||
|
||||
// Constructor
|
||||
constructor = Persistent<FunctionTemplate>::New(
|
||||
FunctionTemplate::New(VideoWriterWrap::New));
|
||||
constructor->InstanceTemplate()->SetInternalFieldCount(1);
|
||||
constructor->SetClassName(String::NewSymbol("VideoWriter"));
|
||||
|
||||
// Prototype
|
||||
//Local<ObjectTemplate> proto = constructor->PrototypeTemplate();
|
||||
|
||||
NODE_SET_PROTOTYPE_METHOD(constructor, "write", Write);
|
||||
|
||||
target->Set(String::NewSymbol("VideoWriter"), constructor->GetFunction());
|
||||
};
|
||||
|
||||
|
||||
|
||||
Handle<Value>
|
||||
VideoWriterWrap::New(const Arguments &args) {
|
||||
HandleScope scope;
|
||||
|
||||
if (args.This()->InternalFieldCount() == 0)
|
||||
return v8::ThrowException(
|
||||
v8::Exception::TypeError(v8::String::New("Cannot Instantiate without new")));
|
||||
|
||||
VideoWriterWrap *v;
|
||||
std::string filename;
|
||||
int codec = CV_FOURCC('M','J','P','G'); // Default mjpg
|
||||
double fps = 24.0;
|
||||
cv::Size framesize = cv::Size(640, 320);
|
||||
//bool isColor; // TODO
|
||||
|
||||
filename = std::string(*v8::String::AsciiValue(args[0]->ToString()));
|
||||
|
||||
|
||||
|
||||
v = new VideoWriterWrap(filename, codec, fps, framesize);
|
||||
v->Wrap(args.This());
|
||||
|
||||
return args.This();
|
||||
}
|
||||
|
||||
|
||||
|
||||
VideoWriterWrap::VideoWriterWrap(const std::string& filename, int codec,
|
||||
double fps, cv::Size framesize){
|
||||
|
||||
writer = cv::VideoWriter(filename, codec, fps, framesize);
|
||||
|
||||
|
||||
if (!writer.isOpened()){
|
||||
std::cout << "VideoWriter: Could not be opened!"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Handle<Value>
|
||||
VideoWriterWrap::Write(const Arguments &args) {
|
||||
SETUP_FUNCTION(VideoWriterWrap)
|
||||
|
||||
Matrix *im = ObjectWrap::Unwrap<Matrix>(args[0]->ToObject());
|
||||
|
||||
self->writer << im->mat;
|
||||
|
||||
return scope.Close(v8::Undefined());
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
#include "OpenCV.h"
|
||||
|
||||
class VideoWriterWrap: public node::ObjectWrap {
|
||||
public:
|
||||
cv::VideoWriter writer;
|
||||
|
||||
static Persistent<FunctionTemplate> constructor;
|
||||
static void Init(Handle<Object> target);
|
||||
static Handle<Value> New(const Arguments &args);
|
||||
|
||||
VideoWriterWrap(const std::string& filename, int codec,
|
||||
double fps, cv::Size framesize);
|
||||
|
||||
static Handle<Value> Write(const v8::Arguments&);
|
||||
};
|
||||
+3
-6
@@ -3,10 +3,10 @@
|
||||
#include "Matrix.h"
|
||||
#include "CascadeClassifierWrap.h"
|
||||
#include "VideoCaptureWrap.h"
|
||||
#include "VideoWriter.h"
|
||||
#include "Contours.h"
|
||||
#include "CamShift.h"
|
||||
#include "HighGUI.h"
|
||||
#include "FaceRecognizer.h"
|
||||
|
||||
|
||||
extern "C" void
|
||||
@@ -17,14 +17,11 @@ init(Handle<Object> target) {
|
||||
Matrix::Init(target);
|
||||
CascadeClassifierWrap::Init(target);
|
||||
VideoCaptureWrap::Init(target);
|
||||
VideoWriterWrap::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)
|
||||
|
||||
Referência em uma Nova Issue
Bloquear um usuário