-
Notifications
You must be signed in to change notification settings - Fork 6
/
ORBMatcher.cpp
107 lines (78 loc) · 2.73 KB
/
ORBMatcher.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
101
102
103
104
105
106
107
/*
Copyright (c) 2020, Tharaka Ratnayake, email: [email protected]
All rights reserved. https://github.com/tharaka27/ImageStitcherFAST
Some algorithms used in this code referred to:
1. OpenCV: http://opencv.org/
Revision history:
April 26th, 2020: initial version.
*/
#include "ORBMatcher.h"
ORBMatcher::ORBMatcher()
{
}
/*
@Compute the number of Inliers using symmetric transfer error.
@Param num Number of points in the array.
@Param H Pointer to the homography matrix.
@Param p1 std::vector to the array of cv::Point2f obj.
@Param p2 std::vector to the array of cv::Point2f scene.
@Param inlier_mask Pointer to the inlier mask matrix.
@Param dist_std Pointer to the std of the distance among all inliers.
Compute number of inliers by computing distance under a perticular H
distance = d(Hx, x') + d(invH x', x)
return: number of inliers
*/
int ORBMatcher::ComputeOrbDistance(cv::Mat vector1, cv::Mat vector2)
{
int numBit = 0;
for (int i = 0; i < 32; ++i)
{
unsigned char c = vector1.at<uchar>(i) ^ vector2.at<uchar>(i);
c = c - ((c >> 1) & 0125); // 01010101
c = (unsigned char)(c & 063) + (unsigned char)((c >> 2) & 063); // 00110011
c = (unsigned char)(c * 021) >> 4; // 11110000
numBit += c;
}
return numBit;
}
/*
@Compute the number of Inliers using symmetric transfer error.
@Param num Number of points in the array.
@Param H Pointer to the homography matrix.
@Param p1 std::vector to the array of cv::Point2f obj.
@Param p2 std::vector to the array of cv::Point2f scene.
@Param inlier_mask Pointer to the inlier mask matrix.
@Param dist_std Pointer to the std of the distance among all inliers.
Compute number of inliers by computing distance under a perticular H
distance = d(Hx, x') + d(invH x', x)
return: number of inliers
*/
std::vector<int> ORBMatcher::MatchDescriptors(cv::Mat descriptors1, cv::Mat descriptors2, std::vector<cv::DMatch> *matches)
{
int numDes1 = descriptors1.rows;
int numDes2 = descriptors2.rows;
std::vector<int> result(numDes1, -1);
std::vector<int> OrbDistances;
for (int i = 0; i < numDes1; ++i)
{
cv::Mat descriptor1 = descriptors1.row(i);
OrbDistances.clear();
OrbDistances.resize(numDes2);
for (int j = 0; j < numDes2; ++j)
{
OrbDistances[j] = ComputeOrbDistance(descriptor1, descriptors2.row(j));
}
std::vector<int>::iterator iter = std::min_element(OrbDistances.begin(), OrbDistances.end());
if (*iter < TH_HAMMING_DIST)
{
int minId = std::distance(OrbDistances.begin(), iter);
result[i] = minId;
cv::DMatch match;
match.distance = OrbDistances[minId];
match.queryIdx = i;
match.trainIdx = minId;
matches->push_back(match);
}
}
return result;
}