Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extend binding functionality #155

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion binding.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,14 @@
, "src/CamShift.cc"
, "src/HighGUI.cc"
, "src/FaceRecognizer.cc"
, "src/BackgroundSubtractor.cc"
, "src/Algorithm.cc"
, "src/KeyPoint.cc"
, "src/DMatch.cc"
, "src/DescriptorExtractor.cc"
, "src/DescriptorMatcher.cc"
, "src/FeatureDetector.cc"
, "src/Feature2D.cc"

]
, 'libraries': [
'<!@(pkg-config --libs opencv)'
Expand Down
42 changes: 42 additions & 0 deletions lib/opencv.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ The matrix is one of opencv's most core datatypes.

*/

module.exports.MatrixSerializer = MatrixSerializer;

var matrix = cv.Matrix.prototype;

Expand All @@ -41,6 +42,40 @@ matrix.inspect = function(){

}


function MatrixSerializer(){
}

MatrixSerializer.prototype.serialize = function (instance){
var size = instance.size();
var xSize = size[0];
var ySize = size[1];
var result = xSize + ' ' + ySize + ' ' + instance.type;
for (var y=0; y<ySize; y++){
for (var x=0; x<xSize; x++){
result += ' ' + instance.get(x,y);
}
}
return result;
}

MatrixSerializer.prototype.deserialize = function (data){
var array = data.split(' ');
var xSize = array[0];
var ySize = array[1];
var type = array[2];
var matrix = new cv.Matrix(xSize, ySize, type);

var i = 3;
for (var y=0; y<ySize; y++){
for (var x=0; x<xSize; x++){
matrix.set(x, y, array[i]);
i++;
}
}
return matrix;
}

cv.ImageDataStream = function(){
this.data = Buffers([])
this.writable = true
Expand Down Expand Up @@ -69,6 +104,13 @@ imagedatastream.end = function(b){
}


cv.KeyPoint.prototype.inspect = function(){
return "[KeyPoint " + this.x + "," + this.y + "]";
}

cv.DMatch.prototype.inspect = function(){
return "[DMatch: " + this.distance + " (dist. A#" + this.queryIdx + " - B#" + this.trainIdx + ")]";
}

cv.ImageStream = function(){
this.writable = true
Expand Down
170 changes: 170 additions & 0 deletions src/Algorithm.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
#include "Algorithm.h"
#include "Matrix.h"
#include "KeyPoint.h"

v8::Persistent<FunctionTemplate> Algorithm::constructor;

void
Algorithm::Init(Handle<Object> target) {
HandleScope scope;

// Constructor
constructor = Persistent<FunctionTemplate>::New(FunctionTemplate::New(Algorithm::New));
constructor->InstanceTemplate()->SetInternalFieldCount(1);
constructor->SetClassName(String::NewSymbol("Algorithm"));

NODE_SET_PROTOTYPE_METHOD(constructor, "get", Get);
NODE_SET_PROTOTYPE_METHOD(constructor, "set", Set);

target->Set(String::NewSymbol("Algorithm"), constructor->GetFunction());
};

Handle<Value>
Algorithm::New(const Arguments &args) {
HandleScope scope;

if (args.This()->InternalFieldCount() == 0)
return v8::ThrowException(v8::Exception::TypeError(v8::String::New("Cannot Instantiate without new")));

Algorithm *algorithm;

if (args[0]->IsString()){
algorithm = new Algorithm(std::string(*v8::String::AsciiValue(args[0]->ToString())));
} else {
return v8::ThrowException(v8::Exception::TypeError(v8::String::New("New gets one string parameter")));
}

algorithm->Wrap(args.This());

return args.This();
}

Local<Object>
Algorithm::NewInstance(){
HandleScope scope;

Local<Value> args[] = {};
Local<Object> instance = constructor->GetFunction()->NewInstance(0, args);
return scope.Close(instance);
}


Algorithm::Algorithm(){
}

Algorithm::Algorithm(const std::string& type) {
HandleScope scope;
_algorithm = cv::Algorithm::create<Algorithm>(type);
}

Handle<Value>
Algorithm::Get(const Arguments &args) {
HandleScope scope;

if (args.Length() != 1){
return v8::ThrowException(v8::Exception::TypeError(v8::String::New("You must provide a param name.")));
}

Local<Value> paramName = args[0];
std::string name = std::string(*v8::String::AsciiValue(paramName->ToString()));
Algorithm *self = ObjectWrap::Unwrap<Algorithm>(args.This());

int paramType = self->_algorithm->paramType(name);
switch(paramType){
case cv::Param::INT:
return scope.Close(Number::New(self->_algorithm->getInt(name)));

case cv::Param::BOOLEAN:
return scope.Close(Boolean::New(self->_algorithm->getBool(name)));

case cv::Param::REAL:
return scope.Close(Number::New(self->_algorithm->getDouble(name)));

case cv::Param::STRING:
return scope.Close(String::New(self->_algorithm->getString(name).c_str()));

case cv::Param::MAT: {
Local<Object> matrixObject = Matrix::constructor->GetFunction()->NewInstance();
Matrix *matrix = ObjectWrap::Unwrap<Matrix>(matrixObject);
matrix->mat = self->_algorithm->getMat(name);
return scope.Close(matrixObject);
}

case cv::Param::MAT_VECTOR: {
cv::vector<cv::Mat> mats = self->_algorithm->getMatVector(name);
Local<Array> array = Array::New(mats.size());
for (unsigned long i=0; i<mats.size(); i++){
cv::Mat mat = mats[i];
Local<Object> matrixItemObject = Matrix::constructor->GetFunction()->NewInstance();
Matrix *matrixItem = ObjectWrap::Unwrap<Matrix>(matrixItemObject);
matrixItem->mat = mat;
array->Set(i, matrixItemObject);
}
return scope.Close(array);
}

case cv::Param::ALGORITHM: {
Local<Object> algorithmObject = Algorithm::NewInstance();
Algorithm *algorithm = ObjectWrap::Unwrap<Algorithm>(algorithmObject);
algorithm->_algorithm = self->_algorithm->getAlgorithm(name);
return scope.Close(algorithmObject);
}
}

return scope.Close(v8::Null());
}

Handle<Value>
Algorithm::Set(const Arguments &args) {
HandleScope scope;

if (args.Length() != 2){
return v8::ThrowException(v8::Exception::TypeError(v8::String::New("Only 2 parameters are supported param name and param value.")));
}

Local<Value> paramName = args[0];
Local<Value> paramValue = args[1];

if (!paramName->IsString()){
return v8::ThrowException(v8::Exception::TypeError(v8::String::New("The param name must be stringand param value.")));
}

std::string name = std::string(*v8::String::AsciiValue(paramName->ToString()));
Algorithm *self = ObjectWrap::Unwrap<Algorithm>(args.This());

if (paramValue->IsInt32()){
self->_algorithm->setInt(name, paramValue->IntegerValue());
} else if (paramValue->IsNumber()){
self->_algorithm->setDouble(name, paramValue->NumberValue());
} else if (paramValue->IsBoolean()){
self->_algorithm->setBool(name, paramValue->BooleanValue());
} else if (paramValue->IsString()){
self->_algorithm->setString(name, std::string(*v8::String::AsciiValue(paramValue->ToString())));
} else if (paramValue->IsObject()){
Matrix *matrix = ObjectWrap::Unwrap<Matrix>(paramValue->ToObject());
Algorithm *algorithm = ObjectWrap::Unwrap<Algorithm>(paramValue->ToObject());
Array *array = ObjectWrap::Unwrap<Array>(paramValue->ToObject());
if (matrix != NULL) {
self->_algorithm->setMat(name, matrix->mat);
} else if (algorithm != NULL) {
self->_algorithm->setAlgorithm(name, algorithm->_algorithm);
} else if (array != NULL){
unsigned int length = array->Get(v8::String::New("length"))->ToObject()->Uint32Value();
cv::vector<cv::Mat> mats;
for (unsigned int i=0; i<length; i++){
Matrix *item = ObjectWrap::Unwrap<Matrix>(array->Get(i)->ToObject());
if (item == NULL){
return v8::ThrowException(v8::Exception::TypeError(v8::String::New("Unsupported param type, only Matrix is a supported item in array.")));
}
mats.push_back(item->mat);
}
self->_algorithm->setMatVector(name, mats);
} else {
return v8::ThrowException(v8::Exception::TypeError(v8::String::New("Unsupported param type")));
}
} else {
return v8::ThrowException(v8::Exception::TypeError(v8::String::New("Unsupported param type")));
}

return scope.Close(v8::Null());
}
19 changes: 19 additions & 0 deletions src/Algorithm.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#include "OpenCV.h"

class Algorithm: public node::ObjectWrap {
public:
cv::Ptr<cv::Algorithm> _algorithm;

static Persistent<FunctionTemplate> constructor;
static void Init(Handle<Object> target);
static Handle<Value> New(const Arguments &args);
static Local<Object> NewInstance();

Algorithm(const std::string& type);

JSFUNC(Set)
JSFUNC(Get)

protected:
Algorithm();
};
2 changes: 1 addition & 1 deletion src/Contours.cc
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Contour::Init(Handle<Object> target) {
NODE_SET_PROTOTYPE_METHOD(constructor, "approxPolyDP", ApproxPolyDP);
NODE_SET_PROTOTYPE_METHOD(constructor, "convexHull", ConvexHull);
NODE_SET_PROTOTYPE_METHOD(constructor, "boundingRect", BoundingRect);
NODE_SET_PROTOTYPE_METHOD(constructor, "minAreaRect", MinAreaRect);
NODE_SET_PROTOTYPE_METHOD(constructor, "minAreaRect", BoundingRect);
NODE_SET_PROTOTYPE_METHOD(constructor, "isConvex", IsConvex);
NODE_SET_PROTOTYPE_METHOD(constructor, "moments", Moments);
target->Set(String::NewSymbol("Contours"), m->GetFunction());
Expand Down
94 changes: 94 additions & 0 deletions src/DMatch.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#include "DMatch.h"

v8::Persistent<FunctionTemplate> DMatch::constructor;

void
DMatch::Init(Handle<Object> target) {
HandleScope scope;

// Constructor
constructor = Persistent<FunctionTemplate>::New(FunctionTemplate::New(DMatch::New));
constructor->InstanceTemplate()->SetInternalFieldCount(1);
constructor->SetClassName(String::NewSymbol("DMatch"));

// Prototype
Local<ObjectTemplate> proto = constructor->PrototypeTemplate();
proto->SetAccessor(String::NewSymbol("queryIdx"), GetQueryIdx, RaiseImmutable);
proto->SetAccessor(String::NewSymbol("trainIdx"), GetTrainIdx, RaiseImmutable);
proto->SetAccessor(String::NewSymbol("imgIdx"), GetImgIdx, RaiseImmutable);
proto->SetAccessor(String::NewSymbol("distance"), GetDistance, RaiseImmutable);

target->Set(String::NewSymbol("DMatch"), constructor->GetFunction());
};

Handle<Value>
DMatch::New(const Arguments &args) {
HandleScope scope;

if (args.This()->InternalFieldCount() == 0)
return v8::ThrowException(v8::Exception::TypeError(v8::String::New("Cannot Instantiate without new")));

int queryIdx = -1, trainIdx = -1, imgIdx = -1;
double distance = -1;
if (args[0]->IsNumber()) queryIdx = args[0]->NumberValue();
if (args[1]->IsNumber()) trainIdx = args[1]->NumberValue();
if (args[2]->IsNumber()) imgIdx = args[2]->NumberValue();
if (args[3]->IsNumber()) distance = args[3]->NumberValue();

DMatch *dMatch = new DMatch(queryIdx, trainIdx, imgIdx, distance);
dMatch->Wrap(args.This());
return args.This();
}

Local<Object>
DMatch::NewInstance(int queryIdx, int trainIdx, int imgIdx, float distance){
HandleScope scope;

Local<Value> args[4] = {
Number::New(queryIdx),
Number::New(trainIdx),
Number::New(imgIdx),
Number::New(distance)
};

Local<Object> instance = constructor->GetFunction()->NewInstance(4, args);
return scope.Close(instance);
}

Handle<Value>
DMatch::GetQueryIdx(Local<String> prop, const AccessorInfo &info) {
HandleScope scope;
DMatch *dMatch = ObjectWrap::Unwrap<DMatch>(info.This());
return scope.Close(Number::New(dMatch->_dMatch.queryIdx));
}

Handle<Value>
DMatch::GetTrainIdx(Local<String> prop, const AccessorInfo &info) {
HandleScope scope;
DMatch *dMatch = ObjectWrap::Unwrap<DMatch>(info.This());
return scope.Close(Number::New(dMatch->_dMatch.trainIdx));
}

Handle<Value>
DMatch::GetImgIdx(Local<String> prop, const AccessorInfo &info) {
HandleScope scope;
DMatch *dMatch = ObjectWrap::Unwrap<DMatch>(info.This());
return scope.Close(Number::New(dMatch->_dMatch.imgIdx));
}

Handle<Value>
DMatch::GetDistance(Local<String> prop, const AccessorInfo &info) {
HandleScope scope;
DMatch *dMatch = ObjectWrap::Unwrap<DMatch>(info.This());
return scope.Close(Number::New(dMatch->_dMatch.distance));
}

void
DMatch::RaiseImmutable(Local<String> property, Local<Value> value, const AccessorInfo& info) {
v8::ThrowException(v8::Exception::TypeError(v8::String::New("DMatch is immutable")));
}

DMatch::DMatch(int queryIdx, int trainIdx, int imgIdx, float distance): ObjectWrap() {
_dMatch = cv::DMatch(queryIdx, trainIdx, imgIdx, distance);
}

19 changes: 19 additions & 0 deletions src/DMatch.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#include "OpenCV.h"

class DMatch: public node::ObjectWrap {
public:
cv::DMatch _dMatch;

static Persistent<FunctionTemplate> constructor;
static void Init(Handle<Object> target);
static Handle<Value> New(const Arguments &args);
static Local<Object> NewInstance(int queryIdx, int trainIdx, int imgIdx, float distance);
DMatch(int queryIdx, int trainIdx, int imgIdx, float distance);

static Handle<Value> GetQueryIdx(Local<String> prop, const AccessorInfo &info);
static Handle<Value> GetTrainIdx(Local<String> prop, const AccessorInfo &info);
static Handle<Value> GetImgIdx(Local<String> prop, const AccessorInfo &info);
static Handle<Value> GetDistance(Local<String> prop, const AccessorInfo &info);
static void RaiseImmutable(Local<String> property, Local<Value> value, const AccessorInfo& info);

};
Loading