@@ -68,7 +68,8 @@ FrameworkReturnCode SolARDescriptorMatcherGeometricOpencv::match(const SRef<SolA
6868 const SolAR::datastructure::CameraParameters & camParams1,
6969 const SolAR::datastructure::CameraParameters & camParams2,
7070 std::vector<SolAR::datastructure::DescriptorMatch> & matches,
71- const std::vector<uint32_t >& mask)
71+ const std::vector<uint32_t >& mask1,
72+ const std::vector<uint32_t >& mask2)
7273{
7374 matches.clear ();
7475 // check conditions
@@ -120,17 +121,24 @@ FrameworkReturnCode SolARDescriptorMatcherGeometricOpencv::match(const SRef<SolA
120121
121122 // get input points in the first frame
122123 std::vector<cv::Point2f> pts1;
123- std::vector<uint32_t > indices1;
124- if (mask .size () == 0 ) {
124+ std::vector<uint32_t > indices1, indices2 ;
125+ if (mask1 .size () == 0 ) {
125126 for (int i = 0 ; i < undistortedKeypoints1.size (); ++i) {
126127 pts1.push_back (cv::Point2f (undistortedKeypoints1[i].getX (), undistortedKeypoints1[i].getY ()));
127128 indices1.push_back (i);
128129 }
129130 }
130131 else {
131- indices1 = mask;
132- for (int i = 0 ; i < mask.size (); ++i)
133- pts1.push_back (cv::Point2f (undistortedKeypoints1[mask[i]].getX (), undistortedKeypoints1[mask[i]].getY ()));
132+ indices1 = mask1;
133+ for (int i = 0 ; i < mask1.size (); ++i)
134+ pts1.push_back (cv::Point2f (undistortedKeypoints1[mask1[i]].getX (), undistortedKeypoints1[mask1[i]].getY ()));
135+ }
136+ if (mask2.size () == 0 ) {
137+ for (int i = 0 ; i < undistortedKeypoints2.size (); ++i)
138+ indices2.push_back (i);
139+ }
140+ else {
141+ indices2 = mask2;
134142 }
135143
136144 // compute epipolar lines
@@ -139,10 +147,30 @@ FrameworkReturnCode SolARDescriptorMatcherGeometricOpencv::match(const SRef<SolA
139147
140148 // convert frame descriptor to opencv's descriptor
141149 uint32_t type_conversion = SolAR::MODULES::OPENCV::SolAROpenCVHelper::deduceOpenDescriptorCVType (descriptors1->getDescriptorDataType ());
150+ #ifdef OPTIM_ON
151+ 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;
158+ }
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;
166+ }
167+ #else
142168 cv::Mat cvDescriptor1 (descriptors1->getNbDescriptors (), descriptors1->getNbElements (), type_conversion);
143169 cvDescriptor1.data = (uchar*)descriptors1->data ();
144170 cv::Mat cvDescriptor2 (descriptors2->getNbDescriptors (), descriptors2->getNbElements (), type_conversion);
145171 cvDescriptor2.data = (uchar*)descriptors2->data ();
172+ #endif
173+
146174
147175#ifdef OPTIM_ON
148176 // perform descriptor matching first on GPU using Cuda if SolARModuleOpenCVCuda
@@ -161,10 +189,10 @@ FrameworkReturnCode SolARDescriptorMatcherGeometricOpencv::match(const SRef<SolA
161189#endif
162190
163191 // filter the matches by three conditions (best distance, 2nd best distance and epipolar constraint)
164- std::vector<bool > checkMatches (undistortedKeypoints2 .size (), true );
192+ std::vector<bool > checkMatches (indices2 .size (), true );
165193 float acceptedDist = m_paddingRatio * camParams2.resolution .width ;
166194 for (auto i = 0 ; i < indices1.size (); i++) {
167- const auto & best_matches = nn_matches[indices1[i] ];
195+ const auto & best_matches = nn_matches[i ];
168196 if (!checkMatches[best_matches[0 ].trainIdx ])
169197 continue ;
170198 if (best_matches[0 ].distance >= m_matchingDistanceMax)
@@ -173,16 +201,16 @@ FrameworkReturnCode SolARDescriptorMatcherGeometricOpencv::match(const SRef<SolA
173201 continue ;
174202 // the match is accepted
175203 // now we should check the epipolar constraint
176- int idx1 = best_matches[0 ].queryIdx ;
177- int idx2 = best_matches[0 ].trainIdx ;
204+ int idx1 = indices1[ best_matches[0 ].queryIdx ] ;
205+ int idx2 = indices2[ best_matches[0 ].trainIdx ] ;
178206 float distance = best_matches[0 ].distance ;
179207 cv::Point3f l = lines2[i]; // line equation a*x + b*y +c = 0
180208 float x = undistortedKeypoints2[idx2].getX ();
181209 float y = undistortedKeypoints2[idx2].getY ();
182210 float disPointLine = std::abs (x * l.x + y * l.y + l.z ) / std::sqrt (l.x * l.x + l.y * l.y );
183211 if (disPointLine < acceptedDist) {
184212 matches.push_back (DescriptorMatch (idx1, idx2, distance));
185- checkMatches[idx2 ] = false ;
213+ checkMatches[best_matches[ 0 ]. trainIdx ] = false ;
186214 }
187215 }
188216#else
0 commit comments