This commit is contained in:
Peter Braden 2012-01-23 19:04:33 -08:00
parent 1acbe4bcaa
commit 2f3d3cea6e
8 changed files with 267 additions and 44 deletions

37
TODO
View File

@ -1,17 +1,32 @@
[X] In C++ get Image to inherit Matrix, to mirror js inherit
- Don't think it's possible :(
Get rid of Image
- Replace with operations on Matrix and cv helper js functions
- CascadeClassifier::DetectMultiScale
- pass in properties
- Make async
- Matrix doesn't need to be eventemitter:
instead create a cv.MatrixBuffer class that is an event emitter, and wraps matrix in js
== Image ==
- make image from stream
- make image from node file object
############ Ideas #####################
- Image::Ellipse
- pass in color
- pass in thickness
var mat = cv.readImage('foo.jpg');
//shortcut for cascade classifier
mat.detectFaces('data.xml', 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);
}
});
var s = new opencv.ImageStream()
s.on('load', function(mat){
cv.writeImage(mat, filename, function(err){});
})
request.get('foo').pipe(s);

48
examples/face-proxy.js Normal file
View File

@ -0,0 +1,48 @@
/*
Face recognition proxy
*/
var http = require('http')
, request = require('request')
, cv = require('../lib/opencv')
, face_cascade = new cv.CascadeClassifier("./examples/haarcascade_frontalface_alt.xml")
http.createServer(function(req, resp){
var url = req.url.slice(1);
console.log(url);
if (url.indexOf('http') != 0){
return request({uri:'http://google.com'}).pipe(resp)
}
// TODO make sure image
if (url.indexOf(".jpg", url.length - 4) !== -1 ||
url.indexOf(".png", url.length - 4) !== -1){
request({uri:url, encoding:'binary'}, function(err, r, body){
if (err) throw err;
var im = new cv.Image(new Buffer(body, 'binary'));
var faces = face_cascade.detectMultiScale(im, 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);
}
//console.log(faces);
resp.writeHead(200, {'Content-Type': 'image/jpeg'});
resp.end(im.toBuffer());
});
})
} else {
request({uri:url || 'http://google.com'}).pipe(resp)
}
}).listen(1901)

View File

@ -1,7 +1,42 @@
var EventEmitter = require('events').EventEmitter
var opencv = require('./bindings')
, Point = opencv.Point
, Image = opencv.Image
, Matrix = opencv.Matrix
module.exports = opencv;
var oc = exports = module.exports = opencv;
/*
# Matrix #
The matrix is one of opencv's most core datatypes.
*/
opencv.Matrix.prototype.__proto__ = EventEmitter.prototype;
/*
# Image #
OpenCV has got rid of, so maybe we just use Matrix class
and augment in js:
new cv.Image()
does
cv.imageRead() // returns Matrix
and
Matrix.save()
does
cv.imwrite
*/

View File

