mirror of
https://github.com/peterbraden/node-opencv.git
synced 2025-12-08 19:45:55 +00:00
WIP
This commit is contained in:
parent
1acbe4bcaa
commit
2f3d3cea6e
37
TODO
37
TODO
@ -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
48
examples/face-proxy.js
Normal 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)
|
||||
|
||||
@ -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
|
||||
|
||||
*/
|
||||
21
src/Image.cc
21
src/Image.cc
@ -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);
|
||||
|
||||
|
||||
@ -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&);
|
||||
|
||||
@ -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));
|
||||
}
|
||||
|
||||
|
||||
50
src/Matrix.h
50
src/Matrix.h
@ -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);
|
||||
|
||||
|
||||
|
||||
@ -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){
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user