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

Commit 7001116

Browse files
committed
Clean and improve some code
1 parent e4ebf82 commit 7001116

File tree

2 files changed

+43
-50
lines changed

2 files changed

+43
-50
lines changed

interfaces/SolARDescriptorMatcherGeometricOpencv.h

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -95,13 +95,9 @@ class SOLAROPENCV_EXPORT_API SolARDescriptorMatcherGeometricOpencv : public base
9595
float m_distanceRatio = 0.75f;
9696
float m_paddingRatio = 0.003f;
9797
float m_matchingDistanceMax = 500.f;
98-
/// matcher type
99-
std::string m_type = "BruteForce";
100-
/// Matcher
98+
/// Matcher used only in case of cuda
10199
#ifdef WITHCUDA
102100
cv::Ptr<cv::cuda::DescriptorMatcher> m_matcher;
103-
#else
104-
cv::Ptr<cv::DescriptorMatcher> m_matcher;
105101
#endif
106102
};
107103

src/SolARDescriptorMatcherGeometricOpencv.cpp

Lines changed: 42 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020

2121
namespace xpcf = org::bcom::xpcf;
2222

23-
// test optimization code implemented by yzhou
23+
// Optimizations made by yzhou. The optimization is based on the assumption that a high performance GPU is available
24+
// If you want to unactivate these optimizations you can comment the following line
2425
#define OPTIM_ON
2526

2627
XPCF_DEFINE_FACTORY_CREATE_INSTANCE(SolAR::MODULES::OPENCV::SolARDescriptorMatcherGeometricOpencv)
@@ -45,17 +46,10 @@ SolARDescriptorMatcherGeometricOpencv::~SolARDescriptorMatcherGeometricOpencv()
4546

4647
xpcf::XPCFErrorCode SolARDescriptorMatcherGeometricOpencv::onConfigured()
4748
{
48-
#ifdef OPTIM_ON
49+
#if defined(WITHCUDA) && defined(OPTIM_ON)
4950
LOG_DEBUG(" SolARDescriptorMatcherGeometricOpencv onConfigured");
50-
#ifdef WITHCUDA
5151
m_matcher = cv::cuda::DescriptorMatcher::createBFMatcher(cv::NORM_L2);
52-
#else
53-
if (SolAROpenCVHelper::createMatcher(m_type, m_matcher) != FrameworkReturnCode::_SUCCESS) {
54-
LOG_ERROR("Descriptor matcher type {} is not supported", m_type);
55-
return xpcf::XPCFErrorCode::_FAIL;
56-
}
57-
#endif // WITHCUDA
58-
#endif
52+
#endif
5953
return xpcf::XPCFErrorCode::_SUCCESS;
6054
}
6155

