Skip to content
This repository was archived by the owner on Oct 18, 2023. It is now read-only.

Commit 3a0d479

Browse files
Merge pull request justadudewhohacks#404 from findie/feature/bfmatcher
ADD BFMatcher Class with match, matchAsync, knnMatch and knnMatchAsync
2 parents 6867cfe + 9d0c72c commit 3a0d479

File tree

11 files changed

+389
-2
lines changed

11 files changed

+389
-2
lines changed

binding.gyp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@
9191
"cc/modules/features2d/KeyPoint.cc",
9292
"cc/modules/features2d/KeyPointMatch.cc",
9393
"cc/modules/features2d/DescriptorMatch.cc",
94+
"cc/modules/features2d/BFMatcher.cc",
9495
"cc/modules/features2d/FeatureDetector.cc",
9596
"cc/modules/features2d/descriptorMatching.cc",
9697
"cc/modules/features2d/descriptorMatchingKnn.cc",

cc/modules/features2d/BFMatcher.cc

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
#include "BFMatcher.h"
2+
#include "BFMatcherBindings.h"
3+
4+
Nan::Persistent<v8::FunctionTemplate> BFMatcher::constructor;
5+
6+
NAN_MODULE_INIT(BFMatcher::Init) {
7+
v8::Local<v8::FunctionTemplate> ctor = Nan::New<v8::FunctionTemplate>(BFMatcher::New);
8+
v8::Local<v8::ObjectTemplate> instanceTemplate = ctor->InstanceTemplate();
9+
10+
constructor.Reset(ctor);
11+
instanceTemplate->SetInternalFieldCount(1);
12+
13+
ctor->SetClassName(Nan::New("BFMatcher").ToLocalChecked());
14+
15+
Nan::SetAccessor(instanceTemplate, Nan::New("normType").ToLocalChecked(), BFMatcher::GetNormType);
16+
Nan::SetAccessor(instanceTemplate, Nan::New("crossCheck").ToLocalChecked(), BFMatcher::GetCrossCheck);
17+
18+
Nan::SetPrototypeMethod(ctor, "match", match);
19+
Nan::SetPrototypeMethod(ctor, "matchAsync", matchAsync);
20+
Nan::SetPrototypeMethod(ctor, "knnMatch", knnMatch);
21+
Nan::SetPrototypeMethod(ctor, "knnMatchAsync", knnMatchAsync);
22+
23+
target->Set(Nan::New("BFMatcher").ToLocalChecked(), ctor->GetFunction());
24+
};
25+
26+
NAN_METHOD(BFMatcher::New) {
27+
FF_METHOD_CONTEXT("BFMatcher::New");
28+
BFMatcher* self = new BFMatcher();
29+
30+
// optional args
31+
bool hasOptArgsObj = FF_HAS_ARG(0) && info[0]->IsObject();
32+
FF_OBJ optArgs = hasOptArgsObj ? info[0]->ToObject() : FF_NEW_OBJ();
33+
34+
FF_GET_NUMBER_IFDEF(optArgs, self->normType, "normType", cv::NORM_L2);
35+
FF_GET_BOOL_IFDEF(optArgs, self->crossCheck, "crossCheck", false);
36+
37+
if (!hasOptArgsObj) {
38+
FF_ARG_INT_IFDEF(0, self->normType, self->normType);
39+
FF_ARG_BOOL_IFDEF(1, self->crossCheck, self->crossCheck);
40+
}
41+
42+
self->Wrap(info.Holder());
43+
self->bfmatcher = cv::BFMatcher(
44+
self->normType,
45+
self->crossCheck
46+
);
47+
48+
info.GetReturnValue().Set(info.Holder());
49+
}
50+
51+
NAN_METHOD(BFMatcher::match) {
52+
FF::SyncBinding(
53+
std::make_shared<BFMatcherBindings::MatchWorker>(BFMatcher::Converter::unwrap(info.This())),
54+
"BFMatcher::match",
55+
info
56+
);
57+
}
58+
59+
NAN_METHOD(BFMatcher::matchAsync) {
60+
FF::AsyncBinding(
61+
std::make_shared<BFMatcherBindings::MatchWorker>(BFMatcher::Converter::unwrap(info.This())),
62+
"BFMatcher::matchAsync",
63+
info
64+
);
65+
}
66+
67+
NAN_METHOD(BFMatcher::knnMatch) {
68+
FF::SyncBinding(
69+
std::make_shared<BFMatcherBindings::MatchKnnWorker>(BFMatcher::Converter::unwrap(info.This())),
70+
"BFMatcher::knnMatch",
71+
info
72+
);
73+
}
74+
75+
76+
NAN_METHOD(BFMatcher::knnMatchAsync) {
77+
FF::AsyncBinding(
78+
std::make_shared<BFMatcherBindings::MatchKnnWorker>(BFMatcher::Converter::unwrap(info.This())),
79+
"BFMatcher::knnMatchAsync",
80+
info
81+
);
82+
}

