Added videocapture working (libuv), some examples, more methods to Matrix and implement of libuv for detectobjects

This commit is contained in:
Tomas Alvarez 2012-06-18 12:01:28 -03:00
parent b73174c00f
commit a0308135cb
14 changed files with 331 additions and 0 deletions

6
build.sh Executable file
View File

@ -0,0 +1,6 @@
#!/bin/bash
node-waf configure build &&
cd examples &&
#node face_detection.js
node $1

61
doc Executable file
View File

@ -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.

16
examples/addweighted.js Executable file
View File

@ -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");
});
});

13
examples/camera.js Executable file
View File

@ -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);

36
examples/contours.js Executable file
View File

@ -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');
});

18
examples/convert_image.js Executable file
View File

@ -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");
});

18
examples/face_detection.js Executable file
View File

@ -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');
});
});

BIN
examples/mona.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 518 KiB

BIN
examples/over_text.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

27
examples/salt.js Executable file
View File

@ -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);
}
}
}

BIN
examples/stuff.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 KiB

73
src/Contours.cc Executable file
View File

@ -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]))));
}

18
src/Contours.h Executable file
View File

@ -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&);
};

45
todo Executable file
View File

@ -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/