Skip to content
70 changes: 41 additions & 29 deletions src/Features2d.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "Matrix.h"
#include <nan.h>
#include <stdio.h>
#include <limits>

void Features::Init(Local<Object> target) {
Nan::HandleScope scope;
Expand Down Expand Up @@ -46,38 +47,47 @@ class AsyncDetectSimilarity: public Nan::AsyncWorker {
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;
//fix for 'Assertion failed...' error
//source: http://stackoverflow.com/questions/15650371/matcher-assertions-failed-error-opencv-android
if (descriptors1.type() == descriptors2.type() && descriptors1.cols == descriptors2.cols) {
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;
//-- 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();
dissimilarity = (double) good_matches_sum / (double) good_matches.size();

}
else {
dissimilarity = std::numeric_limits<double>::quiet_NaN();
}

}

void HandleOKCallback() {
Expand All @@ -86,7 +96,9 @@ class AsyncDetectSimilarity: public Nan::AsyncWorker {
Local<Value> argv[2];

argv[0] = Nan::Null();
argv[1] = Nan::New<Number>(dissimilarity);

if (dissimilarity != dissimilarity) argv[1] = Nan::Null();
else argv[1] = Nan::New<Number>(dissimilarity);

callback->Call(2, argv);
}
Expand Down