Merge github.com:talvarez/node-opencv

Conflicts:
	src/Matrix.cc
	src/Matrix.h
Esse commit está contido em:
Tomas Alvarez
2012-06-19 14:53:52 -03:00
58 arquivos alterados com 844 adições e 181 exclusões
Arquivo normal → Arquivo executável
Ver Arquivo
Arquivo normal → Arquivo executável
Ver Arquivo
Arquivo normal → Arquivo executável
Ver Arquivo
Arquivo normal → Arquivo executável
Ver Arquivo
Arquivo normal → Arquivo executável
Ver Arquivo
Arquivo executável
+6
Ver Arquivo
@@ -0,0 +1,6 @@
#!/bin/bash
node-waf configure build &&
cd examples &&
#node face_detection.js
node $1
Arquivo normal → Arquivo executável
Ver Arquivo
Arquivo normal → Arquivo executável
Ver Arquivo
Arquivo normal → Arquivo executável
Ver Arquivo
Arquivo normal → Arquivo executável
Ver Arquivo
Arquivo normal → Arquivo executável
Ver Arquivo
Arquivo normal → Arquivo executável
Ver Arquivo
Arquivo normal → Arquivo executável
Ver Arquivo
Arquivo normal → Arquivo executável
Ver Arquivo
Arquivo normal → Arquivo executável
Ver Arquivo
Arquivo normal → Arquivo executável
Ver Arquivo
Arquivo normal → Arquivo executável
Ver Arquivo
Arquivo normal → Arquivo executável
Ver Arquivo
Arquivo normal → Arquivo executável
Ver Arquivo
Arquivo normal → Arquivo executável
Ver Arquivo
Arquivo normal → Arquivo executável
Ver Arquivo
Arquivo normal → Arquivo executável
Ver Arquivo
Arquivo normal → Arquivo executável
Ver Arquivo
Arquivo normal → Arquivo executável
Ver Arquivo
Arquivo normal → Arquivo executável
Ver Arquivo
Arquivo executável
+61
Ver Arquivo
@@ -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.
Arquivo executável
+16
Ver Arquivo
@@ -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");
});
});
Arquivo executável
+13
Ver Arquivo
@@ -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);
Arquivo executável
+36
Ver Arquivo
@@ -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');
});
Arquivo executável
+18
Ver Arquivo
@@ -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");
});
Arquivo normal → Arquivo executável
Ver Arquivo
Arquivo executável
+18
Ver Arquivo
@@ -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');
});
});
Arquivo binário não exibido.

Antes

Largura:  |  Altura:  |  Tamanho: 112 KiB

Arquivo executável
BIN
Ver Arquivo
Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 518 KiB

Arquivo executável
BIN
Ver Arquivo
Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 5.4 KiB

Arquivo executável
+27
Ver Arquivo
@@ -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);
}
}
}
Arquivo executável
BIN
Ver Arquivo
Arquivo binário não exibido.

Depois

Largura:  |  Altura:  |  Tamanho: 186 KiB

