mirror of
https://github.com/peterbraden/node-opencv.git
synced 2025-12-08 19:45:55 +00:00
Add imageSimilarity method beased on features 2d
This commit is contained in:
parent
d2a918bedc
commit
a7eba6a9e4
@ -1,6 +1,8 @@
|
|||||||
{
|
{
|
||||||
"targets": [{
|
"targets": [{
|
||||||
|
|
||||||
"target_name": "opencv",
|
"target_name": "opencv",
|
||||||
|
|
||||||
"sources": [
|
"sources": [
|
||||||
"src/init.cc",
|
"src/init.cc",
|
||||||
"src/Matrix.cc",
|
"src/Matrix.cc",
|
||||||
@ -12,6 +14,7 @@
|
|||||||
"src/CamShift.cc",
|
"src/CamShift.cc",
|
||||||
"src/HighGUI.cc",
|
"src/HighGUI.cc",
|
||||||
"src/FaceRecognizer.cc",
|
"src/FaceRecognizer.cc",
|
||||||
|
"src/Features2d.cc",
|
||||||
"src/BackgroundSubtractor.cc",
|
"src/BackgroundSubtractor.cc",
|
||||||
"src/Constants.cc",
|
"src/Constants.cc",
|
||||||
"src/Calib3D.cc",
|
"src/Calib3D.cc",
|
||||||
|
|||||||
17
examples/dissimilarity.js
Normal file
17
examples/dissimilarity.js
Normal 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);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
14
package.json
Executable file → Normal file
14
package.json
Executable file → Normal file
@ -3,18 +3,20 @@
|
|||||||
"description": "Node Bindings to OpenCV",
|
"description": "Node Bindings to OpenCV",
|
||||||
"author": "Peter Braden <peterbraden@peterbraden.co.uk>",
|
"author": "Peter Braden <peterbraden@peterbraden.co.uk>",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"node-pre-gyp": "0.5.31",
|
|
||||||
"buffers": "0.1.1",
|
"buffers": "0.1.1",
|
||||||
"nan": "1.4.3"
|
"nan": "^1.7.0",
|
||||||
|
"node-pre-gyp": "^0.6.4"
|
||||||
},
|
},
|
||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"tape": "^3.0.0",
|
"tape": "^3.0.0",
|
||||||
"aws-sdk": "~2.0.21",
|
"aws-sdk": "~2.1.20",
|
||||||
"glob": "^4.0.6",
|
"glob": "^5.0.3",
|
||||||
"request": "^2.45.0"
|
"request": "^2.44.0"
|
||||||
},
|
},
|
||||||
"bundledDependencies":["node-pre-gyp"],
|
"bundledDependencies": [
|
||||||
|
"node-pre-gyp"
|
||||||
|
],
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "node-gyp build",
|
"build": "node-gyp build",
|
||||||
|
|||||||
@ -71,6 +71,7 @@ class AsyncDetectMultiScale : public NanAsyncWorker {
|
|||||||
NanScope();
|
NanScope();
|
||||||
// this->matrix->Unref();
|
// this->matrix->Unref();
|
||||||
|
|
||||||
|
Handle<Value> argv[2];
|
||||||
v8::Local<v8::Array> arr = NanNew<v8::Array>(this->res.size());
|
v8::Local<v8::Array> arr = NanNew<v8::Array>(this->res.size());
|
||||||
|
|
||||||
for(unsigned int i = 0; i < this->res.size(); i++ ){
|
for(unsigned int i = 0; i < this->res.size(); i++ ){
|
||||||
@ -82,11 +83,8 @@ class AsyncDetectMultiScale : public NanAsyncWorker {
|
|||||||
arr->Set(i, x);
|
arr->Set(i, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
//argv[1] = arr;
|
argv[0] = NanNull();
|
||||||
Local<Value> argv[] = {
|
argv[1] = arr;
|
||||||
NanNull()
|
|
||||||
, arr
|
|
||||||
};
|
|
||||||
|
|
||||||
TryCatch try_catch;
|
TryCatch try_catch;
|
||||||
callback->Call(2, argv);
|
callback->Call(2, argv);
|
||||||
|
|||||||
105
src/Features2d.cc
Normal file
105
src/Features2d.cc
Normal 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
16
src/Features2d.h
Normal 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
|
||||||
@ -8,6 +8,7 @@
|
|||||||
#include "CamShift.h"
|
#include "CamShift.h"
|
||||||
#include "HighGUI.h"
|
#include "HighGUI.h"
|
||||||
#include "FaceRecognizer.h"
|
#include "FaceRecognizer.h"
|
||||||
|
#include "Features2d.h"
|
||||||
#include "Constants.h"
|
#include "Constants.h"
|
||||||
#include "Calib3D.h"
|
#include "Calib3D.h"
|
||||||
#include "ImgProc.h"
|
#include "ImgProc.h"
|
||||||
@ -34,6 +35,7 @@ init(Handle<Object> target) {
|
|||||||
|
|
||||||
|
|
||||||
#if CV_MAJOR_VERSION >= 2 && CV_MINOR_VERSION >=4
|
#if CV_MAJOR_VERSION >= 2 && CV_MINOR_VERSION >=4
|
||||||
|
Features::Init(target);
|
||||||
FaceRecognizerWrap::Init(target);
|
FaceRecognizerWrap::Init(target);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user