mirror of
https://github.com/peterbraden/node-opencv.git
synced 2025-12-08 19:45:55 +00:00
Face detection using cascade classifier
This commit is contained in:
parent
468034d329
commit
23d49455fe
19
TODO
19
TODO
@ -1,2 +1,17 @@
|
||||
- src/OpenCV.c
|
||||
- Test to see if bindings are working
|
||||
[X] In C++ get Image to inherit Matrix, to mirror js inherit
|
||||
- Don't think it's possible :(
|
||||
|
||||
|
||||
- CascadeClassifier::DetectMultiScale
|
||||
- pass in properties
|
||||
- Make async
|
||||
|
||||
|
||||
== Image ==
|
||||
|
||||
- make image from stream
|
||||
- make image from node file object
|
||||
|
||||
- Image::Ellipse
|
||||
- pass in color
|
||||
- pass in thickness
|
||||
26161
examples/haarcascade_frontalface_alt.xml
Normal file
26161
examples/haarcascade_frontalface_alt.xml
Normal file
File diff suppressed because it is too large
Load Diff
16
package.json
Normal file
16
package.json
Normal file
@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "opencv"
|
||||
, "description": "Node Bindings to OpenCV"
|
||||
, "author": "Peter Braden <peterbraden@peterbraden.co.uk>"
|
||||
, "dependencies": {
|
||||
}
|
||||
, "version" : "0.0.1"
|
||||
, "devDependencies": {
|
||||
"vows": "*"
|
||||
}
|
||||
, "engine": "node >= 0.4.1"
|
||||
, "scripts": {
|
||||
"preinstall": "node-waf configure build"
|
||||
}
|
||||
, "main": "./lib/opencv",
|
||||
}
|
||||
15
smoketest.js
15
smoketest.js
@ -1,8 +1,15 @@
|
||||
var opencv = require('./lib/opencv')
|
||||
var cv = require('./lib/opencv')
|
||||
, assert = require('assert')
|
||||
|
||||
console.log(opencv.version)
|
||||
console.log(cv.version)
|
||||
|
||||
console.log(new opencv.Matrix().empty())
|
||||
var im = new cv.Image("./examples/mona.jpg")
|
||||
, face_cascade = new cv.CascadeClassifier("./examples/haarcascade_frontalface_alt.xml")
|
||||
|
||||
console.log(new opencv.Image('./examples/mona.jpg').empty())
|
||||
var faces = face_cascade.detectMultiScale(im, 1.1, 2, [30, 30])
|
||||
|
||||
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');
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
#include "OpenCV.h"
|
||||
#include "CascadeClassifierWrap.h"
|
||||
#include "OpenCV.h"
|
||||
#include "Image.h"
|
||||
|
||||
|
||||
v8::Persistent<v8::FunctionTemplate> CascadeClassifierWrap::constructor;
|
||||
Persistent<FunctionTemplate> CascadeClassifierWrap::constructor;
|
||||
|
||||
void
|
||||
CascadeClassifierWrap::Init(Handle<Object> target) {
|
||||
@ -16,6 +16,10 @@ CascadeClassifierWrap::Init(Handle<Object> target) {
|
||||
// Prototype
|
||||
Local<ObjectTemplate> proto = constructor->PrototypeTemplate();
|
||||
|
||||
NODE_SET_PROTOTYPE_METHOD(constructor, "detectMultiScale", DetectMultiScale);
|
||||
|
||||
|
||||
|
||||
target->Set(String::NewSymbol("CascadeClassifier"), constructor->GetFunction());
|
||||
};
|
||||
|
||||
@ -36,6 +40,45 @@ CascadeClassifierWrap::CascadeClassifierWrap(v8::Value* fileName){
|
||||
std::string filename;
|
||||
filename = std::string(*v8::String::AsciiValue(fileName->ToString()));
|
||||
|
||||
cc.load(filename.c_str());
|
||||
|
||||
|
||||
if (!cc.load(filename.c_str())){
|
||||
v8::ThrowException(v8::Exception::TypeError(v8::String::New("Error loading file")));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Handle<Value>
|
||||
CascadeClassifierWrap::DetectMultiScale(const v8::Arguments& args){
|
||||
HandleScope scope;
|
||||
|
||||
CascadeClassifierWrap *self = ObjectWrap::Unwrap<CascadeClassifierWrap>(args.This());
|
||||
Image *im = ObjectWrap::Unwrap<Image>(args[0]->ToObject());
|
||||
std::vector<cv::Rect> objects;
|
||||
|
||||
double scale = 1.1;
|
||||
int neighbors = 2;
|
||||
int minw = 30;
|
||||
int minh = 30;
|
||||
|
||||
cv::Mat gray;
|
||||
|
||||
cvtColor( im->mat, gray, CV_BGR2GRAY );
|
||||
equalizeHist( gray, gray);
|
||||
|
||||
self->cc.detectMultiScale(gray, objects, scale, neighbors, 0, cv::Size(minw, minh));
|
||||
|
||||
v8::Local<v8::Array> arr = v8::Array::New(objects.size());
|
||||
|
||||
for(unsigned int i = 0; i < objects.size(); i++ ){
|
||||
v8::Local<v8::Object> x = v8::Object::New();
|
||||
x->Set(v8::String::New("x"), v8::Number::New(objects[i].x));
|
||||
x->Set(v8::String::New("y"), v8::Number::New(objects[i].y));
|
||||
x->Set(v8::String::New("width"), v8::Number::New(objects[i].width));
|
||||
x->Set(v8::String::New("height"), v8::Number::New(objects[i].height));
|
||||
arr->Set(i, x);
|
||||
}
|
||||
|
||||
return scope.Close(arr);
|
||||
}
|
||||
|
||||
@ -4,7 +4,6 @@ class CascadeClassifierWrap: public node::ObjectWrap {
|
||||
public:
|
||||
cv::CascadeClassifier cc;
|
||||
|
||||
|
||||
static Persistent<FunctionTemplate> constructor;
|
||||
static void Init(Handle<Object> target);
|
||||
static Handle<Value> New(const Arguments &args);
|
||||
@ -12,4 +11,7 @@ class CascadeClassifierWrap: public node::ObjectWrap {
|
||||
CascadeClassifierWrap(v8::Value* fileName);
|
||||
|
||||
//static Handle<Value> LoadHaarClassifierCascade(const v8::Arguments&);
|
||||
}
|
||||
|
||||
static Handle<Value> DetectMultiScale(const v8::Arguments&);
|
||||
|
||||
};
|
||||
22
src/Image.cc
22
src/Image.cc
@ -1,5 +1,4 @@
|
||||
#include "Image.h"
|
||||
#include "OpenCV.h"
|
||||
#include "Matrix.h"
|
||||
|
||||
v8::Persistent<FunctionTemplate> Image::constructor;
|
||||
@ -21,6 +20,7 @@ Image::Init(Handle<Object> target) {
|
||||
proto->SetAccessor(String::NewSymbol("height"), GetHeight);
|
||||
|
||||
NODE_SET_PROTOTYPE_METHOD(constructor, "save", Save);
|
||||
NODE_SET_PROTOTYPE_METHOD(constructor, "ellipse", Ellipse);
|
||||
|
||||
|
||||
/*proto->SetAccessor(String::NewSymbol("source"), GetSource, SetSource);
|
||||
@ -57,8 +57,7 @@ Image::New(const Arguments &args) {
|
||||
|
||||
|
||||
|
||||
Image::Image(int width, int height): ObjectWrap() {
|
||||
|
||||
Image::Image(int width, int height): ObjectWrap() {
|
||||
};
|
||||
|
||||
|
||||
@ -68,6 +67,8 @@ Image::Image(v8::Value* fileName): ObjectWrap() {
|
||||
mat = cv::imread(filename, -1);
|
||||
};
|
||||
|
||||
Image::~Image() {
|
||||
}
|
||||
|
||||
Handle<Value>
|
||||
Image::GetWidth(Local<String>, const AccessorInfo &info) {
|
||||
@ -97,3 +98,18 @@ Image::Save(const v8::Arguments& args){
|
||||
return scope.Close(Number::New(res));
|
||||
}
|
||||
|
||||
|
||||
// ellipse(x, y, wid, height, angle, startangle, endangle, color, thickness, linetype, shift)
|
||||
Handle<Value>
|
||||
Image::Ellipse(const v8::Arguments& args){
|
||||
HandleScope scope;
|
||||
|
||||
Image *self = ObjectWrap::Unwrap<Image>(args.This());
|
||||
int x = args[0]->Uint32Value();
|
||||
int y = args[1]->Uint32Value();
|
||||
int width = args[2]->Uint32Value();
|
||||
int height = args[3]->Uint32Value();
|
||||
|
||||
cv::ellipse(self->mat, cv::Point(x, y), cv::Size(width, height), 0, 0, 360, cv::Scalar( 255, 0, 255 ), 4, 8, 0);
|
||||
return scope.Close(v8::Null());
|
||||
}
|
||||
|
||||
@ -16,6 +16,11 @@ class Image: public node::ObjectWrap {
|
||||
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&);
|
||||
static Handle<Value> Ellipse(const v8::Arguments&);
|
||||
|
||||
|
||||
private:
|
||||
~Image();
|
||||
};
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
#include "Image.h"
|
||||
#include "CascadeClassifierWrap.h"
|
||||
|
||||
|
||||
extern "C" void
|
||||
init(Handle<Object> target) {
|
||||
HandleScope scope;
|
||||
@ -12,4 +13,4 @@ init(Handle<Object> target) {
|
||||
Matrix::Init(target);
|
||||
Image::Init(target);
|
||||
CascadeClassifierWrap::Init(target);
|
||||
}
|
||||
};
|
||||
|
||||
@ -90,5 +90,30 @@ vows.describe('Smoke Tests OpenCV').addBatch({
|
||||
assert.equal(new cv.Image("./examples/mona.jpg").height, 756)
|
||||
}
|
||||
|
||||
, ".ellipse": function(cv){
|
||||
assert.equal(new cv.Image("./examples/mona.jpg").ellipse(10, 10, 10, 10), undefined)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
, "CascadeClassifier": {
|
||||
topic : require('../lib/opencv')
|
||||
|
||||
, "constructor" : function(cv){
|
||||
assert.ok(new cv.CascadeClassifier("./examples/haarcascade_frontalface_alt.xml"))
|
||||
}
|
||||
|
||||
, "face detection": function(cv){
|
||||
var im = new cv.Image("./examples/mona.jpg")
|
||||
, face_cascade = new cv.CascadeClassifier("./examples/haarcascade_frontalface_alt.xml")
|
||||
, faces = face_cascade.detectMultiScale(im, 1.1, 2, [30, 30])
|
||||
|
||||
assert.equal(faces.length, 1)
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}).run();
|
||||
Loading…
x
Reference in New Issue
Block a user