@ -20,10 +20,6 @@ Image::Init(Handle<Object> target) {
// Prototype
Local<ObjectTemplate> proto = constructor->PrototypeTemplate();
proto->SetAccessor(String::NewSymbol("width"), GetWidth);
proto->SetAccessor(String::NewSymbol("height"), GetHeight);
NODE_SET_PROTOTYPE_METHOD(constructor, "save", Save);
NODE_SET_PROTOTYPE_METHOD(constructor, "ellipse", Ellipse);
NODE_SET_PROTOTYPE_METHOD(constructor, "toBuffer", ToBuffer);
@ -92,19 +88,6 @@ Image::Image(v8::Value* fileName): ObjectWrap() {
Image::~Image() {
}
Handle<Value>
Image::GetWidth(Local<String>, const AccessorInfo &info) {
HandleScope scope;
Image *img = ObjectWrap::Unwrap<Image>(info.This());
return scope.Close(Number::New(img->mat.size().width));
}
Handle<Value>
Image::GetHeight(Local<String>, const AccessorInfo &info) {
HandleScope scope;
Image *img = ObjectWrap::Unwrap<Image>(info.This());
return scope.Close(Number::New(img->mat.size().height));
}
Handle<Value>
@ -127,8 +110,8 @@ Image::ToBuffer(const v8::Arguments& args){
Image *self = ObjectWrap::Unwrap<Image>(args.This());
vector<uchar> vec(0);
vector<int> params(0);//CV_IMWRITE_JPEG_QUALITY 90
std::vector<uchar> vec(0);
std::vector<int> params(0);//CV_IMWRITE_JPEG_QUALITY 90
cv::imencode(".jpg", self->mat, vec, params);

View File

@ -12,8 +12,7 @@ class Image: public node::ObjectWrap {
Image(v8::Value* src);
Image(uint8_t* buf, unsigned len);
static Handle<Value> GetWidth(Local<String> prop, const AccessorInfo &info);
static Handle<Value> GetHeight(Local<String> prop, const AccessorInfo &info);
//static Handle<Value> Convert(const v8::Arguments&);
static Handle<Value> Save(const v8::Arguments&);

View File

@ -15,13 +15,18 @@ Matrix::Init(Handle<Object> target) {
// Constructor
constructor = Persistent<FunctionTemplate>::New(m);
constructor->InstanceTemplate()->SetInternalFieldCount(1);
//constructor->SetClassName(String::NewSymbol("Matrix"));
constructor->SetClassName(String::NewSymbol("Matrix"));
// Prototype
Local<ObjectTemplate> proto = constructor->PrototypeTemplate();
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);
target->Set(String::NewSymbol("Matrix"), m->GetFunction());
};
@ -34,8 +39,13 @@ Matrix::New(const Arguments &args) {
if (args.This()->InternalFieldCount() == 0)
return v8::ThrowException(v8::Exception::TypeError(v8::String::New("Cannot instantiate without new")));
Matrix *mat;
Matrix *mat = new Matrix;
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());
}
@ -44,6 +54,10 @@ Matrix::Matrix(): ObjectWrap() {
mat = cv::Mat();
}
Matrix::Matrix(int w, int h): ObjectWrap() {
mat = cv::Mat(w, h, CV_8UC1);
}
Handle<Value>
Matrix::Empty(const Arguments& args){
HandleScope scope;
@ -51,3 +65,60 @@ Matrix::Empty(const Arguments& args){
Matrix *self = ObjectWrap::Unwrap<Matrix>(args.This());
return scope.Close(Boolean::New(self->mat.empty()));
}
Handle<Value>
Matrix::Get(const Arguments& args){
HandleScope scope;
Matrix *self = ObjectWrap::Unwrap<Matrix>(args.This());
int i = args[0]->IntegerValue();
int j = args[1]->IntegerValue();
return scope.Close(Number::New(self->mat.at<double>(i,j)));
}
Handle<Value>
Matrix::Set(const Arguments& args){
HandleScope scope;
Matrix *self = ObjectWrap::Unwrap<Matrix>(args.This());
int i = args[0]->IntegerValue();
int j = args[1]->IntegerValue();
double val = args[2]->NumberValue();
self->mat.at<double>(i,j) = val;
return scope.Close(Undefined());
}
Handle<Value>
Matrix::Size(const Arguments& args){
HandleScope scope;
Matrix *self = ObjectWrap::Unwrap<Matrix>(args.This());
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);
}
Handle<Value>
Matrix::Width(const Arguments& args){
HandleScope scope;
Matrix *self = ObjectWrap::Unwrap<Matrix>(args.This());
return scope.Close(Number::New(self->mat.size().width));
}
Handle<Value>
Matrix::Height(const Arguments& args){
HandleScope scope;
Matrix *self = ObjectWrap::Unwrap<Matrix>(args.This());
return scope.Close(Number::New(self->mat.size().height));
}

View File

@ -8,8 +8,58 @@ class Matrix: public node::ObjectWrap {
static void Init(Handle<Object> target);
static Handle<Value> New(const Arguments &args);
Matrix();
Matrix(int rows, int cols);
Matrix(int rows, int cols, int typ);
/*
static Handle<Value> Val(const Arguments& args);
static Handle<Value> Row(const Arguments& args);
static Handle<Value> Col(const Arguments& args);
static Handle<Value> RowRange(const Arguments& args);
static Handle<Value> ColRange(const Arguments& args);
static Handle<Value> Diag(const Arguments& args);
static Handle<Value> Clone(const Arguments& args);
static Handle<Value> CopyTo(const Arguments& args);
static Handle<Value> ConvertTo(const Arguments& args);
static Handle<Value> AssignTo(const Arguments& args);
static Handle<Value> SetTo(const Arguments& args);
static Handle<Value> Reshape(const Arguments& args);
static Handle<Value> Transpose(const Arguments& args);
static Handle<Value> Invert(const Arguments& args);
static Handle<Value> Multiply(const Arguments& args);
static Handle<Value> Cross(const Arguments& args);
static Handle<Value> Dot(const Arguments& args);
static Handle<Value> Zeroes(const Arguments& args);
static Handle<Value> Ones(const Arguments& args);
static Handle<Value> Eye(const Arguments& args);
// create, increment, release
static Handle<Value> Resize(const Arguments& args);
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);
static Handle<Value> Depth(const Arguments& args);
static Handle<Value> Channels(const Arguments& args);
static Handle<Value> StepOne(const Arguments& args);
*/
static Handle<Value> Get(const Arguments& args); // at
static Handle<Value> Set(const Arguments& args);
static Handle<Value> Size(const Arguments& args);
static Handle<Value> Width(const Arguments& args);
static Handle<Value> Height(const Arguments& args);
static Handle<Value> Empty(const Arguments& args);

View File

@ -66,15 +66,37 @@ vows.describe('Smoke Tests OpenCV').addBatch({
, "constructor" : function(cv){
assert.ok(cv.Matrix);
assert.ok(new cv.Matrix);
assert.ok(new cv.Matrix(1,2,0));
assert.ok(new cv.Matrix(1,2));
}
, "get/set" : function(cv){
var mat = new cv.Matrix(1,2);
assert.equal(mat.set(0,0,3), undefined);
assert.equal(mat.get(0,0), 3);
}
, ".width" : function(cv){
var mat = new cv.Matrix(6,7);
assert.equal(mat.width(), 7);
}
, ".height" : function(cv){
var mat = new cv.Matrix(6,7);
assert.equal(mat.height(), 6);
}
, ".size" : function(cv){
var mat = new cv.Matrix(6,7);
assert.deepEqual(mat.size(), [6, 7]);
}
, "empty": function(cv){
assert.equal(new cv.Matrix(1,2).empty(), true);
assert.equal(new cv.Matrix().empty(), true);
}
}
, "Image" : {
topic : require('../lib/opencv')
@ -85,8 +107,8 @@ vows.describe('Smoke Tests OpenCV').addBatch({
, "constructor(buffer)" : function(cv){
var im = new cv.Image(fs.readFileSync('./examples/mona.jpg'))
assert.ok(im);
assert.equal(im.width, 500);
assert.equal(im.height, 756)
assert.equal(im.width(), 500);
assert.equal(im.height(), 756)
assert.equal(im.empty(), false)
}
@ -96,8 +118,8 @@ vows.describe('Smoke Tests OpenCV').addBatch({
}
, ".width / .height" : function(cv){
assert.equal(new cv.Image("./examples/mona.jpg").width, 500)
assert.equal(new cv.Image("./examples/mona.jpg").height, 756)
assert.equal(new cv.Image("./examples/mona.jpg").width(), 500)
assert.equal(new cv.Image("./examples/mona.jpg").height(), 756)
}
, ".ellipse": function(cv){