Arquivo normal → Arquivo executável
Ver Arquivo
Arquivo normal → Arquivo executável
Ver Arquivo
Arquivo normal → Arquivo executável
+1 -1
Ver Arquivo
@@ -1,5 +1,5 @@
var Stream = require('stream').Stream
, Buffers = require('buffers')
, Buffers = require('buffer')
, util = require('util');
var bindings = require('./bindings')
Arquivo normal → Arquivo executável
Ver Arquivo
Arquivo normal → Arquivo executável
+23 -14
Ver Arquivo
@@ -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,10 +106,13 @@ 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();
@@ -113,31 +120,33 @@ CascadeClassifierWrap::DetectMultiScale(const v8::Arguments& args){
}
void
CascadeClassifierWrap::EIO_DetectMultiScale(eio_req *req){
void AsyncDetectMultiScale(uv_work_t *req) {
classifier_baton_t *baton = static_cast<classifier_baton_t *>(req->data);
sleep(baton->sleep_for);
// 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;
}
Arquivo normal → Arquivo executável
Ver Arquivo
Arquivo executável
+73
Ver Arquivo
@@ -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]))));
}
Arquivo executável
+18
Ver Arquivo
@@ -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&);
};
Arquivo normal → Arquivo executável
+260 -6
Ver Arquivo
@@ -1,8 +1,12 @@
#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) {
@@ -37,6 +41,21 @@ Matrix::Init(Handle<Object> target) {
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, "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, "findContours", FindContours);
NODE_SET_PROTOTYPE_METHOD(constructor, "drawContour", DrawContour);
NODE_SET_PROTOTYPE_METHOD(constructor, "drawAllContours", DrawAllContours);
NODE_SET_METHOD(constructor, "Eye", Eye);
@@ -59,18 +78,24 @@ Matrix::New(const Arguments &args) {
} 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());
}
Matrix::Matrix(): ObjectWrap() {
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>
Matrix::Empty(const Arguments& args){
SETUP_FUNCTION(Matrix)
@@ -97,7 +122,17 @@ Matrix::Set(const Arguments& args){
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;
} 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());
}
@@ -137,12 +172,13 @@ Matrix::Row(const Arguments& args){
}
arr->Set(x, Number::New(v));
}
return scope.Close(arr);
}
Handle<Value>
Matrix::PixelRow(const Arguments& args){
Matrix::PixelRow(const Arguments& args){
SETUP_FUNCTION(Matrix)
int width = self->mat.size().width;
@@ -155,7 +191,8 @@ Matrix::PixelRow(const Arguments& args){
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);
}
@@ -218,6 +255,12 @@ Matrix::Height(const Arguments& args){
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>
@@ -242,7 +285,6 @@ Matrix::ToBuffer(const v8::Arguments& args){
}
// ellipse(x, y, wid, height, angle, startangle, endangle, color, thickness, linetype, shift)
Handle<Value>
Matrix::Ellipse(const v8::Arguments& args){
SETUP_FUNCTION(Matrix)
@@ -256,7 +298,7 @@ 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>
@@ -272,6 +314,7 @@ Matrix::Save(const v8::Arguments& args){
return scope.Close(Number::New(res));
}
Handle<Value>
Matrix::Eye(const v8::Arguments& args){
HandleScope scope;
@@ -281,13 +324,224 @@ Matrix::Eye(const v8::Arguments& args){
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::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);
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();
cv::Canny(self->mat, self->mat, lowThresh, highThresh);
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){
Arquivo normal → Arquivo executável
+14
Ver Arquivo
@@ -61,6 +61,7 @@ class Matrix: public node::ObjectWrap {
JSFUNC(Size)
JSFUNC(Width)
JSFUNC(Height)
JSFUNC(Channels)
JSFUNC(ToBuffer)
JSFUNC(Ellipse)
JSFUNC(Empty)
@@ -68,6 +69,19 @@ class Matrix: public node::ObjectWrap {
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)
};
Arquivo normal → Arquivo executável
Ver Arquivo
Arquivo normal → Arquivo executável
+1
Ver Arquivo
@@ -10,6 +10,7 @@
#include <highgui.h>
#include <string.h>
using namespace v8;
using namespace node;
Arquivo normal → Arquivo executável
Ver Arquivo
Arquivo normal → Arquivo executável
Ver Arquivo
Arquivo normal → Arquivo executável
+62 -12
Ver Arquivo
@@ -2,8 +2,22 @@
#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;
@@ -16,7 +30,7 @@ VideoCaptureWrap::Init(Handle<Object> target) {
// 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());
};
@@ -33,15 +47,17 @@ VideoCaptureWrap::New(const Arguments &args) {
if (args[0]->IsNumber()){
v = new VideoCaptureWrap(args[0]->NumberValue());
} else {}
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")));
@@ -50,16 +66,50 @@ VideoCaptureWrap::VideoCaptureWrap(int device){
Handle<Value>
VideoCaptureWrap::GetFrame(const Arguments &args) {
SETUP_FUNCTION(VideoCaptureWrap)
VideoCaptureWrap::Read(const Arguments &args) {
cv::Mat frame;
self->cap.retrieve(frame);
HandleScope scope;
VideoCaptureWrap *v = ObjectWrap::Unwrap<VideoCaptureWrap>(args.This());
Local<Object> im_h = Matrix::constructor->GetFunction()->NewInstance();
Matrix *im = ObjectWrap::Unwrap<Matrix>(im_h);
im->mat = frame;
return scope.Close(im_h);
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;
uv_queue_work(uv_default_loop(), &baton->request, AsyncRead, AfterAsyncRead);
return Undefined();
}
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;
}
Arquivo normal → Arquivo executável
+3 -1
Ver Arquivo
@@ -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&);
};
Arquivo normal → Arquivo executável
+2
Ver Arquivo
@@ -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);
};
Arquivo normal → Arquivo executável
Ver Arquivo
Arquivo executável
+45
Ver Arquivo
@@ -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/
Arquivo normal → Arquivo executável
Ver Arquivo