@@ -79,6 +73,7 @@ FrameworkReturnCode SolARDescriptorMatcherGeometricOpencv::match(const SRef<SolA
7973
}
8074
// calculate fundametal matrix
8175
#ifdef OPTIM_ON
76+
// avoid inverting pose matrix
8277
Transform3Df pose1Inv;
8378
for (int i = 0; i < 3; i++)
8479
for (int j = 0; j < 3; j++)
@@ -102,6 +97,7 @@ FrameworkReturnCode SolARDescriptorMatcherGeometricOpencv::match(const SRef<SolA
10297
cv::Mat K1(3, 3, CV_32FC1, (void *)camParams1.intrinsic.data());
10398
cv::Mat K2(3, 3, CV_32FC1, (void *)camParams2.intrinsic.data());
10499
#ifdef OPTIM_ON
100+
// avoid inverting intrinsic matrix
105101
cv::Mat K1tInv = cv::Mat::zeros(3, 3, CV_32FC1);
106102
K1tInv.at<float>(0, 0) = 1.f / K1.at<float>(0, 0);
107103
K1tInv.at<float>(1, 1) = 1.f / K1.at<float>(1, 1);
@@ -147,47 +143,48 @@ FrameworkReturnCode SolARDescriptorMatcherGeometricOpencv::match(const SRef<SolA
147143

148144
// convert frame descriptor to opencv's descriptor
149145
uint32_t type_conversion = SolAR::MODULES::OPENCV::SolAROpenCVHelper::deduceOpenDescriptorCVType(descriptors1->getDescriptorDataType());
150-
#ifdef OPTIM_ON
146+
// take into account of mask for both descriptors 1 & 2
151147
cv::Mat cvDescriptor1(indices1.size(), descriptors1->getNbElements(), type_conversion);
152-
uchar* buf_in = (uchar*)descriptors1->data();
153-
uchar* buf_out = cvDescriptor1.data;
154-
uint32_t num_elements = static_cast<uint32_t>(descriptors1->getNbElements());
155-
for (auto i = 0; i < indices1.size(); i++) {
156-
std::memcpy(buf_out, buf_in + num_elements * indices1[i], num_elements);
157-
buf_out += num_elements;
148+
if (mask1.size() == 0) {
149+
cvDescriptor1.data = (uchar*)descriptors1->data();
158150
}
159-
cv::Mat cvDescriptor2(indices2.size(), descriptors2->getNbElements(), type_conversion);
160-
buf_in = (uchar*)descriptors2->data();
161-
buf_out = cvDescriptor2.data;
162-
num_elements = static_cast<uint32_t>(descriptors2->getNbElements());
163-
for (auto i = 0; i < indices2.size(); i++) {
164-
std::memcpy(buf_out, buf_in + num_elements * indices2[i], num_elements);
165-
buf_out += num_elements;
151+
else {
152+
uchar* buf_in = (uchar*)descriptors1->data();
153+
uchar* buf_out = cvDescriptor1.data;
154+
uint32_t num_elements = static_cast<uint32_t>(descriptors1->getNbElements());
155+
for (auto i = 0; i < indices1.size(); i++) {
156+
std::memcpy(buf_out, buf_in + num_elements * indices1[i], num_elements);
157+
buf_out += num_elements;
158+
}
166159
}
167-
#else
168-
cv::Mat cvDescriptor1(descriptors1->getNbDescriptors(), descriptors1->getNbElements(), type_conversion);
169-
cvDescriptor1.data = (uchar*)descriptors1->data();
170-
cv::Mat cvDescriptor2(descriptors2->getNbDescriptors(), descriptors2->getNbElements(), type_conversion);
171-
cvDescriptor2.data = (uchar*)descriptors2->data();
172-
#endif
173160

161+
cv::Mat cvDescriptor2(indices2.size(), descriptors2->getNbElements(), type_conversion);
162+
if (mask2.size() == 0) {
163+
cvDescriptor2.data = (uchar*)descriptors2->data();
164+
}
165+
else {
166+
uchar* buf_in = (uchar*)descriptors2->data();
167+
uchar* buf_out = cvDescriptor2.data;
168+
uint32_t num_elements = static_cast<uint32_t>(descriptors2->getNbElements());
169+
for (auto i = 0; i < indices2.size(); i++) {
170+
std::memcpy(buf_out, buf_in + num_elements * indices2[i], num_elements);
171+
buf_out += num_elements;
172+
}
173+
}
174174

175-
#ifdef OPTIM_ON
176175
// perform descriptor matching first on GPU using Cuda if SolARModuleOpenCVCuda
176+
#if defined(WITHCUDA) && defined(OPTIM_ON)
177+
cv::cuda::GpuMat cvDescriptor1Gpu, cvDescriptor2Gpu;
177178
std::vector< std::vector<cv::DMatch> > nn_matches;
178-
#ifdef WITHCUDA
179179
if (descriptors1->getDescriptorDataType() != DescriptorDataType::TYPE_32F) // convert to float because cuda descriptor match only supports float type
180180
cvDescriptor1.convertTo(cvDescriptor1, CV_32F);
181181
if (descriptors2->getDescriptorDataType() != DescriptorDataType::TYPE_32F)
182182
cvDescriptor2.convertTo(cvDescriptor2, CV_32F);
183-
cv::cuda::GpuMat cvDescriptor1Gpu, cvDescriptor2Gpu;
183+
184184
cvDescriptor1Gpu.upload(cvDescriptor1);
185185
cvDescriptor2Gpu.upload(cvDescriptor2);
186186
m_matcher->knnMatch(cvDescriptor1Gpu, cvDescriptor2Gpu, nn_matches, 2);
187-
#else
188-
m_matcher->knnMatch(cvDescriptor1, cvDescriptor2, nn_matches, 2);
189-
#endif
190-
187+
191188
// filter the matches by three conditions (best distance, 2nd best distance and epipolar constraint)
192189
std::vector<bool> checkMatches(indices2.size(), true);
193190
float acceptedDist = m_paddingRatio * camParams2.resolution.width;
@@ -215,19 +212,19 @@ FrameworkReturnCode SolARDescriptorMatcherGeometricOpencv::match(const SRef<SolA
215212
}
216213
#else
217214
// first apply epipolar constraint then apply descriptor matching
218-
std::vector<bool> checkMatches(undistortedKeypoints2.size(), true);
215+
std::vector<bool> checkMatches(indices2.size(), true);
219216
float acceptedDist = m_paddingRatio * camParams2.resolution.width;
220217
for (int i = 0; i < indices1.size(); i++) {
221-
const cv::Mat cvDes1 = cvDescriptor1.row(indices1[i]);
218+
const cv::Mat cvDes1 = cvDescriptor1.row(i);
222219
float bestDist = std::numeric_limits<float>::max();
223220
float bestDist2 = std::numeric_limits<float>::max();
224221
int bestIdx = -1;
225222
cv::Point3f l = lines2[i];
226223
float lxyz_norm = std::sqrt(l.x * l.x + l.y * l.y);
227-
228-
for (int j = 0; j < undistortedKeypoints2.size(); j++) {
229-
float x = undistortedKeypoints2[j].getX();
230-
float y = undistortedKeypoints2[j].getY();
224+
225+
for (int j = 0; j < indices2.size(); j++) {
226+
float x = undistortedKeypoints2[indices2[j]].getX();
227+
float y = undistortedKeypoints2[indices2[j]].getY();
231228
float disPointLine = std::abs(x * l.x + y * l.y + l.z) / lxyz_norm;
232229
if (disPointLine < acceptedDist) {
233230
float dist = cv::norm(cvDes1, cvDescriptor2.row(j), cv::NORM_L2);
@@ -244,11 +241,11 @@ FrameworkReturnCode SolARDescriptorMatcherGeometricOpencv::match(const SRef<SolA
244241
}
245242
}
246243
if ((bestIdx != -1) && (bestDist < m_matchingDistanceMax) && (bestDist < m_distanceRatio * bestDist2) && (checkMatches[bestIdx])) {
247-
matches.push_back(DescriptorMatch(indices1[i], bestIdx, bestDist));
244+
matches.push_back(DescriptorMatch(indices1[i], indices2[bestIdx], bestDist));
248245
checkMatches[bestIdx] = false;
249246
}
250247
}
251-
#endif
248+
#endif
252249
return FrameworkReturnCode::_SUCCESS;
253250
}
254251

0 commit comments

Comments
 (0)