-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcorrespondences_matching.cpp
100 lines (73 loc) · 3.11 KB
/
correspondences_matching.cpp
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
#include "arguments_parser.hpp"
#include <opencv2/opencv.hpp>
void correspondencesMatching(cv::Mat img1, cv::Mat img2) {
// Create SIFT (floating-point descriptors)
cv::Ptr<cv::SIFT> sift = cv::SIFT::create();
std::vector<cv::KeyPoint> keypoints1, keypoints2;
cv::Mat descriptors1, descriptors2;
sift->detectAndCompute(img1, cv::Mat(), keypoints1, descriptors1);
sift->detectAndCompute(img2, cv::Mat(), keypoints2, descriptors2);
//////////////////////// BFMatcher ////////////////////////////
cv::BFMatcher matcher(cv::NORM_L2);
std::vector<cv::DMatch> matches;
cv::Mat img_matches;
matcher.match(descriptors1, descriptors2, matches);
cv::drawMatches(img1, keypoints1, img2, keypoints2, matches, img_matches);
cv::imshow("BFMatcher", img_matches);
cv::imwrite("BFMatcher.png", img_matches);
cv::waitKey(0);
//////////////////////// knnMatches ////////////////////////////
std::vector<std::vector<cv::DMatch>> knnMatches;
int k = 5;
matcher.knnMatch(descriptors1, descriptors2, knnMatches, k);
// Apply Lowe's ratio test to filter matches
const float ratioThresh = 0.75f; // Lowe's ratio test threshold
std::vector<cv::DMatch> goodMatches;
for (const auto &knnMatch : knnMatches) {
if (knnMatch.size() >= 2 &&
knnMatch[0].distance < ratioThresh * knnMatch[1].distance) {
goodMatches.push_back(knnMatch[0]);
}
}
cv::Mat img_knn_matches;
cv::drawMatches(img1, keypoints1, img2, keypoints2, goodMatches,
img_knn_matches);
cv::imshow("KNN Matches", img_knn_matches);
cv::imwrite("KNN_Matches.png", img_knn_matches);
cv::waitKey(0);
//////////////////////// radius matching ////////////////////////////
cv::Ptr<cv::ORB> orb = cv::ORB::create();
orb->detectAndCompute(img1, cv::noArray(), keypoints1, descriptors1);
orb->detectAndCompute(img2, cv::noArray(), keypoints2, descriptors2);
// Use BFMatcher with NORM_HAMMING (suitable for ORB descriptors)
cv::BFMatcher radius_matcher(cv::NORM_HAMMING);
// Perform radius matching
const float maxDistance = 100.0f; // Radius threshold
std::vector<std::vector<cv::DMatch>> radiusMatches;
matcher.radiusMatch(descriptors1, descriptors2, radiusMatches, maxDistance);
// Filter and collect matches for visualization
std::vector<cv::DMatch> radiusGoodMatches;
for (const auto &matches : radiusMatches) {
for (const auto &match : matches) {
if (match.distance < maxDistance) {
radiusGoodMatches.push_back(match);
}
}
}
// Draw matches
cv::Mat imgMatches;
cv::drawMatches(img1, keypoints1, img2, keypoints2, radiusMatches,
imgMatches);
// Display the result
cv::imshow("Radius Match", imgMatches);
cv::imwrite("Radius_Match.png", img_knn_matches);
cv::waitKey(0);
}
int main(int argc, char **argv) {
std::string image_path1 = "../../images/correspondences_matching/000000.png";
std::string image_path2 = "../../images/correspondences_matching/000001.png";
cv::Mat img1 = cv::imread(image_path1, cv::IMREAD_ANYCOLOR);
cv::Mat img2 = cv::imread(image_path2, cv::IMREAD_ANYCOLOR);
correspondencesMatching(img1, img2);
return 0;
}