cc/modules/features2d/BFMatcher.h

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#include "macros.h"
2+
#include <opencv2/core.hpp>
3+
#include <opencv2/features2d.hpp>
4+
#include "KeyPoint.h"
5+
#include "Mat.h"
6+
#include "CatchCvExceptionWorker.h"
7+
8+
#ifndef __FF_BFMATCHER_H__
9+
#define __FF_BFMATCHER_H__
10+
11+
class BFMatcher : public Nan::ObjectWrap {
12+
public:
13+
cv::BFMatcher bfmatcher;
14+
15+
int normType;
16+
bool crossCheck;
17+
18+
static FF_GETTER(BFMatcher, GetNormType, normType)
19+
static FF_GETTER(BFMatcher, GetCrossCheck, crossCheck)
20+
21+
static Nan::Persistent<v8::FunctionTemplate> constructor;
22+
23+
cv::BFMatcher* getNativeObjectPtr() { return &bfmatcher; }
24+
cv::BFMatcher getNativeObject() { return bfmatcher; }
25+
26+
typedef InstanceConverter<BFMatcher, cv::BFMatcher> Converter;
27+
28+
static NAN_MODULE_INIT(Init);
29+
30+
static NAN_METHOD(New);
31+
static NAN_METHOD(match);
32+
static NAN_METHOD(matchAsync);
33+
static NAN_METHOD(knnMatch);
34+
static NAN_METHOD(knnMatchAsync);
35+
36+
static const char* getClassName() {
37+
return "BFMatcher";
38+
}
39+
};
40+
41+
#endif
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#include "BFMatcher.h"
2+
#include "DescriptorMatch.h"
3+
4+
#ifndef __FF_BFMATCHERBINDINGS_H_
5+
#define __FF_BFMATCHERBINDINGS_H_
6+
7+
namespace BFMatcherBindings {
8+
9+
struct MatchWorker : public CatchCvExceptionWorker {
10+
public:
11+
cv::BFMatcher bfmatcher;
12+
13+
MatchWorker(cv::BFMatcher _bfmatcher) {
14+
this->bfmatcher = _bfmatcher;
15+
}
16+
17+
cv::Mat descFrom;
18+
cv::Mat descTo;
19+
std::vector<cv::DMatch> dmatches;
20+
21+
std::string executeCatchCvExceptionWorker() {
22+
bfmatcher.match(descFrom, descTo, dmatches);
23+
return "";
24+
}
25+
26+
bool unwrapRequiredArgs(Nan::NAN_METHOD_ARGS_TYPE info) {
27+
return Mat::Converter::arg(0, &descFrom, info)
28+
|| Mat::Converter::arg(1, &descTo, info);
29+
}
30+
31+
FF_VAL getReturnValue() {
32+
return ObjectArrayConverter<DescriptorMatch, cv::DMatch>::wrap(dmatches);
33+
}
34+
};
35+
36+
37+
struct MatchKnnWorker : public CatchCvExceptionWorker {
38+
public:
39+
cv::BFMatcher bfmatcher;
40+
41+
MatchKnnWorker(cv::BFMatcher _bfmatcher) {
42+
this->bfmatcher = _bfmatcher;
43+
}
44+
45+
cv::Mat descFrom;
46+
cv::Mat descTo;
47+
int k;
48+
std::vector<std::vector<cv::DMatch>> dmatches;
49+
50+
std::string executeCatchCvExceptionWorker() {
51+
bfmatcher.knnMatch(descFrom, descTo, dmatches, k);
52+
return "";
53+
}
54+
55+
bool unwrapRequiredArgs(Nan::NAN_METHOD_ARGS_TYPE info) {
56+
return Mat::Converter::arg(0, &descFrom, info)
57+
|| Mat::Converter::arg(1, &descTo, info)
58+
|| IntConverter::arg(2, &k, info);
59+
}
60+
61+
FF_VAL getReturnValue() {
62+
return ObjectArrayOfArraysConverter<DescriptorMatch, cv::DMatch>::wrap(dmatches);
63+
}
64+
};
65+
66+
}
67+
68+
#endif

