-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdescriptor_matching.cpp
More file actions
130 lines (104 loc) · 5.2 KB
/
descriptor_matching.cpp
File metadata and controls
130 lines (104 loc) · 5.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#include <iostream>
#include <numeric>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/features2d.hpp>
#include <opencv2/xfeatures2d.hpp>
#include <opencv2/xfeatures2d/nonfree.hpp>
#include "structIO.hpp"
using namespace std;
void matchDescriptors(cv::Mat &imgSource, cv::Mat &imgRef, vector<cv::KeyPoint> &kPtsSource, vector<cv::KeyPoint> &kPtsRef, cv::Mat &descSource, cv::Mat &descRef,
vector<cv::DMatch> &matches, string descriptorType, string matcherType, string selectorType)
{
// configure matcher
bool crossCheck = true;
cv::Ptr<cv::DescriptorMatcher> matcher;
if (matcherType.compare("MAT_BF") == 0)
{
if (descSource.type() != CV_32F)
{ // OpenCV bug workaround : convert binary descriptors to floating point due to a bug in current OpenCV implementation
descSource.convertTo(descSource, CV_32S);
descRef.convertTo(descRef, CV_32S);
}
int normType = descriptorType.compare("DES_BINARY") == 0 ? cv::NORM_HAMMING : cv::NORM_L2;
cout <<"here is norm type " << normType << endl;
matcher = cv::BFMatcher::create(normType, crossCheck);
cout << "BF matching cross-check=" << crossCheck;
}
else if (matcherType.compare("MAT_FLANN") == 0)
{
if (descSource.type() != CV_32F)
{ // OpenCV bug workaround : convert binary descriptors to floating point due to a bug in current OpenCV implementation
descSource.convertTo(descSource, CV_32F);
descRef.convertTo(descRef, CV_32F);
}
//... TODO : implement FLANN matching
matcher = cv::DescriptorMatcher::create(cv::DescriptorMatcher::FLANNBASED);
cout << "FLANN matching";
}
// perform matching task
if (selectorType.compare("SEL_NN") == 0)
{ // nearest neighbor (best match)
double t = (double)cv::getTickCount();
matcher->match(descSource, descRef, matches); // Finds the best match for each descriptor in desc1
t = ((double)cv::getTickCount() - t) / cv::getTickFrequency();
cout << " (NN) with n=" << matches.size() << " matches in " << 1000 * t / 1.0 << " ms" << endl;
}
else if (selectorType.compare("SEL_KNN") == 0)
{ // k nearest neighbors (k=2)
// TODO : implement k-nearest-neighbor matching
vector<vector<cv::DMatch>> knn_matches;
double t = (double)cv::getTickCount();
matcher->knnMatch(descSource, descRef, knn_matches, 2); // finds the 2 best matches
t = ((double)cv::getTickCount() - t) / cv::getTickFrequency();
cout << " (KNN) with n=" << knn_matches.size() << " matches in " << 1000 * t / 1.0 << " ms" << endl;
// filter matches using descriptor distance ratio test
// TODO : filter matches using descriptor distance ratio test
double minDescDistRatio = 0.8;
for (auto it = knn_matches.begin(); it != knn_matches.end(); ++it)
{
if ((*it)[0].distance < minDescDistRatio * (*it)[1].distance)
{
matches.push_back((*it)[0]);
}
}
cout << "# keypoints removed = " << knn_matches.size() - matches.size() << endl;
}
// visualize results
cv::Mat matchImg = imgRef.clone();
cv::drawMatches(imgSource, kPtsSource, imgRef, kPtsRef, matches,
matchImg, cv::Scalar::all(-1), cv::Scalar::all(-1), vector<char>(), cv::DrawMatchesFlags::DRAW_RICH_KEYPOINTS);
string windowName = "Matching keypoints between two camera images (best 50)";
cv::namedWindow(windowName, 7);
cv::imshow(windowName, matchImg);
cv::waitKey(0);
}
int main()
{
cv::Mat imgSource = cv::imread("../images/img1gray.png");
cv::Mat imgRef = cv::imread("../images/img2gray.png");
// vector<cv::KeyPoint> kptsSource, kptsRef;
// readKeypoints("../dat/C35A5_KptsSource_BRISK_small.dat", kptsSource);
// readKeypoints("../dat/C35A5_KptsRef_BRISK_small.dat", kptsRef);
// cv::Mat descSource, descRef;
// readDescriptors("../dat/C35A5_DescSource_BRISK_small.dat", descSource);
// readDescriptors("../dat/C35A5_DescRef_BRISK_small.dat", descRef);
// vector<cv::KeyPoint> kptsSource, kptsRef;
// readKeypoints("../dat/C35A5_KptsSource_BRISK_large.dat", kptsSource);
// readKeypoints("../dat/C35A5_KptsRef_BRISK_large.dat", kptsRef);
// cv::Mat descSource, descRef;
// readDescriptors("../dat/C35A5_DescSource_BRISK_large.dat", descSource);
// readDescriptors("../dat/C35A5_DescRef_BRISK_large.dat", descRef);
vector<cv::KeyPoint> kptsSource, kptsRef;
readKeypoints("../dat/C35A5_KptsSource_SIFT.dat", kptsSource);
readKeypoints("../dat/C35A5_KptsRef_SIFT.dat", kptsRef);
cv::Mat descSource, descRef;
readDescriptors("../dat/C35A5_DescSource_SIFT.dat", descSource);
readDescriptors("../dat/C35A5_DescRef_SIFT.dat", descRef);
vector<cv::DMatch> matches;
string matcherType = "MAT_BF"; // MAT_BF, MAT_FLANN
string descriptorType = "DES_BINARY"; // DES_BINARY, DES_HOG
string selectorType = "SEL_NN"; // SEL_NN, SEL_KNN
matchDescriptors(imgSource, imgRef, kptsSource, kptsRef, descSource, descRef, matches, descriptorType, matcherType, selectorType);
}