Features2d.cpp
Go to the documentation of this file.
1 /*
2 Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
3 All rights reserved.
4 
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7  * Redistributions of source code must retain the above copyright
8  notice, this list of conditions and the following disclaimer.
9  * Redistributions in binary form must reproduce the above copyright
10  notice, this list of conditions and the following disclaimer in the
11  documentation and/or other materials provided with the distribution.
12  * Neither the name of the Universite de Sherbrooke nor the
13  names of its contributors may be used to endorse or promote products
14  derived from this software without specific prior written permission.
15 
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
20 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27 
29 #include "rtabmap/core/util3d.h"
31 #include "rtabmap/core/Stereo.h"
32 #include "rtabmap/core/util2d.h"
33 #include "rtabmap/utilite/UStl.h"
36 #include "rtabmap/utilite/UMath.h"
38 #include "rtabmap/utilite/UTimer.h"
39 #include <opencv2/imgproc/imgproc_c.h>
40 #include <opencv2/core/version.hpp>
41 #include <opencv2/opencv_modules.hpp>
42 
43 #if CV_MAJOR_VERSION < 3
44 #include "opencv/Orb.h"
45 #ifdef HAVE_OPENCV_GPU
46 #include <opencv2/gpu/gpu.hpp>
47 #endif
48 #else
49 #include <opencv2/core/cuda.hpp>
50 #endif
51 
52 #ifdef HAVE_OPENCV_NONFREE
53  #if CV_MAJOR_VERSION == 2 && CV_MINOR_VERSION >=4
54  #include <opencv2/nonfree/gpu.hpp>
55  #include <opencv2/nonfree/features2d.hpp>
56  #endif
57 #endif
58 #ifdef HAVE_OPENCV_XFEATURES2D
59  #include <opencv2/xfeatures2d.hpp>
60  #include <opencv2/xfeatures2d/nonfree.hpp>
61  #include <opencv2/xfeatures2d/cuda.hpp>
62 #endif
63 
64 namespace rtabmap {
65 
67  std::vector<cv::KeyPoint> & keypoints,
68  const cv::Mat & depth,
69  float minDepth,
70  float maxDepth)
71 {
72  cv::Mat descriptors;
73  filterKeypointsByDepth(keypoints, descriptors, depth, minDepth, maxDepth);
74 }
75 
77  std::vector<cv::KeyPoint> & keypoints,
78  cv::Mat & descriptors,
79  const cv::Mat & depth,
80  float minDepth,
81  float maxDepth)
82 {
83  UASSERT(minDepth >= 0.0f);
84  UASSERT(maxDepth <= 0.0f || maxDepth > minDepth);
85  if(!depth.empty() && (descriptors.empty() || descriptors.rows == (int)keypoints.size()))
86  {
87  std::vector<cv::KeyPoint> output(keypoints.size());
88  std::vector<int> indexes(keypoints.size(), 0);
89  int oi=0;
90  bool isInMM = depth.type() == CV_16UC1;
91  for(unsigned int i=0; i<keypoints.size(); ++i)
92  {
93  int u = int(keypoints[i].pt.x+0.5f);
94  int v = int(keypoints[i].pt.y+0.5f);
95  if(u >=0 && u<depth.cols && v >=0 && v<depth.rows)
96  {
97  float d = isInMM?(float)depth.at<uint16_t>(v,u)*0.001f:depth.at<float>(v,u);
98  if(uIsFinite(d) && d>minDepth && (maxDepth <= 0.0f || d < maxDepth))
99  {
100  output[oi++] = keypoints[i];
101  indexes[i] = 1;
102  }
103  }
104  }
105  output.resize(oi);
106  keypoints = output;
107 
108  if(!descriptors.empty() && (int)keypoints.size() != descriptors.rows)
109  {
110  if(keypoints.size() == 0)
111  {
112  descriptors = cv::Mat();
113  }
114  else
115  {
116  cv::Mat newDescriptors((int)keypoints.size(), descriptors.cols, descriptors.type());
117  int di = 0;
118  for(unsigned int i=0; i<indexes.size(); ++i)
119  {
120  if(indexes[i] == 1)
121  {
122  if(descriptors.type() == CV_32FC1)
123  {
124  memcpy(newDescriptors.ptr<float>(di++), descriptors.ptr<float>(i), descriptors.cols*sizeof(float));
125  }
126  else // CV_8UC1
127  {
128  memcpy(newDescriptors.ptr<char>(di++), descriptors.ptr<char>(i), descriptors.cols*sizeof(char));
129  }
130  }
131  }
132  descriptors = newDescriptors;
133  }
134  }
135  }
136 }
137 
139  std::vector<cv::KeyPoint> & keypoints,
140  const cv::Mat & disparity,
141  float minDisparity)
142 {
143  cv::Mat descriptors;
144  filterKeypointsByDisparity(keypoints, descriptors, disparity, minDisparity);
145 }
146 
148  std::vector<cv::KeyPoint> & keypoints,
149  cv::Mat & descriptors,
150  const cv::Mat & disparity,
151  float minDisparity)
152 {
153  if(!disparity.empty() && minDisparity > 0.0f && (descriptors.empty() || descriptors.rows == (int)keypoints.size()))
154  {
155  std::vector<cv::KeyPoint> output(keypoints.size());
156  std::vector<int> indexes(keypoints.size(), 0);
157  int oi=0;
158  for(unsigned int i=0; i<keypoints.size(); ++i)
159  {
160  int u = int(keypoints[i].pt.x+0.5f);
161  int v = int(keypoints[i].pt.y+0.5f);
162  if(u >=0 && u<disparity.cols && v >=0 && v<disparity.rows)
163  {
164  float d = disparity.type() == CV_16SC1?float(disparity.at<short>(v,u))/16.0f:disparity.at<float>(v,u);
165  if(d!=0.0f && uIsFinite(d) && d >= minDisparity)
166  {
167  output[oi++] = keypoints[i];
168  indexes[i] = 1;
169  }
170  }
171  }
172  output.resize(oi);
173  keypoints = output;
174 
175  if(!descriptors.empty() && (int)keypoints.size() != descriptors.rows)
176  {
177  if(keypoints.size() == 0)
178  {
179  descriptors = cv::Mat();
180  }
181  else
182  {
183  cv::Mat newDescriptors((int)keypoints.size(), descriptors.cols, descriptors.type());
184  int di = 0;
185  for(unsigned int i=0; i<indexes.size(); ++i)
186  {
187  if(indexes[i] == 1)
188  {
189  if(descriptors.type() == CV_32FC1)
190  {
191  memcpy(newDescriptors.ptr<float>(di++), descriptors.ptr<float>(i), descriptors.cols*sizeof(float));
192  }
193  else // CV_8UC1
194  {
195  memcpy(newDescriptors.ptr<char>(di++), descriptors.ptr<char>(i), descriptors.cols*sizeof(char));
196  }
197  }
198  }
199  descriptors = newDescriptors;
200  }
201  }
202  }
203 }
204 
205 void Feature2D::limitKeypoints(std::vector<cv::KeyPoint> & keypoints, int maxKeypoints)
206 {
207  cv::Mat descriptors;
208  limitKeypoints(keypoints, descriptors, maxKeypoints);
209 }
210 
211 void Feature2D::limitKeypoints(std::vector<cv::KeyPoint> & keypoints, cv::Mat & descriptors, int maxKeypoints)
212 {
213  std::vector<cv::Point3f> keypoints3D;
214  limitKeypoints(keypoints, keypoints3D, descriptors, maxKeypoints);
215 }
216 
217 void Feature2D::limitKeypoints(std::vector<cv::KeyPoint> & keypoints, std::vector<cv::Point3f> & keypoints3D, cv::Mat & descriptors, int maxKeypoints)
218 {
219  UASSERT_MSG((int)keypoints.size() == descriptors.rows || descriptors.rows == 0, uFormat("keypoints=%d descriptors=%d", (int)keypoints.size(), descriptors.rows).c_str());
220  UASSERT_MSG(keypoints.size() == keypoints3D.size() || keypoints3D.size() == 0, uFormat("keypoints=%d keypoints3D=%d", (int)keypoints.size(), (int)keypoints3D.size()).c_str());
221  if(maxKeypoints > 0 && (int)keypoints.size() > maxKeypoints)
222  {
223  UTimer timer;
224  ULOGGER_DEBUG("too much words (%d), removing words with the hessian threshold", keypoints.size());
225  // Remove words under the new hessian threshold
226 
227  // Sort words by hessian
228  std::multimap<float, int> hessianMap; // <hessian,id>
229  for(unsigned int i = 0; i <keypoints.size(); ++i)
230  {
231  //Keep track of the data, to be easier to manage the data in the next step
232  hessianMap.insert(std::pair<float, int>(fabs(keypoints[i].response), i));
233  }
234 
235  // Remove them from the signature
236  int removed = (int)hessianMap.size()-maxKeypoints;
237  std::multimap<float, int>::reverse_iterator iter = hessianMap.rbegin();
238  std::vector<cv::KeyPoint> kptsTmp(maxKeypoints);
239  std::vector<cv::Point3f> kpts3DTmp(maxKeypoints);
240  cv::Mat descriptorsTmp;
241  if(descriptors.rows)
242  {
243  descriptorsTmp = cv::Mat(maxKeypoints, descriptors.cols, descriptors.type());
244  }
245  for(unsigned int k=0; k < kptsTmp.size() && iter!=hessianMap.rend(); ++k, ++iter)
246  {
247  kptsTmp[k] = keypoints[iter->second];
248  if(keypoints3D.size())
249  {
250  kpts3DTmp[k] = keypoints3D[iter->second];
251  }
252  if(descriptors.rows)
253  {
254  if(descriptors.type() == CV_32FC1)
255  {
256  memcpy(descriptorsTmp.ptr<float>(k), descriptors.ptr<float>(iter->second), descriptors.cols*sizeof(float));
257  }
258  else
259  {
260  memcpy(descriptorsTmp.ptr<char>(k), descriptors.ptr<char>(iter->second), descriptors.cols*sizeof(char));
261  }
262  }
263  }
264  ULOGGER_DEBUG("%d keypoints removed, (kept %d), minimum response=%f", removed, (int)kptsTmp.size(), kptsTmp.size()?kptsTmp.back().response:0.0f);
265  ULOGGER_DEBUG("removing words time = %f s", timer.ticks());
266  keypoints = kptsTmp;
267  keypoints3D = kpts3DTmp;
268  if(descriptors.rows)
269  {
270  descriptors = descriptorsTmp;
271  }
272  }
273 }
274 
275 void Feature2D::limitKeypoints(const std::vector<cv::KeyPoint> & keypoints, std::vector<bool> & inliers, int maxKeypoints)
276 {
277  if(maxKeypoints > 0 && (int)keypoints.size() > maxKeypoints)
278  {
279  UTimer timer;
280  ULOGGER_DEBUG("too much words (%d), removing words with the hessian threshold", keypoints.size());
281  // Remove words under the new hessian threshold
282 
283  // Sort words by hessian
284  std::multimap<float, int> hessianMap; // <hessian,id>
285  for(unsigned int i = 0; i <keypoints.size(); ++i)
286  {
287  //Keep track of the data, to be easier to manage the data in the next step
288  hessianMap.insert(std::pair<float, int>(fabs(keypoints[i].response), i));
289  }
290 
291  // Keep keypoints with highest response
292  int removed = (int)hessianMap.size()-maxKeypoints;
293  std::multimap<float, int>::reverse_iterator iter = hessianMap.rbegin();
294  inliers.resize(keypoints.size(), false);
295  float minimumHessian = 0.0f;
296  for(int k=0; k < maxKeypoints && iter!=hessianMap.rend(); ++k, ++iter)
297  {
298  inliers[iter->second] = true;
299  minimumHessian = iter->first;
300  }
301  ULOGGER_DEBUG("%d keypoints removed, (kept %d), minimum response=%f", removed, maxKeypoints, minimumHessian);
302  ULOGGER_DEBUG("filter keypoints time = %f s", timer.ticks());
303  }
304  else
305  {
306  inliers.resize(keypoints.size(), true);
307  }
308 }
309 
310 cv::Rect Feature2D::computeRoi(const cv::Mat & image, const std::string & roiRatios)
311 {
312  return util2d::computeRoi(image, roiRatios);
313 }
314 
315 cv::Rect Feature2D::computeRoi(const cv::Mat & image, const std::vector<float> & roiRatios)
316 {
317  return util2d::computeRoi(image, roiRatios);
318 }
319 
321 // Feature2D
323 Feature2D::Feature2D(const ParametersMap & parameters) :
324  maxFeatures_(Parameters::defaultKpMaxFeatures()),
325  _maxDepth(Parameters::defaultKpMaxDepth()),
326  _minDepth(Parameters::defaultKpMinDepth()),
327  _roiRatios(std::vector<float>(4, 0.0f)),
328  _subPixWinSize(Parameters::defaultKpSubPixWinSize()),
329  _subPixIterations(Parameters::defaultKpSubPixIterations()),
330  _subPixEps(Parameters::defaultKpSubPixEps()),
331  gridRows_(Parameters::defaultKpGridRows()),
332  gridCols_(Parameters::defaultKpGridCols())
333 {
334  _stereo = new Stereo(parameters);
335  this->parseParameters(parameters);
336 }
338 {
339  delete _stereo;
340 }
342 {
343  uInsert(parameters_, parameters);
344 
345  Parameters::parse(parameters, Parameters::kKpMaxFeatures(), maxFeatures_);
346  Parameters::parse(parameters, Parameters::kKpMaxDepth(), _maxDepth);
347  Parameters::parse(parameters, Parameters::kKpMinDepth(), _minDepth);
348  Parameters::parse(parameters, Parameters::kKpSubPixWinSize(), _subPixWinSize);
349  Parameters::parse(parameters, Parameters::kKpSubPixIterations(), _subPixIterations);
350  Parameters::parse(parameters, Parameters::kKpSubPixEps(), _subPixEps);
351  Parameters::parse(parameters, Parameters::kKpGridRows(), gridRows_);
352  Parameters::parse(parameters, Parameters::kKpGridCols(), gridCols_);
353 
354  UASSERT(gridRows_ >= 1 && gridCols_>=1);
355  if(maxFeatures_ > 0)
356  {
358  }
359 
360  // convert ROI from string to vector
361  ParametersMap::const_iterator iter;
362  if((iter=parameters.find(Parameters::kKpRoiRatios())) != parameters.end())
363  {
364  std::list<std::string> strValues = uSplit(iter->second, ' ');
365  if(strValues.size() != 4)
366  {
367  ULOGGER_ERROR("The number of values must be 4 (roi=\"%s\")", iter->second.c_str());
368  }
369  else
370  {
371  std::vector<float> tmpValues(4);
372  unsigned int i=0;
373  for(std::list<std::string>::iterator jter = strValues.begin(); jter!=strValues.end(); ++jter)
374  {
375  tmpValues[i] = uStr2Float(*jter);
376  ++i;
377  }
378 
379  if(tmpValues[0] >= 0 && tmpValues[0] < 1 && tmpValues[0] < 1.0f-tmpValues[1] &&
380  tmpValues[1] >= 0 && tmpValues[1] < 1 && tmpValues[1] < 1.0f-tmpValues[0] &&
381  tmpValues[2] >= 0 && tmpValues[2] < 1 && tmpValues[2] < 1.0f-tmpValues[3] &&
382  tmpValues[3] >= 0 && tmpValues[3] < 1 && tmpValues[3] < 1.0f-tmpValues[2])
383  {
384  _roiRatios = tmpValues;
385  }
386  else
387  {
388  ULOGGER_ERROR("The roi ratios are not valid (roi=\"%s\")", iter->second.c_str());
389  }
390  }
391  }
392 
393  //stereo
394  UASSERT(_stereo != 0);
395  if((iter=parameters.find(Parameters::kStereoOpticalFlow())) != parameters.end())
396  {
397  delete _stereo;
399  }
400  else
401  {
402  _stereo->parseParameters(parameters);
403  }
404 }
406 {
407  int type = Parameters::defaultKpDetectorStrategy();
408  Parameters::parse(parameters, Parameters::kKpDetectorStrategy(), type);
409  return create((Feature2D::Type)type, parameters);
410 }
412 {
413 #ifndef RTABMAP_NONFREE
414  if(type == Feature2D::kFeatureSurf || type == Feature2D::kFeatureSift)
415  {
416 #if CV_MAJOR_VERSION < 3
417  UWARN("SURF and SIFT features cannot be used because OpenCV was not built with nonfree module. ORB is used instead.");
418 #else
419  UWARN("SURF and SIFT features cannot be used because OpenCV was not built with xfeatures2d module. ORB is used instead.");
420 #endif
421  type = Feature2D::kFeatureOrb;
422  }
423 #if CV_MAJOR_VERSION == 3
424  if(type == Feature2D::kFeatureFastBrief ||
428  {
429  UWARN("BRIEF and FREAK features cannot be used because OpenCV was not built with xfeatures2d module. ORB is used instead.");
430  type = Feature2D::kFeatureOrb;
431  }
432 #endif
433 #endif
434 
435 #if CV_MAJOR_VERSION < 3
436  if(type == Feature2D::kFeatureKaze)
437  {
438 #ifdef RTABMAP_NONFREE
439  UWARN("KAZE detector/descriptor can be used only with OpenCV3. SURF is used instead.");
441 #else
442  UWARN("KAZE detector/descriptor can be used only with OpenCV3. ORB is used instead.");
443  type = Feature2D::kFeatureOrb;
444 #endif
445  }
446 #endif
447 
448  Feature2D * feature2D = 0;
449  switch(type)
450  {
452  feature2D = new SURF(parameters);
453  break;
455  feature2D = new SIFT(parameters);
456  break;
458  feature2D = new ORB(parameters);
459  break;
461  feature2D = new FAST_BRIEF(parameters);
462  break;
464  feature2D = new FAST_FREAK(parameters);
465  break;
467  feature2D = new GFTT_FREAK(parameters);
468  break;
470  feature2D = new GFTT_BRIEF(parameters);
471  break;
473  feature2D = new GFTT_ORB(parameters);
474  break;
476  feature2D = new BRISK(parameters);
477  break;
479  feature2D = new KAZE(parameters);
480  break;
481 #ifdef RTABMAP_NONFREE
482  default:
483  feature2D = new SURF(parameters);
485  break;
486 #else
487  default:
488  feature2D = new ORB(parameters);
489  type = Feature2D::kFeatureOrb;
490  break;
491 #endif
492 
493  }
494  return feature2D;
495 }
496 
497 std::vector<cv::KeyPoint> Feature2D::generateKeypoints(const cv::Mat & image, const cv::Mat & maskIn) const
498 {
499  UASSERT(!image.empty());
500  UASSERT(image.type() == CV_8UC1);
501 
502  cv::Mat mask;
503  if(!maskIn.empty())
504  {
505  if(maskIn.type()==CV_16UC1 || maskIn.type() == CV_32FC1)
506  {
507  mask = cv::Mat::zeros(maskIn.rows, maskIn.cols, CV_8UC1);
508  for(int i=0; i<(int)mask.total(); ++i)
509  {
510  float value = 0.0f;
511  if(maskIn.type()==CV_16UC1)
512  {
513  if(((unsigned short*)maskIn.data)[i] > 0 &&
514  ((unsigned short*)maskIn.data)[i] < std::numeric_limits<unsigned short>::max())
515  {
516  value = float(((unsigned short*)maskIn.data)[i])*0.001f;
517  }
518  }
519  else
520  {
521  value = ((float*)maskIn.data)[i];
522  }
523 
524  if(value>_minDepth &&
525  (_maxDepth == 0.0f || value <= _maxDepth))
526  {
527  ((unsigned char*)mask.data)[i] = 255; // ORB uses 255 to handle pyramids
528  }
529  }
530  }
531  else if(maskIn.type()==CV_8UC1)
532  {
533  // assume a standard mask
534  mask = maskIn;
535  }
536  else
537  {
538  UERROR("Wrong mask type (%d)! Should be 8UC1, 16UC1 or 32FC1.", maskIn.type());
539  }
540  }
541 
542  UASSERT(mask.empty() || (mask.cols == image.cols && mask.rows == image.rows));
543 
544  std::vector<cv::KeyPoint> keypoints;
545  UTimer timer;
546  cv::Rect globalRoi = Feature2D::computeRoi(image, _roiRatios);
547  if(!(globalRoi.width && globalRoi.height))
548  {
549  globalRoi = cv::Rect(0,0,image.cols, image.rows);
550  }
551 
552  // Get keypoints
553  int rowSize = globalRoi.height / gridRows_;
554  int colSize = globalRoi.width / gridCols_;
555  for (int i = 0; i<gridRows_; ++i)
556  {
557  for (int j = 0; j<gridCols_; ++j)
558  {
559  cv::Rect roi(globalRoi.x + j*colSize, globalRoi.y + i*rowSize, colSize, rowSize);
560  std::vector<cv::KeyPoint> sub_keypoints;
561  sub_keypoints = this->generateKeypointsImpl(image, roi, mask);
562  limitKeypoints(sub_keypoints, maxFeatures_);
563  if(roi.x || roi.y)
564  {
565  // Adjust keypoint position to raw image
566  for(std::vector<cv::KeyPoint>::iterator iter=sub_keypoints.begin(); iter!=sub_keypoints.end(); ++iter)
567  {
568  iter->pt.x += roi.x;
569  iter->pt.y += roi.y;
570  }
571  }
572  keypoints.insert( keypoints.end(), sub_keypoints.begin(), sub_keypoints.end() );
573  }
574  }
575  UDEBUG("Keypoints extraction time = %f s, keypoints extracted = %d (mask empty=%d)", timer.ticks(), keypoints.size(), mask.empty()?1:0);
576 
577  if(keypoints.size() && _subPixWinSize > 0 && _subPixIterations > 0)
578  {
579  std::vector<cv::Point2f> corners;
580  cv::KeyPoint::convert(keypoints, corners);
581  cv::cornerSubPix( image, corners,
582  cv::Size( _subPixWinSize, _subPixWinSize ),
583  cv::Size( -1, -1 ),
584  cv::TermCriteria( CV_TERMCRIT_ITER | CV_TERMCRIT_EPS, _subPixIterations, _subPixEps ) );
585 
586  for(unsigned int i=0;i<corners.size(); ++i)
587  {
588  keypoints[i].pt = corners[i];
589  }
590  UDEBUG("subpixel time = %f s", timer.ticks());
591  }
592 
593  return keypoints;
594 }
595 
597  const cv::Mat & image,
598  std::vector<cv::KeyPoint> & keypoints) const
599 {
600  cv::Mat descriptors;
601  if(keypoints.size())
602  {
603  UASSERT(!image.empty());
604  UASSERT(image.type() == CV_8UC1);
605  descriptors = generateDescriptorsImpl(image, keypoints);
606  UASSERT_MSG(descriptors.rows == (int)keypoints.size(), uFormat("descriptors=%d, keypoints=%d", descriptors.rows, (int)keypoints.size()).c_str());
607  UDEBUG("Descriptors extracted = %d, remaining kpts=%d", descriptors.rows, (int)keypoints.size());
608  }
609  return descriptors;
610 }
611 
612 std::vector<cv::Point3f> Feature2D::generateKeypoints3D(
613  const SensorData & data,
614  const std::vector<cv::KeyPoint> & keypoints) const
615 {
616  std::vector<cv::Point3f> keypoints3D;
617  if(keypoints.size())
618  {
619  if(!data.rightRaw().empty() && !data.imageRaw().empty() && data.stereoCameraModel().isValidForProjection())
620  {
621  //stereo
622  cv::Mat imageMono;
623  // convert to grayscale
624  if(data.imageRaw().channels() > 1)
625  {
626  cv::cvtColor(data.imageRaw(), imageMono, cv::COLOR_BGR2GRAY);
627  }
628  else
629  {
630  imageMono = data.imageRaw();
631  }
632 
633  std::vector<cv::Point2f> leftCorners;
634  cv::KeyPoint::convert(keypoints, leftCorners);
635  std::vector<unsigned char> status;
636 
637  std::vector<cv::Point2f> rightCorners;
638  rightCorners = _stereo->computeCorrespondences(
639  imageMono,
640  data.rightRaw(),
641  leftCorners,
642  status);
643 
644  keypoints3D = util3d::generateKeypoints3DStereo(
645  leftCorners,
646  rightCorners,
647  data.stereoCameraModel(),
648  status,
649  _minDepth,
650  _maxDepth);
651  }
652  else if(!data.depthRaw().empty() && data.cameraModels().size())
653  {
654  keypoints3D = util3d::generateKeypoints3DDepth(
655  keypoints,
656  data.depthOrRightRaw(),
657  data.cameraModels(),
658  _minDepth,
659  _maxDepth);
660  }
661  }
662 
663  return keypoints3D;
664 }
665 
667 //SURF
669 SURF::SURF(const ParametersMap & parameters) :
670  hessianThreshold_(Parameters::defaultSURFHessianThreshold()),
671  nOctaves_(Parameters::defaultSURFOctaves()),
672  nOctaveLayers_(Parameters::defaultSURFOctaveLayers()),
673  extended_(Parameters::defaultSURFExtended()),
674  upright_(Parameters::defaultSURFUpright()),
675  gpuKeypointsRatio_(Parameters::defaultSURFGpuKeypointsRatio()),
676  gpuVersion_(Parameters::defaultSURFGpuVersion())
677 {
678  parseParameters(parameters);
679 }
680 
682 {
683 }
684 
685 void SURF::parseParameters(const ParametersMap & parameters)
686 {
687  Feature2D::parseParameters(parameters);
688 
689  Parameters::parse(parameters, Parameters::kSURFExtended(), extended_);
690  Parameters::parse(parameters, Parameters::kSURFHessianThreshold(), hessianThreshold_);
691  Parameters::parse(parameters, Parameters::kSURFOctaveLayers(), nOctaveLayers_);
692  Parameters::parse(parameters, Parameters::kSURFOctaves(), nOctaves_);
693  Parameters::parse(parameters, Parameters::kSURFUpright(), upright_);
694  Parameters::parse(parameters, Parameters::kSURFGpuKeypointsRatio(), gpuKeypointsRatio_);
695  Parameters::parse(parameters, Parameters::kSURFGpuVersion(), gpuVersion_);
696 
697 #ifdef RTABMAP_NONFREE
698 #if CV_MAJOR_VERSION < 3
699  if(gpuVersion_ && cv::gpu::getCudaEnabledDeviceCount() == 0)
700  {
701  UWARN("GPU version of SURF not available! Using CPU version instead...");
702  gpuVersion_ = false;
703  }
704 #else
705  if(gpuVersion_ && cv::cuda::getCudaEnabledDeviceCount() == 0)
706  {
707  UWARN("GPU version of SURF not available! Using CPU version instead...");
708  gpuVersion_ = false;
709  }
710 #endif
711  if(gpuVersion_)
712  {
714  }
715  else
716  {
717 #if CV_MAJOR_VERSION < 3
719 #else
721 #endif
722  }
723 #else
724  UWARN("RTAB-Map is not built with OpenCV nonfree module so SURF cannot be used!");
725 #endif
726 }
727 
728 std::vector<cv::KeyPoint> SURF::generateKeypointsImpl(const cv::Mat & image, const cv::Rect & roi, const cv::Mat & mask) const
729 {
730  UASSERT(!image.empty() && image.channels() == 1 && image.depth() == CV_8U);
731  std::vector<cv::KeyPoint> keypoints;
732 
733 #ifdef RTABMAP_NONFREE
734  cv::Mat imgRoi(image, roi);
735  cv::Mat maskRoi;
736  if(!mask.empty())
737  {
738  maskRoi = cv::Mat(mask, roi);
739  }
740  if(gpuVersion_)
741  {
742 #if CV_MAJOR_VERSION < 3
743  cv::gpu::GpuMat imgGpu(imgRoi);
744  cv::gpu::GpuMat maskGpu(maskRoi);
745  (*_gpuSurf.obj)(imgGpu, maskGpu, keypoints);
746 #else
747  cv::cuda::GpuMat imgGpu(imgRoi);
748  cv::cuda::GpuMat maskGpu(maskRoi);
749  (*_gpuSurf.get())(imgGpu, maskGpu, keypoints);
750 #endif
751  }
752  else
753  {
754  _surf->detect(imgRoi, keypoints, maskRoi);
755  }
756 #else
757  UWARN("RTAB-Map is not built with OpenCV nonfree module so SURF cannot be used!");
758 #endif
759  return keypoints;
760 }
761 
762 cv::Mat SURF::generateDescriptorsImpl(const cv::Mat & image, std::vector<cv::KeyPoint> & keypoints) const
763 {
764  UASSERT(!image.empty() && image.channels() == 1 && image.depth() == CV_8U);
765  cv::Mat descriptors;
766 #ifdef RTABMAP_NONFREE
767  if(gpuVersion_)
768  {
769 #if CV_MAJOR_VERSION < 3
770  cv::gpu::GpuMat imgGpu(image);
771  cv::gpu::GpuMat descriptorsGPU;
772  (*_gpuSurf.obj)(imgGpu, cv::gpu::GpuMat(), keypoints, descriptorsGPU, true);
773 #else
774  cv::cuda::GpuMat imgGpu(image);
775  cv::cuda::GpuMat descriptorsGPU;
776  (*_gpuSurf.get())(imgGpu, cv::cuda::GpuMat(), keypoints, descriptorsGPU, true);
777 #endif
778 
779  // Download descriptors
780  if (descriptorsGPU.empty())
781  descriptors = cv::Mat();
782  else
783  {
784  UASSERT(descriptorsGPU.type() == CV_32F);
785  descriptors = cv::Mat(descriptorsGPU.size(), CV_32F);
786  descriptorsGPU.download(descriptors);
787  }
788  }
789  else
790  {
791  _surf->compute(image, keypoints, descriptors);
792  }
793 #else
794  UWARN("RTAB-Map is not built with OpenCV nonfree module so SURF cannot be used!");
795 #endif
796 
797  return descriptors;
798 }
799 
801 //SIFT
803 SIFT::SIFT(const ParametersMap & parameters) :
804  nOctaveLayers_(Parameters::defaultSIFTNOctaveLayers()),
805  contrastThreshold_(Parameters::defaultSIFTContrastThreshold()),
806  edgeThreshold_(Parameters::defaultSIFTEdgeThreshold()),
807  sigma_(Parameters::defaultSIFTSigma())
808 {
809  parseParameters(parameters);
810 }
811 
813 {
814 }
815 
816 void SIFT::parseParameters(const ParametersMap & parameters)
817 {
818  Feature2D::parseParameters(parameters);
819 
820  Parameters::parse(parameters, Parameters::kSIFTContrastThreshold(), contrastThreshold_);
821  Parameters::parse(parameters, Parameters::kSIFTEdgeThreshold(), edgeThreshold_);
822  Parameters::parse(parameters, Parameters::kSIFTNOctaveLayers(), nOctaveLayers_);
823  Parameters::parse(parameters, Parameters::kSIFTSigma(), sigma_);
824 
825 #ifdef RTABMAP_NONFREE
826 #if CV_MAJOR_VERSION < 3
828 #else
830 #endif
831 #else
832  UWARN("RTAB-Map is not built with OpenCV nonfree module so SIFT cannot be used!");
833 #endif
834 }
835 
836 std::vector<cv::KeyPoint> SIFT::generateKeypointsImpl(const cv::Mat & image, const cv::Rect & roi, const cv::Mat & mask) const
837 {
838  UASSERT(!image.empty() && image.channels() == 1 && image.depth() == CV_8U);
839  std::vector<cv::KeyPoint> keypoints;
840 #ifdef RTABMAP_NONFREE
841  cv::Mat imgRoi(image, roi);
842  cv::Mat maskRoi;
843  if(!mask.empty())
844  {
845  maskRoi = cv::Mat(mask, roi);
846  }
847  _sift->detect(imgRoi, keypoints, maskRoi); // Opencv keypoints
848 #else
849  UWARN("RTAB-Map is not built with OpenCV nonfree module so SIFT cannot be used!");
850 #endif
851  return keypoints;
852 }
853 
854 cv::Mat SIFT::generateDescriptorsImpl(const cv::Mat & image, std::vector<cv::KeyPoint> & keypoints) const
855 {
856  UASSERT(!image.empty() && image.channels() == 1 && image.depth() == CV_8U);
857  cv::Mat descriptors;
858 #ifdef RTABMAP_NONFREE
859  _sift->compute(image, keypoints, descriptors);
860 #else
861  UWARN("RTAB-Map is not built with OpenCV nonfree module so SIFT cannot be used!");
862 #endif
863  return descriptors;
864 }
865 
867 //ORB
869 ORB::ORB(const ParametersMap & parameters) :
870  scaleFactor_(Parameters::defaultORBScaleFactor()),
871  nLevels_(Parameters::defaultORBNLevels()),
872  edgeThreshold_(Parameters::defaultORBEdgeThreshold()),
873  firstLevel_(Parameters::defaultORBFirstLevel()),
874  WTA_K_(Parameters::defaultORBWTA_K()),
875  scoreType_(Parameters::defaultORBScoreType()),
876  patchSize_(Parameters::defaultORBPatchSize()),
877  gpu_(Parameters::defaultORBGpu()),
878  fastThreshold_(Parameters::defaultFASTThreshold()),
879  nonmaxSuppresion_(Parameters::defaultFASTNonmaxSuppression())
880 {
881  parseParameters(parameters);
882 }
883 
885 {
886 }
887 
888 void ORB::parseParameters(const ParametersMap & parameters)
889 {
890  Feature2D::parseParameters(parameters);
891 
892  Parameters::parse(parameters, Parameters::kORBScaleFactor(), scaleFactor_);
893  Parameters::parse(parameters, Parameters::kORBNLevels(), nLevels_);
894  Parameters::parse(parameters, Parameters::kORBEdgeThreshold(), edgeThreshold_);
895  Parameters::parse(parameters, Parameters::kORBFirstLevel(), firstLevel_);
896  Parameters::parse(parameters, Parameters::kORBWTA_K(), WTA_K_);
897  Parameters::parse(parameters, Parameters::kORBScoreType(), scoreType_);
898  Parameters::parse(parameters, Parameters::kORBPatchSize(), patchSize_);
899  Parameters::parse(parameters, Parameters::kORBGpu(), gpu_);
900 
901  Parameters::parse(parameters, Parameters::kFASTThreshold(), fastThreshold_);
902  Parameters::parse(parameters, Parameters::kFASTNonmaxSuppression(), nonmaxSuppresion_);
903 
904 #if CV_MAJOR_VERSION < 3
905 #ifdef HAVE_OPENCV_GPU
906  if(gpu_ && cv::gpu::getCudaEnabledDeviceCount() == 0)
907  {
908  UWARN("GPU version of ORB not available! Using CPU version instead...");
909  gpu_ = false;
910  }
911 #else
912  if(gpu_)
913  {
914  UWARN("GPU version of ORB not available (OpenCV not built with gpu/cuda module)! Using CPU version instead...");
915  gpu_ = false;
916  }
917 #endif
918 #else
919 #ifndef HAVE_OPENCV_CUDAFEATURES2D
920  if(gpu_)
921  {
922  UWARN("GPU version of ORB not available (OpenCV cudafeatures2d module)! Using CPU version instead...");
923  gpu_ = false;
924  }
925 #endif
926  if(gpu_ && cv::cuda::getCudaEnabledDeviceCount() == 0)
927  {
928  UWARN("GPU version of ORB not available (no GPU found)! Using CPU version instead...");
929  gpu_ = false;
930  }
931 #endif
932  if(gpu_)
933  {
934 #if CV_MAJOR_VERSION < 3
935 #ifdef HAVE_OPENCV_GPU
937  _gpuOrb->setFastParams(fastThreshold_, nonmaxSuppresion_);
938 #else
939  UFATAL("not supposed to be here");
940 #endif
941 #else
942 #ifdef HAVE_OPENCV_CUDAFEATURES2D
944 #endif
945 #endif
946  }
947  else
948  {
949 #if CV_MAJOR_VERSION < 3
950  _orb = cv::Ptr<CV_ORB>(new CV_ORB(this->getMaxFeatures(), scaleFactor_, nLevels_, edgeThreshold_, firstLevel_, WTA_K_, scoreType_, patchSize_, parameters));
951 #else
953 #endif
954  }
955 }
956 
957 std::vector<cv::KeyPoint> ORB::generateKeypointsImpl(const cv::Mat & image, const cv::Rect & roi, const cv::Mat & mask) const
958 {
959  UASSERT(!image.empty() && image.channels() == 1 && image.depth() == CV_8U);
960  std::vector<cv::KeyPoint> keypoints;
961  cv::Mat imgRoi(image, roi);
962  cv::Mat maskRoi;
963  if(!mask.empty())
964  {
965  maskRoi = cv::Mat(mask, roi);
966  }
967 
968  if(gpu_)
969  {
970 #if CV_MAJOR_VERSION < 3
971 #ifdef HAVE_OPENCV_GPU
972  cv::gpu::GpuMat imgGpu(imgRoi);
973  cv::gpu::GpuMat maskGpu(maskRoi);
974  (*_gpuOrb.obj)(imgGpu, maskGpu, keypoints);
975 #else
976  UERROR("Cannot use ORBGPU because OpenCV is not built with gpu module.");
977 #endif
978 #else
979 #ifdef HAVE_OPENCV_CUDAFEATURES2D
980  cv::cuda::GpuMat d_image(imgRoi);
981  cv::cuda::GpuMat d_mask(maskRoi);
982  try {
983  _gpuOrb->detectAndCompute(d_image, d_mask, keypoints, cv::cuda::GpuMat(), false);
984  } catch (cv::Exception& e) {
985  const char* err_msg = e.what();
986  UWARN("OpenCV exception caught: %s", err_msg);
987  }
988 #endif
989 #endif
990  }
991  else
992  {
993  _orb->detect(imgRoi, keypoints, maskRoi);
994  }
995 
996  return keypoints;
997 }
998 
999 cv::Mat ORB::generateDescriptorsImpl(const cv::Mat & image, std::vector<cv::KeyPoint> & keypoints) const
1000 {
1001  UASSERT(!image.empty() && image.channels() == 1 && image.depth() == CV_8U);
1002  cv::Mat descriptors;
1003  if(image.empty())
1004  {
1005  ULOGGER_ERROR("Image is null ?!?");
1006  return descriptors;
1007  }
1008  if(gpu_)
1009  {
1010 #if CV_MAJOR_VERSION < 3
1011 #ifdef HAVE_OPENCV_GPU
1012  cv::gpu::GpuMat imgGpu(image);
1013  cv::gpu::GpuMat descriptorsGPU;
1014  (*_gpuOrb.obj)(imgGpu, cv::gpu::GpuMat(), keypoints, descriptorsGPU);
1015  // Download descriptors
1016  if (descriptorsGPU.empty())
1017  descriptors = cv::Mat();
1018  else
1019  {
1020  UASSERT(descriptorsGPU.type() == CV_32F);
1021  descriptors = cv::Mat(descriptorsGPU.size(), CV_32F);
1022  descriptorsGPU.download(descriptors);
1023  }
1024 #else
1025  UERROR("GPU version of ORB not available (OpenCV not built with gpu/cuda module)! Using CPU version instead...");
1026 #endif
1027 #else
1028 #ifdef HAVE_OPENCV_CUDAFEATURES2D
1029  cv::cuda::GpuMat d_image(image);
1030  cv::cuda::GpuMat d_descriptors;
1031  try {
1032  _gpuOrb->detectAndCompute(d_image, cv::cuda::GpuMat(), keypoints, d_descriptors, true);
1033  } catch (cv::Exception& e) {
1034  const char* err_msg = e.what();
1035  UWARN("OpenCV exception caught: %s", err_msg);
1036  }
1037  // Download descriptors
1038  if (d_descriptors.empty())
1039  descriptors = cv::Mat();
1040  else
1041  {
1042  UASSERT(d_descriptors.type() == CV_32F || d_descriptors.type() == CV_8U);
1043  d_descriptors.download(descriptors);
1044  }
1045 #endif
1046 #endif
1047  }
1048  else
1049  {
1050  _orb->compute(image, keypoints, descriptors);
1051  }
1052 
1053  return descriptors;
1054 }
1055 
1057 //FAST
1059 FAST::FAST(const ParametersMap & parameters) :
1060  threshold_(Parameters::defaultFASTThreshold()),
1061  nonmaxSuppression_(Parameters::defaultFASTNonmaxSuppression()),
1062  gpu_(Parameters::defaultFASTGpu()),
1063  gpuKeypointsRatio_(Parameters::defaultFASTGpuKeypointsRatio()),
1064  minThreshold_(Parameters::defaultFASTMinThreshold()),
1065  maxThreshold_(Parameters::defaultFASTMaxThreshold()),
1066  gridRows_(Parameters::defaultFASTGridRows()),
1067  gridCols_(Parameters::defaultFASTGridCols())
1068 {
1069  parseParameters(parameters);
1070 }
1071 
1073 {
1074 }
1075 
1076 void FAST::parseParameters(const ParametersMap & parameters)
1077 {
1078  Feature2D::parseParameters(parameters);
1079 
1080  Parameters::parse(parameters, Parameters::kFASTThreshold(), threshold_);
1081  Parameters::parse(parameters, Parameters::kFASTNonmaxSuppression(), nonmaxSuppression_);
1082  Parameters::parse(parameters, Parameters::kFASTGpu(), gpu_);
1083  Parameters::parse(parameters, Parameters::kFASTGpuKeypointsRatio(), gpuKeypointsRatio_);
1084 
1085  Parameters::parse(parameters, Parameters::kFASTMinThreshold(), minThreshold_);
1086  Parameters::parse(parameters, Parameters::kFASTMaxThreshold(), maxThreshold_);
1087  Parameters::parse(parameters, Parameters::kFASTGridRows(), gridRows_);
1088  Parameters::parse(parameters, Parameters::kFASTGridCols(), gridCols_);
1089 
1092 
1093 #if CV_MAJOR_VERSION < 3
1094 #ifdef HAVE_OPENCV_GPU
1095  if(gpu_ && cv::gpu::getCudaEnabledDeviceCount() == 0)
1096  {
1097  UWARN("GPU version of FAST not available! Using CPU version instead...");
1098  gpu_ = false;
1099  }
1100 #else
1101  if(gpu_)
1102  {
1103  UWARN("GPU version of FAST not available (OpenCV not built with gpu/cuda module)! Using CPU version instead...");
1104  gpu_ = false;
1105  }
1106 #endif
1107 #else
1108 #ifdef HAVE_OPENCV_CUDAFEATURES2D
1109  if(gpu_ && cv::cuda::getCudaEnabledDeviceCount() == 0)
1110  {
1111  UWARN("GPU version of FAST not available! Using CPU version instead...");
1112  gpu_ = false;
1113  }
1114 #else
1115  if(gpu_)
1116  {
1117  UWARN("GPU version of FAST not available (OpenCV cudafeatures2d module)! Using CPU version instead...");
1118  gpu_ = false;
1119  }
1120 #endif
1121 #endif
1122  if(gpu_)
1123  {
1124 #if CV_MAJOR_VERSION < 3
1125 #ifdef HAVE_OPENCV_GPU
1127 #else
1128  UFATAL("not supposed to be here!");
1129 #endif
1130 #else
1131 #ifdef HAVE_OPENCV_CUDAFEATURES2D
1132  UFATAL("not implemented");
1133 #endif
1134 #endif
1135  }
1136  else
1137  {
1138 #if CV_MAJOR_VERSION < 3
1139  if(gridRows_ > 0 && gridCols_ > 0)
1140  {
1141  UDEBUG("grid max features = %d", this->getMaxFeatures());
1142  cv::Ptr<cv::FeatureDetector> fastAdjuster = cv::Ptr<cv::FastAdjuster>(new cv::FastAdjuster(threshold_, nonmaxSuppression_, minThreshold_, maxThreshold_));
1143  _fast = cv::Ptr<cv::FeatureDetector>(new cv::GridAdaptedFeatureDetector(fastAdjuster, this->getMaxFeatures(), gridRows_, gridCols_));
1144  }
1145  else
1146  {
1147  if(gridRows_ > 0)
1148  {
1149  UWARN("Parameter \"%s\" is set (value=%d) but not \"%s\"! Grid adaptor will not be added.",
1150  Parameters::kFASTGridRows().c_str(), gridRows_, Parameters::kFASTGridCols().c_str());
1151  }
1152  else if(gridCols_ > 0)
1153  {
1154  UWARN("Parameter \"%s\" is set (value=%d) but not \"%s\"! Grid adaptor will not be added.",
1155  Parameters::kFASTGridCols().c_str(), gridCols_, Parameters::kFASTGridRows().c_str());
1156  }
1157  _fast = cv::Ptr<cv::FeatureDetector>(new CV_FAST(threshold_, nonmaxSuppression_));
1158  }
1159 #else
1160  _fast = CV_FAST::create(threshold_, nonmaxSuppression_);
1161 #endif
1162  }
1163 }
1164 
1165 std::vector<cv::KeyPoint> FAST::generateKeypointsImpl(const cv::Mat & image, const cv::Rect & roi, const cv::Mat & mask) const
1166 {
1167  UASSERT(!image.empty() && image.channels() == 1 && image.depth() == CV_8U);
1168  std::vector<cv::KeyPoint> keypoints;
1169  cv::Mat imgRoi(image, roi);
1170  cv::Mat maskRoi;
1171  if(!mask.empty())
1172  {
1173  maskRoi = cv::Mat(mask, roi);
1174  }
1175  if(gpu_)
1176  {
1177 #if CV_MAJOR_VERSION < 3
1178 #ifdef HAVE_OPENCV_GPU
1179  cv::gpu::GpuMat imgGpu(imgRoi);
1180  cv::gpu::GpuMat maskGpu(maskRoi);
1181  (*_gpuFast.obj)(imgGpu, maskGpu, keypoints);
1182 #else
1183  UERROR("Cannot use FAST GPU because OpenCV is not built with gpu module.");
1184 #endif
1185 #else
1186 #ifdef HAVE_OPENCV_CUDAFEATURES2D
1187  UFATAL("not implemented");
1188 #endif
1189 #endif
1190  }
1191  else
1192  {
1193  _fast->detect(imgRoi, keypoints, maskRoi); // Opencv keypoints
1194  }
1195  return keypoints;
1196 }
1197 
1199 //FAST-BRIEF
1202  FAST(parameters),
1203  bytes_(Parameters::defaultBRIEFBytes())
1204 {
1205  parseParameters(parameters);
1206 }
1207 
1209 {
1210 }
1211 
1213 {
1214  FAST::parseParameters(parameters);
1215 
1216  Parameters::parse(parameters, Parameters::kBRIEFBytes(), bytes_);
1217 #if CV_MAJOR_VERSION < 3
1218  _brief = cv::Ptr<CV_BRIEF>(new CV_BRIEF(bytes_));
1219 #else
1220 #ifdef HAVE_OPENCV_XFEATURES2D
1221  _brief = CV_BRIEF::create(bytes_);
1222 #else
1223  UWARN("RTAB-Map is not built with OpenCV xfeatures2d module so Brief cannot be used!");
1224 #endif
1225 #endif
1226 }
1227 
1228 cv::Mat FAST_BRIEF::generateDescriptorsImpl(const cv::Mat & image, std::vector<cv::KeyPoint> & keypoints) const
1229 {
1230  UASSERT(!image.empty() && image.channels() == 1 && image.depth() == CV_8U);
1231  cv::Mat descriptors;
1232 #if CV_MAJOR_VERSION < 3
1233  _brief->compute(image, keypoints, descriptors);
1234 #else
1235 #ifdef HAVE_OPENCV_XFEATURES2D
1236  _brief->compute(image, keypoints, descriptors);
1237 #else
1238  UWARN("RTAB-Map is not built with OpenCV xfeatures2d module so Brief cannot be used!");
1239 #endif
1240 #endif
1241  return descriptors;
1242 }
1243 
1245 //FAST-FREAK
1248  FAST(parameters),
1249  orientationNormalized_(Parameters::defaultFREAKOrientationNormalized()),
1250  scaleNormalized_(Parameters::defaultFREAKScaleNormalized()),
1251  patternScale_(Parameters::defaultFREAKPatternScale()),
1252  nOctaves_(Parameters::defaultFREAKNOctaves())
1253 {
1254  parseParameters(parameters);
1255 }
1256 
1258 {
1259 }
1260 
1262 {
1263  FAST::parseParameters(parameters);
1264 
1265  Parameters::parse(parameters, Parameters::kFREAKOrientationNormalized(), orientationNormalized_);
1266  Parameters::parse(parameters, Parameters::kFREAKScaleNormalized(), scaleNormalized_);
1267  Parameters::parse(parameters, Parameters::kFREAKPatternScale(), patternScale_);
1268  Parameters::parse(parameters, Parameters::kFREAKNOctaves(), nOctaves_);
1269 
1270 #if CV_MAJOR_VERSION < 3
1272 #else
1273 #ifdef HAVE_OPENCV_XFEATURES2D
1275 #else
1276  UWARN("RTAB-Map is not built with OpenCV xfeatures2d module so Freak cannot be used!");
1277 #endif
1278 #endif
1279 }
1280 
1281 cv::Mat FAST_FREAK::generateDescriptorsImpl(const cv::Mat & image, std::vector<cv::KeyPoint> & keypoints) const
1282 {
1283  UASSERT(!image.empty() && image.channels() == 1 && image.depth() == CV_8U);
1284  cv::Mat descriptors;
1285 #if CV_MAJOR_VERSION < 3
1286  _freak->compute(image, keypoints, descriptors);
1287 #else
1288 #ifdef HAVE_OPENCV_XFEATURES2D
1289  _freak->compute(image, keypoints, descriptors);
1290 #else
1291  UWARN("RTAB-Map is not built with OpenCV xfeatures2d module so Freak cannot be used!");
1292 #endif
1293 #endif
1294  return descriptors;
1295 }
1296 
1298 //GFTT
1300 GFTT::GFTT(const ParametersMap & parameters) :
1301  _qualityLevel(Parameters::defaultGFTTQualityLevel()),
1302  _minDistance(Parameters::defaultGFTTMinDistance()),
1303  _blockSize(Parameters::defaultGFTTBlockSize()),
1304  _useHarrisDetector(Parameters::defaultGFTTUseHarrisDetector()),
1305  _k(Parameters::defaultGFTTK())
1306 {
1307  parseParameters(parameters);
1308 }
1309 
1311 {
1312 }
1313 
1314 void GFTT::parseParameters(const ParametersMap & parameters)
1315 {
1316  Feature2D::parseParameters(parameters);
1317 
1318  Parameters::parse(parameters, Parameters::kGFTTQualityLevel(), _qualityLevel);
1319  Parameters::parse(parameters, Parameters::kGFTTMinDistance(), _minDistance);
1320  Parameters::parse(parameters, Parameters::kGFTTBlockSize(), _blockSize);
1321  Parameters::parse(parameters, Parameters::kGFTTUseHarrisDetector(), _useHarrisDetector);
1322  Parameters::parse(parameters, Parameters::kGFTTK(), _k);
1323 
1324 #if CV_MAJOR_VERSION < 3
1325  _gftt = cv::Ptr<CV_GFTT>(new CV_GFTT(this->getMaxFeatures(), _qualityLevel, _minDistance, _blockSize, _useHarrisDetector ,_k));
1326 #else
1328 #endif
1329 }
1330 
1331 std::vector<cv::KeyPoint> GFTT::generateKeypointsImpl(const cv::Mat & image, const cv::Rect & roi, const cv::Mat & mask) const
1332 {
1333  UASSERT(!image.empty() && image.channels() == 1 && image.depth() == CV_8U);
1334  std::vector<cv::KeyPoint> keypoints;
1335  cv::Mat imgRoi(image, roi);
1336  cv::Mat maskRoi;
1337  if(!mask.empty())
1338  {
1339  maskRoi = cv::Mat(mask, roi);
1340  }
1341  _gftt->detect(imgRoi, keypoints, maskRoi); // Opencv keypoints
1342  return keypoints;
1343 }
1344 
1346 //FAST-BRIEF
1349  GFTT(parameters),
1350  bytes_(Parameters::defaultBRIEFBytes())
1351 {
1352  parseParameters(parameters);
1353 }
1354 
1356 {
1357 }
1358 
1360 {
1361  GFTT::parseParameters(parameters);
1362 
1363  Parameters::parse(parameters, Parameters::kBRIEFBytes(), bytes_);
1364 #if CV_MAJOR_VERSION < 3
1365  _brief = cv::Ptr<CV_BRIEF>(new CV_BRIEF(bytes_));
1366 #else
1367 #ifdef HAVE_OPENCV_XFEATURES2D
1368  _brief = CV_BRIEF::create(bytes_);
1369 #else
1370  UWARN("RTAB-Map is not built with OpenCV xfeatures2d module so Brief cannot be used!");
1371 #endif
1372 #endif
1373 }
1374 
1375 cv::Mat GFTT_BRIEF::generateDescriptorsImpl(const cv::Mat & image, std::vector<cv::KeyPoint> & keypoints) const
1376 {
1377  UASSERT(!image.empty() && image.channels() == 1 && image.depth() == CV_8U);
1378  cv::Mat descriptors;
1379 #if CV_MAJOR_VERSION < 3
1380  _brief->compute(image, keypoints, descriptors);
1381 #else
1382 #ifdef HAVE_OPENCV_XFEATURES2D
1383  _brief->compute(image, keypoints, descriptors);
1384 #else
1385  UWARN("RTAB-Map is not built with OpenCV xfeatures2d module so Brief cannot be used!");
1386 #endif
1387 #endif
1388  return descriptors;
1389 }
1390 
1392 //GFTT-FREAK
1395  GFTT(parameters),
1396  orientationNormalized_(Parameters::defaultFREAKOrientationNormalized()),
1397  scaleNormalized_(Parameters::defaultFREAKScaleNormalized()),
1398  patternScale_(Parameters::defaultFREAKPatternScale()),
1399  nOctaves_(Parameters::defaultFREAKNOctaves())
1400 {
1401  parseParameters(parameters);
1402 }
1403 
1405 {
1406 }
1407 
1409 {
1410  GFTT::parseParameters(parameters);
1411 
1412  Parameters::parse(parameters, Parameters::kFREAKOrientationNormalized(), orientationNormalized_);
1413  Parameters::parse(parameters, Parameters::kFREAKScaleNormalized(), scaleNormalized_);
1414  Parameters::parse(parameters, Parameters::kFREAKPatternScale(), patternScale_);
1415  Parameters::parse(parameters, Parameters::kFREAKNOctaves(), nOctaves_);
1416 
1417 #if CV_MAJOR_VERSION < 3
1419 #else
1420 #ifdef HAVE_OPENCV_XFEATURES2D
1422 #else
1423  UWARN("RTAB-Map is not built with OpenCV xfeatures2d module so Freak cannot be used!");
1424 #endif
1425 #endif
1426 }
1427 
1428 cv::Mat GFTT_FREAK::generateDescriptorsImpl(const cv::Mat & image, std::vector<cv::KeyPoint> & keypoints) const
1429 {
1430  UASSERT(!image.empty() && image.channels() == 1 && image.depth() == CV_8U);
1431  cv::Mat descriptors;
1432 #if CV_MAJOR_VERSION < 3
1433  _freak->compute(image, keypoints, descriptors);
1434 #else
1435 #ifdef HAVE_OPENCV_XFEATURES2D
1436  _freak->compute(image, keypoints, descriptors);
1437 #else
1438  UWARN("RTAB-Map is not built with OpenCV xfeatures2d module so Freak cannot be used!");
1439 #endif
1440 #endif
1441  return descriptors;
1442 }
1443 
1445 //GFTT-ORB
1447 GFTT_ORB::GFTT_ORB(const ParametersMap & parameters) :
1448  GFTT(parameters),
1449  _orb(parameters)
1450 {
1451  parseParameters(parameters);
1452 }
1453 
1455 {
1456 }
1457 
1459 {
1460  GFTT::parseParameters(parameters);
1461  _orb.parseParameters(parameters);
1462 }
1463 
1464 cv::Mat GFTT_ORB::generateDescriptorsImpl(const cv::Mat & image, std::vector<cv::KeyPoint> & keypoints) const
1465 {
1466  UASSERT(!image.empty() && image.channels() == 1 && image.depth() == CV_8U);
1467  return _orb.generateDescriptors(image, keypoints);
1468 }
1469 
1471 //BRISK
1473 BRISK::BRISK(const ParametersMap & parameters) :
1474  thresh_(Parameters::defaultBRISKThresh()),
1475  octaves_(Parameters::defaultBRISKOctaves()),
1476  patternScale_(Parameters::defaultBRISKPatternScale())
1477 {
1478  parseParameters(parameters);
1479 }
1480 
1482 {
1483 }
1484 
1485 void BRISK::parseParameters(const ParametersMap & parameters)
1486 {
1487  Feature2D::parseParameters(parameters);
1488 
1489  Parameters::parse(parameters, Parameters::kBRISKThresh(), thresh_);
1490  Parameters::parse(parameters, Parameters::kBRISKOctaves(), octaves_);
1491  Parameters::parse(parameters, Parameters::kBRISKPatternScale(), patternScale_);
1492 
1493 #if CV_MAJOR_VERSION < 3
1494  brisk_ = cv::Ptr<CV_BRISK>(new CV_BRISK(thresh_, octaves_, patternScale_));
1495 #else
1496  brisk_ = CV_BRISK::create(thresh_, octaves_, patternScale_);
1497 #endif
1498 }
1499 
1500 std::vector<cv::KeyPoint> BRISK::generateKeypointsImpl(const cv::Mat & image, const cv::Rect & roi, const cv::Mat & mask) const
1501 {
1502  UASSERT(!image.empty() && image.channels() == 1 && image.depth() == CV_8U);
1503  std::vector<cv::KeyPoint> keypoints;
1504  cv::Mat imgRoi(image, roi);
1505  cv::Mat maskRoi;
1506  if(!mask.empty())
1507  {
1508  maskRoi = cv::Mat(mask, roi);
1509  }
1510  brisk_->detect(imgRoi, keypoints, maskRoi); // Opencv keypoints
1511  return keypoints;
1512 }
1513 
1514 cv::Mat BRISK::generateDescriptorsImpl(const cv::Mat & image, std::vector<cv::KeyPoint> & keypoints) const
1515 {
1516  UASSERT(!image.empty() && image.channels() == 1 && image.depth() == CV_8U);
1517  cv::Mat descriptors;
1518  brisk_->compute(image, keypoints, descriptors);
1519  return descriptors;
1520 }
1521 
1523 //KAZE
1525 KAZE::KAZE(const ParametersMap & parameters) :
1526  extended_(Parameters::defaultKAZEExtended()),
1527  upright_(Parameters::defaultKAZEUpright()),
1528  threshold_(Parameters::defaultKAZEThreshold()),
1529  nOctaves_(Parameters::defaultKAZENOctaves()),
1530  nOctaveLayers_(Parameters::defaultKAZENOctaveLayers()),
1531  diffusivity_(Parameters::defaultKAZEDiffusivity())
1532 {
1533  parseParameters(parameters);
1534 }
1535 
1537 {
1538 }
1539 
1540 void KAZE::parseParameters(const ParametersMap & parameters)
1541 {
1542  Feature2D::parseParameters(parameters);
1543 
1544  Parameters::parse(parameters, Parameters::kKAZEExtended(), extended_);
1545  Parameters::parse(parameters, Parameters::kKAZEUpright(), upright_);
1546  Parameters::parse(parameters, Parameters::kKAZEThreshold(), threshold_);
1547  Parameters::parse(parameters, Parameters::kKAZENOctaves(), nOctaves_);
1548  Parameters::parse(parameters, Parameters::kKAZENOctaveLayers(), nOctaveLayers_);
1549  Parameters::parse(parameters, Parameters::kKAZEDiffusivity(), diffusivity_);
1550 
1551 #if CV_MAJOR_VERSION > 2
1552  kaze_ = cv::KAZE::create(extended_, upright_, threshold_, nOctaves_, nOctaveLayers_, diffusivity_);
1553 #else
1554  UWARN("RTAB-Map is not built with OpenCV3 so Kaze feature cannot be used!");
1555 #endif
1556 }
1557 
1558 std::vector<cv::KeyPoint> KAZE::generateKeypointsImpl(const cv::Mat & image, const cv::Rect & roi, const cv::Mat & mask) const
1559 {
1560  UASSERT(!image.empty() && image.channels() == 1 && image.depth() == CV_8U);
1561  std::vector<cv::KeyPoint> keypoints;
1562 #if CV_MAJOR_VERSION > 2
1563  cv::Mat imgRoi(image, roi);
1564  cv::Mat maskRoi;
1565  if (!mask.empty())
1566  {
1567  maskRoi = cv::Mat(mask, roi);
1568  }
1569  kaze_->detect(imgRoi, keypoints, maskRoi); // Opencv keypoints
1570 #else
1571  UWARN("RTAB-Map is not built with OpenCV3 so Kaze feature cannot be used!");
1572 #endif
1573  return keypoints;
1574 }
1575 
1576 cv::Mat KAZE::generateDescriptorsImpl(const cv::Mat & image, std::vector<cv::KeyPoint> & keypoints) const
1577 {
1578  UASSERT(!image.empty() && image.channels() == 1 && image.depth() == CV_8U);
1579  cv::Mat descriptors;
1580 #if CV_MAJOR_VERSION > 2
1581  kaze_->compute(image, keypoints, descriptors);
1582 #else
1583  UWARN("RTAB-Map is not built with OpenCV3 so Kaze feature cannot be used!");
1584 #endif
1585  return descriptors;
1586 }
1587 
1588 }
virtual std::vector< cv::KeyPoint > generateKeypointsImpl(const cv::Mat &image, const cv::Rect &roi, const cv::Mat &mask=cv::Mat()) const
d
GLM_FUNC_DECL genIType mask(genIType const &count)
static bool parse(const ParametersMap &parameters, const std::string &key, bool &value)
Definition: Parameters.cpp:446
virtual cv::Mat generateDescriptorsImpl(const cv::Mat &image, std::vector< cv::KeyPoint > &keypoints) const
virtual ~BRISK()
virtual cv::Mat generateDescriptorsImpl(const cv::Mat &image, std::vector< cv::KeyPoint > &keypoints) const =0
int nOctaveLayers_
Definition: Features2d.h:457
virtual void parseParameters(const ParametersMap &parameters)
Definition: UTimer.h:46
static void limitKeypoints(std::vector< cv::KeyPoint > &keypoints, int maxKeypoints)
Definition: Features2d.cpp:205
virtual std::vector< cv::KeyPoint > generateKeypointsImpl(const cv::Mat &image, const cv::Rect &roi, const cv::Mat &mask=cv::Mat()) const
Definition: Features2d.cpp:957
virtual ~SIFT()
Definition: Features2d.cpp:812
std::vector< cv::Point3f > generateKeypoints3D(const SensorData &data, const std::vector< cv::KeyPoint > &keypoints) const
Definition: Features2d.cpp:612
double gpuKeypointsRatio_
Definition: Features2d.h:285
FAST_BRIEF(const ParametersMap &parameters=ParametersMap())
virtual void parseParameters(const ParametersMap &parameters)
f
cv::Mat generateDescriptors(const cv::Mat &image, std::vector< cv::KeyPoint > &keypoints) const
Definition: Features2d.cpp:596
virtual void parseParameters(const ParametersMap &parameters)
Definition: Features2d.cpp:341
double _qualityLevel
Definition: Features2d.h:349
cv::Ptr< CV_FREAK > _freak
Definition: Features2d.h:333
GFTT_FREAK(const ParametersMap &parameters=ParametersMap())
cv::SIFT CV_SIFT
Definition: Features2d.h:50
double edgeThreshold_
Definition: Features2d.h:230
virtual cv::Mat generateDescriptorsImpl(const cv::Mat &image, std::vector< cv::KeyPoint > &keypoints) const
Definition: Features2d.cpp:999
virtual void parseParameters(const ParametersMap &parameters)
Definition: Features2d.cpp:685
cv::Ptr< CV_ORB > _orb
Definition: Features2d.h:263
virtual void parseParameters(const ParametersMap &parameters)
Definition: Features2d.cpp:888
cv::Ptr< CV_FREAK > _freak
Definition: Features2d.h:396
float scaleFactor_
Definition: Features2d.h:251
std::vector< cv::KeyPoint > generateKeypoints(const cv::Mat &image, const cv::Mat &mask=cv::Mat()) const
Definition: Features2d.cpp:497
cv::BriefDescriptorExtractor CV_BRIEF
Definition: Features2d.h:55
virtual cv::Mat generateDescriptorsImpl(const cv::Mat &image, std::vector< cv::KeyPoint > &keypoints) const
GLM_FUNC_DECL genType e()
virtual ~SURF()
Definition: Features2d.cpp:681
float UTILITE_EXP uStr2Float(const std::string &str)
virtual cv::Mat generateDescriptorsImpl(const cv::Mat &image, std::vector< cv::KeyPoint > &keypoints) const
Definition: Features2d.cpp:762
bool nonmaxSuppression_
Definition: Features2d.h:283
virtual std::vector< cv::KeyPoint > generateKeypointsImpl(const cv::Mat &image, const cv::Rect &roi, const cv::Mat &mask=cv::Mat()) const
std::map< std::string, std::string > ParametersMap
Definition: Parameters.h:41
double contrastThreshold_
Definition: Features2d.h:229
virtual std::vector< cv::KeyPoint > generateKeypointsImpl(const cv::Mat &image, const cv::Rect &roi, const cv::Mat &mask=cv::Mat()) const
Definition: Features2d.cpp:836
std::vector< float > _roiRatios
Definition: Features2d.h:176
int nOctaveLayers_
Definition: Features2d.h:228
Basic mathematics functions.
cv::Ptr< CV_BRISK > brisk_
Definition: Features2d.h:435
cv::Ptr< CV_ORB_GPU > _gpuOrb
Definition: Features2d.h:264
Some conversion functions.
cv::FastFeatureDetector CV_FAST
Definition: Features2d.h:52
const cv::Mat & imageRaw() const
Definition: SensorData.h:161
virtual std::vector< cv::KeyPoint > generateKeypointsImpl(const cv::Mat &image, const cv::Rect &roi, const cv::Mat &mask=cv::Mat()) const
Definition: Features2d.cpp:728
virtual ~Feature2D()
Definition: Features2d.cpp:337
Feature2D(const ParametersMap &parameters=ParametersMap())
Definition: Features2d.cpp:323
virtual cv::Mat generateDescriptorsImpl(const cv::Mat &image, std::vector< cv::KeyPoint > &keypoints) const
virtual cv::Mat generateDescriptorsImpl(const cv::Mat &image, std::vector< cv::KeyPoint > &keypoints) const
Definition: Features2d.cpp:854
detail::uint16 uint16_t
Definition: fwd.hpp:912
#define UFATAL(...)
int getMaxFeatures() const
Definition: Features2d.h:143
cv::Mat rightRaw() const
Definition: SensorData.h:173
cv::SURF CV_SURF
Definition: Features2d.h:51
std::list< std::string > uSplit(const std::string &str, char separator= ' ')
Definition: UStl.h:566
bool uIsFinite(const T &value)
Definition: UMath.h:55
cv::Ptr< CV_FAST_GPU > _gpuFast
Definition: Features2d.h:292
#define UASSERT(condition)
virtual void parseParameters(const ParametersMap &parameters)
Definition: Features2d.cpp:816
virtual ~ORB()
Definition: Features2d.cpp:884
Wrappers of STL for convenient functions.
static void filterKeypointsByDisparity(std::vector< cv::KeyPoint > &keypoints, const cv::Mat &disparity, float minDisparity)
Definition: Features2d.cpp:138
virtual std::vector< cv::Point2f > computeCorrespondences(const cv::Mat &leftImage, const cv::Mat &rightImage, const std::vector< cv::Point2f > &leftCorners, std::vector< unsigned char > &status) const
Definition: Stereo.cpp:72
BRISK(const ParametersMap &parameters=ParametersMap())
cv::BRISK CV_BRISK
Definition: Features2d.h:56
virtual ~FAST()
static Feature2D * create(const ParametersMap &parameters=ParametersMap())
Definition: Features2d.cpp:405
#define ULOGGER_DEBUG(...)
Definition: ULogger.h:53
virtual void parseParameters(const ParametersMap &parameters)
#define UASSERT_MSG(condition, msg_str)
Definition: ULogger.h:67
virtual ~GFTT()
cv::Rect RTABMAP_EXP computeRoi(const cv::Mat &image, const std::string &roiRatios)
Definition: util2d.cpp:1108
FAST(const ParametersMap &parameters=ParametersMap())
virtual void parseParameters(const ParametersMap &parameters)
virtual cv::Mat generateDescriptorsImpl(const cv::Mat &image, std::vector< cv::KeyPoint > &keypoints) const
virtual void parseParameters(const ParametersMap &parameters)
Definition: Stereo.cpp:61
static void filterKeypointsByDepth(std::vector< cv::KeyPoint > &keypoints, const cv::Mat &depth, float minDepth, float maxDepth)
Definition: Features2d.cpp:66
KAZE(const ParametersMap &parameters=ParametersMap())
const cv::Mat & depthOrRightRaw() const
Definition: SensorData.h:162
cv::gpu::SURF_GPU CV_SURF_GPU
Definition: Features2d.h:57
int fastThreshold_
Definition: Features2d.h:260
float patternScale_
Definition: Features2d.h:433
virtual std::vector< cv::KeyPoint > generateKeypointsImpl(const cv::Mat &image, const cv::Rect &roi, const cv::Mat &mask=cv::Mat()) const
static cv::Rect computeRoi(const cv::Mat &image, const std::string &roiRatios)
Definition: Features2d.cpp:310
virtual std::vector< cv::KeyPoint > generateKeypointsImpl(const cv::Mat &image, const cv::Rect &roi, const cv::Mat &mask=cv::Mat()) const =0
SIFT(const ParametersMap &parameters=ParametersMap())
Definition: Features2d.cpp:803
static Stereo * create(const ParametersMap &parameters=ParametersMap())
Definition: Stereo.cpp:35
double sigma_
Definition: Features2d.h:231
cv::Ptr< CV_BRIEF > _brief
Definition: Features2d.h:311
cv::Ptr< CV_SURF > _surf
Definition: Features2d.h:209
virtual ~KAZE()
const std::vector< CameraModel > & cameraModels() const
Definition: SensorData.h:193
FAST_FREAK(const ParametersMap &parameters=ParametersMap())
int nOctaveLayers_
Definition: Features2d.h:203
float gpuKeypointsRatio_
Definition: Features2d.h:206
cv::FREAK CV_FREAK
Definition: Features2d.h:53
#define UDEBUG(...)
GLM_FUNC_DECL genType max(genType const &x, genType const &y)
virtual void parseParameters(const ParametersMap &parameters)
virtual cv::Mat generateDescriptorsImpl(const cv::Mat &image, std::vector< cv::KeyPoint > &keypoints) const
ORB(const ParametersMap &parameters=ParametersMap())
Definition: Features2d.cpp:869
cv::Ptr< CV_BRIEF > _brief
Definition: Features2d.h:374
cv::Ptr< CV_SIFT > _sift
Definition: Features2d.h:233
#define UERROR(...)
virtual void parseParameters(const ParametersMap &parameters)
virtual cv::Mat generateDescriptorsImpl(const cv::Mat &image, std::vector< cv::KeyPoint > &keypoints) const
virtual void parseParameters(const ParametersMap &parameters)
GFTT(const ParametersMap &parameters=ParametersMap())
float threshold_
Definition: Features2d.h:455
ULogger class and convenient macros.
const StereoCameraModel & stereoCameraModel() const
Definition: SensorData.h:194
SURF(const ParametersMap &parameters=ParametersMap())
Definition: Features2d.cpp:669
#define UWARN(...)
virtual void parseParameters(const ParametersMap &parameters)
double ticks()
Definition: UTimer.cpp:110
double _minDistance
Definition: Features2d.h:350
virtual cv::Mat generateDescriptorsImpl(const cv::Mat &image, std::vector< cv::KeyPoint > &keypoints) const
bool gpuVersion_
Definition: Features2d.h:207
GFTT_BRIEF(const ParametersMap &parameters=ParametersMap())
virtual std::vector< cv::KeyPoint > generateKeypointsImpl(const cv::Mat &image, const cv::Rect &roi, const cv::Mat &mask=cv::Mat()) const
int edgeThreshold_
Definition: Features2d.h:253
cv::gpu::ORB_GPU CV_ORB_GPU
Definition: Features2d.h:58
GFTT_ORB(const ParametersMap &parameters=ParametersMap())
cv::GFTTDetector CV_GFTT
Definition: Features2d.h:54
cv::gpu::FAST_GPU CV_FAST_GPU
Definition: Features2d.h:59
#define ULOGGER_ERROR(...)
Definition: ULogger.h:56
bool nonmaxSuppresion_
Definition: Features2d.h:261
std::vector< cv::Point3f > RTABMAP_EXP generateKeypoints3DDepth(const std::vector< cv::KeyPoint > &keypoints, const cv::Mat &depth, const CameraModel &cameraModel, float minDepth=0, float maxDepth=0)
cv::Ptr< cv::FeatureDetector > _fast
Definition: Features2d.h:291
double hessianThreshold_
Definition: Features2d.h:201
std::string UTILITE_EXP uFormat(const char *fmt,...)
cv::Ptr< CV_GFTT > _gftt
Definition: Features2d.h:355
cv::Mat depthRaw() const
Definition: SensorData.h:172
ParametersMap parameters_
Definition: Features2d.h:172
void uInsert(std::map< K, V > &map, const std::pair< K, V > &pair)
Definition: UStl.h:443
virtual void parseParameters(const ParametersMap &parameters)
std::vector< cv::Point3f > RTABMAP_EXP generateKeypoints3DStereo(const std::vector< cv::Point2f > &leftCorners, const std::vector< cv::Point2f > &rightCorners, const StereoCameraModel &model, const std::vector< unsigned char > &mask=std::vector< unsigned char >(), float minDepth=0, float maxDepth=0)
bool _useHarrisDetector
Definition: Features2d.h:352
cv::Ptr< CV_SURF_GPU > _gpuSurf
Definition: Features2d.h:210


rtabmap
Author(s): Mathieu Labbe
autogenerated on Wed Jun 5 2019 22:41:31