Merge pull request #202 from arkcore/features2d

Dirty draft of using features2d for calculating
This commit is contained in:
Peter Braden 2015-04-01 08:15:29 +02:00
commit e65202575a
7 changed files with 173 additions and 30 deletions

View File

@ -1,6 +1,8 @@
{
"targets": [{
"target_name": "opencv",
"sources": [
"src/init.cc",
"src/Matrix.cc",
@ -12,6 +14,7 @@
"src/CamShift.cc",
"src/HighGUI.cc",
"src/FaceRecognizer.cc",
"src/Features2d.cc",
"src/BackgroundSubtractor.cc",
"src/Constants.cc",
"src/Calib3D.cc",

17
examples/dissimilarity.js Normal file
View File

@ -0,0 +1,17 @@
var cv = require('../lib/opencv');
cv.readImage("./examples/files/car1.jpg", function(err, car1) {
if (err) throw err;
cv.readImage("./examples/files/car2.jpg", function(err, car2) {
if (err) throw err;
cv.ImageSimilarity(car1, car2, function (err, dissimilarity) {
if (err) throw err;
console.log('Dissimilarity: ', dissimilarity);
});
});
});

22
package.json Executable file → Normal file
View File

@ -3,18 +3,20 @@
"description": "Node Bindings to OpenCV",
"author": "Peter Braden <peterbraden@peterbraden.co.uk>",
"dependencies": {
"node-pre-gyp": "0.5.31",
"buffers": "0.1.1",
"nan": "1.4.3"
"nan": "^1.7.0",
"node-pre-gyp": "^0.6.4"
},
"version": "3.0.1",
"devDependencies": {
"tape": "^3.0.0",
"aws-sdk": "~2.0.21",
"glob": "^4.0.6",
"request": "^2.45.0"
"aws-sdk": "~2.1.20",
"glob": "^5.0.3",
"request": "^2.44.0"
},
"bundledDependencies":["node-pre-gyp"],
"bundledDependencies": [
"node-pre-gyp"
],
"license": "MIT",
"scripts": {
"build": "node-gyp build",
@ -36,10 +38,10 @@
"node": ">=0.10"
},
"binary": {
"module_name" : "opencv",
"module_path" : "./build/{module_name}/v{version}/{configuration}/{node_abi}-{platform}-{arch}/",
"remote_path" : "./{module_name}/v{version}/{configuration}/",
"module_name": "opencv",
"module_path": "./build/{module_name}/v{version}/{configuration}/{node_abi}-{platform}-{arch}/",
"remote_path": "./{module_name}/v{version}/{configuration}/",
"package_name": "{node_abi}-{platform}-{arch}.tar.gz",
"host" : "https://node-opencv.s3.amazonaws.com"
"host": "https://node-opencv.s3.amazonaws.com"
}
}

View File

@ -71,6 +71,7 @@ class AsyncDetectMultiScale : public NanAsyncWorker {
NanScope();
// this->matrix->Unref();
Handle<Value> argv[2];
v8::Local<v8::Array> arr = NanNew<v8::Array>(this->res.size());
for(unsigned int i = 0; i < this->res.size(); i++ ){
@ -82,11 +83,8 @@ class AsyncDetectMultiScale : public NanAsyncWorker {
arr->Set(i, x);
}
//argv[1] = arr;
Local<Value> argv[] = {
NanNull()
, arr
};
argv[0] = NanNull();
argv[1] = arr;
TryCatch try_catch;
callback->Call(2, argv);

105
src/Features2d.cc Normal file
View File

@ -0,0 +1,105 @@
#include "Features2d.h"
#include "Matrix.h"
#include <nan.h>
#include <stdio.h>
#if CV_MAJOR_VERSION >= 2 && CV_MINOR_VERSION >=4
void
Features::Init(Handle<Object> target) {
NanScope();
NODE_SET_METHOD(target, "ImageSimilarity", Similarity);
};
class AsyncDetectSimilarity : public NanAsyncWorker {
public:
AsyncDetectSimilarity(NanCallback *callback, cv::Mat image1, cv::Mat image2) : NanAsyncWorker(callback), image1(image1), image2(image2), dissimilarity(0) {}
~AsyncDetectSimilarity() {}
void Execute () {
cv::Ptr<cv::FeatureDetector> detector = cv::FeatureDetector::create("ORB");
cv::Ptr<cv::DescriptorExtractor> extractor = cv::DescriptorExtractor::create("ORB");
cv::Ptr<cv::DescriptorMatcher> matcher = cv::DescriptorMatcher::create("BruteForce-Hamming");
std::vector<cv::DMatch> matches;
cv::Mat descriptors1 = cv::Mat();
cv::Mat descriptors2 = cv::Mat();
std::vector<cv::KeyPoint> keypoints1;
std::vector<cv::KeyPoint> keypoints2;
detector->detect(image1, keypoints1);
detector->detect(image2, keypoints2);
extractor->compute(image1, keypoints1, descriptors1);
extractor->compute(image2, keypoints2, descriptors2);
matcher->match(descriptors1, descriptors2, matches);
double max_dist = 0;
double min_dist = 100;
//-- Quick calculation of max and min distances between keypoints
for (int i = 0; i < descriptors1.rows; i++) {
double dist = matches[i].distance;
if( dist < min_dist ) min_dist = dist;
if( dist > max_dist ) max_dist = dist;
}
//-- Draw only "good" matches (i.e. whose distance is less than 2*min_dist,
//-- or a small arbitary value ( 0.02 ) in the event that min_dist is very
//-- small)
//-- PS.- radiusMatch can also be used here.
std::vector<cv::DMatch> good_matches;
double good_matches_sum = 0.0;
for (int i = 0; i < descriptors1.rows; i++ ) {
double distance = matches[i].distance;
if (distance <= std::max(2*min_dist, 0.02)) {
good_matches.push_back(matches[i]);
good_matches_sum += distance;
}
}
dissimilarity = (double)good_matches_sum / (double)good_matches.size();
}
void HandleOKCallback () {
NanScope();
Handle<Value> argv[2];
argv[0] = NanNull();
argv[1] = NanNew<Number>(dissimilarity);
callback->Call(2, argv);
}
private:
cv::Mat image1;
cv::Mat image2;
double dissimilarity;
};
NAN_METHOD(Features::Similarity) {
NanScope();
REQ_FUN_ARG(2, cb);
cv::Mat image1 = ObjectWrap::Unwrap<Matrix>(args[0]->ToObject())->mat;
cv::Mat image2 = ObjectWrap::Unwrap<Matrix>(args[1]->ToObject())->mat;
NanCallback *callback = new NanCallback(cb.As<Function>());
NanAsyncQueueWorker( new AsyncDetectSimilarity(callback, image1, image2) );
NanReturnUndefined();
};
#endif

16
src/Features2d.h Normal file
View File

@ -0,0 +1,16 @@
#include "OpenCV.h"
#if CV_MAJOR_VERSION >= 2 && CV_MINOR_VERSION >=4
#include <opencv2/core/core.hpp>
#include <opencv2/features2d/features2d.hpp>
class Features: public node::ObjectWrap {
public:
static Persistent<FunctionTemplate> constructor;
static void Init(Handle<Object> target);
static NAN_METHOD(Similarity);
};
#endif

View File

@ -8,6 +8,7 @@
#include "CamShift.h"
#include "HighGUI.h"
#include "FaceRecognizer.h"
#include "Features2d.h"
#include "Constants.h"
#include "Calib3D.h"
#include "ImgProc.h"
@ -34,6 +35,7 @@ init(Handle<Object> target) {
#if CV_MAJOR_VERSION >= 2 && CV_MINOR_VERSION >=4
Features::Init(target);
FaceRecognizerWrap::Init(target);
#endif