cc/modules/features2d/features2d.cc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include "KeyPoint.h"
33
#include "KeyPointMatch.h"
44
#include "DescriptorMatch.h"
5+
#include "BFMatcher.h"
56
#include "descriptorMatching.h"
67
#include "descriptorMatchingKnn.h"
78
#include "detectors/AGASTDetector.h"
@@ -23,6 +24,7 @@ NAN_MODULE_INIT(Features2d::Init) {
2324
AGASTDetector::Init(target);
2425
AKAZEDetector::Init(target);
2526
BRISKDetector::Init(target);
27+
BFMatcher::Init(target);
2628
FASTDetector::Init(target);
2729
GFTTDetector::Init(target);
2830
KAZEDetector::Init(target);
@@ -102,4 +104,4 @@ NAN_METHOD(Features2d::DrawMatches) {
102104
FF_OBJ jsMat = FF_NEW_INSTANCE(Mat::constructor);
103105
cv::drawMatches(img1, kps1, img2, kps2, dMatches, FF_UNWRAP_MAT_AND_GET(jsMat));
104106
FF_RETURN(jsMat);
105-
}
107+
}

examples/matchFeatures.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,13 @@ const orbMatchesImg = matchFeatures({
5151
});
5252
cv.imshowWait('ORB matches', orbMatchesImg);
5353

54+
// Match using the BFMatcher with crossCheck true
55+
const bf = new cv.BFMatcher(cv.NORM_L2, true);
56+
const orbBFMatchIMG = matchFeatures({
57+
img1,
58+
img2,
59+
detector: new cv.ORBDetector(),
60+
matchFunc: (desc1, desc2) => bf.match(desc1, desc2)
61+
});
62+
cv.imshowWait('ORB with BFMatcher - crossCheck true', orbBFMatchIMG);
63+

lib/index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ export * from './typings/FisherFaceRecognizer.d';
2323
export * from './typings/KeyPointDetector.d';
2424
export * from './typings/FeatureDetector.d';
2525
export * from './typings/AGASTDetector.d';
26+
export * from './typings/BFMatcher.d';
2627
export * from './typings/AKAZEDetector.d';
2728
export * from './typings/BRISKDetector.d';
2829
export * from './typings/DescriptorMatch.d';

lib/typings/BFMatcher.d.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import {Mat} from "./Mat";
2+
import {DescriptorMatch} from "./DescriptorMatch";
3+
4+
export class BFMatcher {
5+
constructor(normType: number, crossCheck?: boolean);
6+
constructor(params: { normType: number, crossCheck?: boolean });
7+
match(descriptors1: Mat, descriptors2: Mat): DescriptorMatch[];
8+
matchAsync(descriptors1: Mat, descriptors2: Mat): Promise<DescriptorMatch[]>;
9+
knnMatch(descriptors1: Mat, descriptors2: Mat, k: number): Array<[DescriptorMatch]|[]>;
10+
knnMatchAsync(descriptors1: Mat, descriptors2: Mat, k: number): Promise<Array<[DescriptorMatch]|[]>>;
11+
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
"gypfile": true,
4040
"dependencies": {
4141
"macro-inferno": "^0.2.1",
42-
"nan": "^2.10.0",
42+
"nan": "^2.11.0",
4343
"native-node-utils": "0.1.2",
4444
"opencv-build": "0.0.14"
4545
},

0 commit comments

Comments
 (0)