Visual Servoing Platform  version 3.0.1
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
vpKeyPoint.h
1 /****************************************************************************
2  *
3  * This file is part of the ViSP software.
4  * Copyright (C) 2005 - 2017 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * ("GPL") version 2 as published by the Free Software Foundation.
9  * See the file LICENSE.txt at the root directory of this source
10  * distribution for additional information about the GNU GPL.
11  *
12  * For using ViSP with software that can not be combined with the GNU
13  * GPL, please contact Inria about acquiring a ViSP Professional
14  * Edition License.
15  *
16  * See http://visp.inria.fr for more information.
17  *
18  * This software was developed at:
19  * Inria Rennes - Bretagne Atlantique
20  * Campus Universitaire de Beaulieu
21  * 35042 Rennes Cedex
22  * France
23  *
24  * If you have questions regarding the use of this file, please contact
25  * Inria at visp@inria.fr
26  *
27  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29  *
30  * Description:
31  * Key point functionalities.
32  *
33  * Authors:
34  * Souriya Trinh
35  *
36  *****************************************************************************/
37 #ifndef __vpKeyPoint_h__
38 #define __vpKeyPoint_h__
39 
40 #include <algorithm> // std::transform
41 #include <vector> // std::vector
42 #include <stdlib.h> // srand, rand
43 #include <time.h> // time
44 #include <fstream> // std::ofstream
45 #include <numeric> // std::accumulate
46 #include <float.h> // DBL_MAX
47 #include <map> // std::map
48 #include <limits>
49 
50 #include <visp3/core/vpConfig.h>
51 #include <visp3/vision/vpBasicKeyPoint.h>
52 #include <visp3/core/vpImageConvert.h>
53 #include <visp3/core/vpPoint.h>
54 #include <visp3/core/vpDisplay.h>
55 #include <visp3/core/vpPlane.h>
56 #include <visp3/core/vpPixelMeterConversion.h>
57 #include <visp3/vision/vpPose.h>
58 #ifdef VISP_HAVE_MODULE_IO
59 # include <visp3/io/vpImageIo.h>
60 #endif
61 #include <visp3/core/vpPolygon.h>
62 #include <visp3/vision/vpXmlConfigParserKeyPoint.h>
63 #include <visp3/core/vpConvert.h>
64 #include <visp3/core/vpMeterPixelConversion.h>
65 #include <visp3/core/vpCylinder.h>
66 
67 // Require at least OpenCV >= 2.1.1
68 #if (VISP_HAVE_OPENCV_VERSION >= 0x020101)
69 
70 #include <opencv2/features2d/features2d.hpp>
71 #include <opencv2/calib3d/calib3d.hpp>
72 #include <opencv2/imgproc/imgproc.hpp>
73 
74 #if defined(VISP_HAVE_OPENCV_XFEATURES2D) // OpenCV >= 3.0.0
75 # include <opencv2/xfeatures2d.hpp>
76 #elif defined(VISP_HAVE_OPENCV_NONFREE) && (VISP_HAVE_OPENCV_VERSION >= 0x020400) && (VISP_HAVE_OPENCV_VERSION < 0x030000)
77 # include <opencv2/nonfree/nonfree.hpp>
78 #endif
79 
80 #ifdef VISP_HAVE_XML2
81 # include <libxml/xmlwriter.h>
82 #endif
83 
217 class VISP_EXPORT vpKeyPoint : public vpBasicKeyPoint {
218 
219 public:
220 
227  noFilterMatching
228  };
229 
233  detectionScore
235  };
236 
238  typedef enum {
242  pgmImageFormat
243  } vpImageFormatType;
244 
247 #if (VISP_HAVE_OPENCV_VERSION >= 0x020403)
254  #if (VISP_HAVE_OPENCV_VERSION < 0x030000) || (defined (VISP_HAVE_OPENCV_XFEATURES2D))
256  #endif
257  #if defined(VISP_HAVE_OPENCV_NONFREE) || defined (VISP_HAVE_OPENCV_XFEATURES2D)
260  #endif
261  #if (VISP_HAVE_OPENCV_VERSION >= 0x030000)
262  DETECTOR_KAZE,
263  DETECTOR_AKAZE,
264  DETECTOR_AGAST,
265  #endif
266  #if (VISP_HAVE_OPENCV_VERSION >= 0x030100) && defined (VISP_HAVE_OPENCV_XFEATURES2D)
267  DETECTOR_MSD,
268  #endif
269 #endif
270  DETECTOR_TYPE_SIZE
271  };
272 
275 #if (VISP_HAVE_OPENCV_VERSION >= 0x020403)
278  #if (VISP_HAVE_OPENCV_VERSION < 0x030000) || (defined (VISP_HAVE_OPENCV_XFEATURES2D))
281 #endif
282  #if defined(VISP_HAVE_OPENCV_NONFREE) || defined (VISP_HAVE_OPENCV_XFEATURES2D)
285  #endif
286  #if (VISP_HAVE_OPENCV_VERSION >= 0x030000)
287  DESCRIPTOR_KAZE,
288  DESCRIPTOR_AKAZE,
289  #if defined (VISP_HAVE_OPENCV_XFEATURES2D)
290  DESCRIPTOR_DAISY,
291  DESCRIPTOR_LATCH,
292  #endif
293  #endif
294  #if (VISP_HAVE_OPENCV_VERSION >= 0x030200) && defined (VISP_HAVE_OPENCV_XFEATURES2D)
295  DESCRIPTOR_VGG,
296  DESCRIPTOR_BoostDesc,
297  #endif
298 #endif
299  DESCRIPTOR_TYPE_SIZE
300  };
301 
302 
303  vpKeyPoint(const vpFeatureDetectorType &detectorType, const vpFeatureDescriptorType &descriptorType,
304  const std::string &matcherName, const vpFilterMatchingType &filterType=ratioDistanceThreshold);
305  vpKeyPoint(const std::string &detectorName="ORB", const std::string &extractorName="ORB",
306  const std::string &matcherName="BruteForce-Hamming", const vpFilterMatchingType &filterType=ratioDistanceThreshold);
307  vpKeyPoint(const std::vector<std::string> &detectorNames, const std::vector<std::string> &extractorNames,
308  const std::string &matcherName="BruteForce", const vpFilterMatchingType &filterType=ratioDistanceThreshold);
309 
310  unsigned int buildReference(const vpImage<unsigned char> &I);
311  unsigned int buildReference(const vpImage<unsigned char> &I,
312  const vpImagePoint &iP, const unsigned int height, const unsigned int width);
313  unsigned int buildReference(const vpImage<unsigned char> &I, const vpRect& rectangle);
314 
315  void buildReference(const vpImage<unsigned char> &I, std::vector<cv::KeyPoint> &trainKeyPoint,
316  std::vector<cv::Point3f> &points3f, const bool append=false, const int class_id=-1);
317  void buildReference(const vpImage<unsigned char> &I, const std::vector<cv::KeyPoint> &trainKeyPoint,
318  const cv::Mat &trainDescriptors, const std::vector<cv::Point3f> &points3f,
319  const bool append=false, const int class_id=-1);
320 
321  static void compute3D(const cv::KeyPoint &candidate, const std::vector<vpPoint> &roi,
322  const vpCameraParameters &cam, const vpHomogeneousMatrix &cMo, cv::Point3f &point);
323 
324  static void compute3D(const vpImagePoint &candidate, const std::vector<vpPoint> &roi,
325  const vpCameraParameters &cam, const vpHomogeneousMatrix &cMo, vpPoint &point);
326 
327  static void compute3DForPointsInPolygons(const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam,
328  std::vector<cv::KeyPoint> &candidates, const std::vector<vpPolygon> &polygons,
329  const std::vector<std::vector<vpPoint> > &roisPt, std::vector<cv::Point3f> &points, cv::Mat *descriptors=NULL);
330 
331  static void compute3DForPointsInPolygons(const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam,
332  std::vector<vpImagePoint> &candidates, const std::vector<vpPolygon> &polygons,
333  const std::vector<std::vector<vpPoint> > &roisPt, std::vector<vpPoint> &points, cv::Mat *descriptors=NULL);
334 
335  static void compute3DForPointsOnCylinders(const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam,
336  std::vector<cv::KeyPoint> &candidates, const std::vector<vpCylinder> &cylinders,
337  const std::vector<std::vector<std::vector<vpImagePoint> > > &vectorOfCylinderRois,
338  std::vector<cv::Point3f> &points, cv::Mat *descriptors=NULL);
339 
340  static void compute3DForPointsOnCylinders(const vpHomogeneousMatrix &cMo, const vpCameraParameters &cam,
341  std::vector<vpImagePoint> &candidates, const std::vector<vpCylinder> &cylinders,
342  const std::vector<std::vector<std::vector<vpImagePoint> > > &vectorOfCylinderRois,
343  std::vector<vpPoint> &points, cv::Mat *descriptors=NULL);
344 
345  bool computePose(const std::vector<cv::Point2f> &imagePoints, const std::vector<cv::Point3f> &objectPoints,
346  const vpCameraParameters &cam, vpHomogeneousMatrix &cMo, std::vector<int> &inlierIndex,
347  double &elapsedTime, bool (*func)(vpHomogeneousMatrix *)=NULL);
348 
349  bool computePose(const std::vector<vpPoint> &objectVpPoints, vpHomogeneousMatrix &cMo,
350  std::vector<vpPoint> &inliers, double &elapsedTime, bool (*func)(vpHomogeneousMatrix *)=NULL);
351 
352  bool computePose(const std::vector<vpPoint> &objectVpPoints, vpHomogeneousMatrix &cMo,
353  std::vector<vpPoint> &inliers, std::vector<unsigned int> &inlierIndex,
354  double &elapsedTime, bool (*func)(vpHomogeneousMatrix *)=NULL);
355 
356  void createImageMatching(vpImage<unsigned char> &IRef, vpImage<unsigned char> &ICurrent, vpImage<unsigned char> &IMatching);
357  void createImageMatching(vpImage<unsigned char> &ICurrent, vpImage<unsigned char> &IMatching);
358 
359  void detect(const vpImage<unsigned char> &I, std::vector<cv::KeyPoint> &keyPoints, const vpRect& rectangle=vpRect());
360  void detect(const cv::Mat &matImg, std::vector<cv::KeyPoint> &keyPoints, const cv::Mat &mask=cv::Mat());
361  void detect(const vpImage<unsigned char> &I, std::vector<cv::KeyPoint> &keyPoints, double &elapsedTime,
362  const vpRect& rectangle=vpRect());
363  void detect(const cv::Mat &matImg, std::vector<cv::KeyPoint> &keyPoints, double &elapsedTime,
364  const cv::Mat &mask=cv::Mat());
365 
366  void detectExtractAffine(const vpImage<unsigned char> &I, std::vector<std::vector<cv::KeyPoint> >& listOfKeypoints,
367  std::vector<cv::Mat>& listOfDescriptors,
368  std::vector<vpImage<unsigned char> > *listOfAffineI=NULL);
369 
370  void display(const vpImage<unsigned char> &IRef, const vpImage<unsigned char> &ICurrent, unsigned int size=3);
371  void display(const vpImage<unsigned char> &ICurrent, unsigned int size=3, const vpColor &color=vpColor::green);
372 
373  void displayMatching(const vpImage<unsigned char> &IRef, vpImage<unsigned char> &IMatching,
374  unsigned int crossSize, unsigned int lineThickness=1,
375  const vpColor &color=vpColor::green);
376  void displayMatching(const vpImage<unsigned char> &ICurrent, vpImage<unsigned char> &IMatching,
377  const std::vector<vpImagePoint> &ransacInliers=std::vector<vpImagePoint>(), unsigned int crossSize=3,
378  unsigned int lineThickness=1);
379 
380  void extract(const vpImage<unsigned char> &I, std::vector<cv::KeyPoint> &keyPoints, cv::Mat &descriptors, std::vector<cv::Point3f> *trainPoints=NULL);
381  void extract(const cv::Mat &matImg, std::vector<cv::KeyPoint> &keyPoints, cv::Mat &descriptors, std::vector<cv::Point3f> *trainPoints=NULL);
382  void extract(const vpImage<unsigned char> &I, std::vector<cv::KeyPoint> &keyPoints, cv::Mat &descriptors,
383  double &elapsedTime, std::vector<cv::Point3f> *trainPoints=NULL);
384  void extract(const cv::Mat &matImg, std::vector<cv::KeyPoint> &keyPoints, cv::Mat &descriptors,
385  double &elapsedTime, std::vector<cv::Point3f> *trainPoints=NULL);
386 
394  inline vpMatrix getCovarianceMatrix() const {
395  if(!m_computeCovariance) {
396  std::cout << "Warning : The covariance matrix has not been computed. See setCovarianceComputation() to do it." << std::endl;
397  return vpMatrix();
398  }
399 
400  if(m_computeCovariance && !m_useRansacVVS) {
401  std::cout << "Warning : The covariance matrix can only be computed with a Virtual Visual Servoing approach." << std::endl
402  << "Use setUseRansacVVS(true) to choose to use a pose estimation method based on a Virtual Visual Servoing approach."
403  << std::endl;
404  return vpMatrix();
405  }
406 
407  return m_covarianceMatrix;
408  }
409 
415  inline double getDetectionTime() const {
416  return m_detectionTime;
417  }
418 
425  inline cv::Ptr<cv::FeatureDetector> getDetector(const vpFeatureDetectorType &type) const {
426  std::map<vpFeatureDetectorType, std::string>::const_iterator it_name = m_mapOfDetectorNames.find(type);
427  if (it_name == m_mapOfDetectorNames.end()) {
428  std::cerr << "Internal problem with the feature type and the corresponding name!" << std::endl;
429  }
430 
431  std::map<std::string, cv::Ptr<cv::FeatureDetector> >::const_iterator findDetector = m_detectors.find(it_name->second);
432  if(findDetector != m_detectors.end()) {
433  return findDetector->second;
434  }
435 
436  std::cerr << "Cannot find: " << it_name->second << std::endl;
437  return cv::Ptr<cv::FeatureDetector>();
438  }
439 
446  inline cv::Ptr<cv::FeatureDetector> getDetector(const std::string &name) const {
447  std::map<std::string, cv::Ptr<cv::FeatureDetector> >::const_iterator findDetector = m_detectors.find(name);
448  if(findDetector != m_detectors.end()) {
449  return findDetector->second;
450  }
451 
452  std::cerr << "Cannot find: " << name << std::endl;
453  return cv::Ptr<cv::FeatureDetector>();
454  }
455 
459  inline std::map<vpFeatureDetectorType, std::string> getDetectorNames() const {
460  return m_mapOfDetectorNames;
461  }
462 
468  inline double getExtractionTime() const {
469  return m_extractionTime;
470  }
471 
478  inline cv::Ptr<cv::DescriptorExtractor> getExtractor(const vpFeatureDescriptorType &type) const {
479  std::map<vpFeatureDescriptorType, std::string>::const_iterator it_name = m_mapOfDescriptorNames.find(type);
480  if (it_name == m_mapOfDescriptorNames.end()) {
481  std::cerr << "Internal problem with the feature type and the corresponding name!" << std::endl;
482  }
483 
484  std::map<std::string, cv::Ptr<cv::DescriptorExtractor> >::const_iterator findExtractor = m_extractors.find(it_name->second);
485  if(findExtractor != m_extractors.end()) {
486  return findExtractor->second;
487  }
488 
489  std::cerr << "Cannot find: " << it_name->second << std::endl;
490  return cv::Ptr<cv::DescriptorExtractor>();
491  }
492 
499  inline cv::Ptr<cv::DescriptorExtractor> getExtractor(const std::string &name) const {
500  std::map<std::string, cv::Ptr<cv::DescriptorExtractor> >::const_iterator findExtractor = m_extractors.find(name);
501  if(findExtractor != m_extractors.end()) {
502  return findExtractor->second;
503  }
504 
505  std::cerr << "Cannot find: " << name << std::endl;
506  return cv::Ptr<cv::DescriptorExtractor>();
507  }
508 
512  inline std::map<vpFeatureDescriptorType, std::string> getExtractorNames() const {
513  return m_mapOfDescriptorNames;
514  }
515 
522  return m_imageFormat;
523  }
524 
530  inline double getMatchingTime() const {
531  return m_matchingTime;
532  }
533 
539  inline cv::Ptr<cv::DescriptorMatcher> getMatcher() const {
540  return m_matcher;
541  }
542 
548  inline std::vector<cv::DMatch> getMatches() const {
549  return m_filteredMatches;
550  }
551 
557  inline std::vector<std::pair<cv::KeyPoint, cv::KeyPoint> > getMatchQueryToTrainKeyPoints() const {
558  std::vector<std::pair<cv::KeyPoint, cv::KeyPoint> > matchQueryToTrainKeyPoints(m_filteredMatches.size());
559  for (size_t i = 0; i < m_filteredMatches.size(); i++) {
560  matchQueryToTrainKeyPoints.push_back(std::pair<cv::KeyPoint, cv::KeyPoint>(
561  m_queryFilteredKeyPoints[(size_t) m_filteredMatches[i].queryIdx],
562  m_trainKeyPoints[(size_t) m_filteredMatches[i].trainIdx]));
563  }
564  return matchQueryToTrainKeyPoints;
565  }
566 
572  inline unsigned int getNbImages() const {
573  return static_cast<unsigned int>(m_mapOfImages.size());
574  }
575 
576  void getObjectPoints(std::vector<cv::Point3f> &objectPoints) const;
577  void getObjectPoints(std::vector<vpPoint> &objectPoints) const;
578 
584  inline double getPoseTime() const {
585  return m_poseTime;
586  }
587 
593  inline cv::Mat getQueryDescriptors() const {
594  return m_queryDescriptors;
595  }
596 
597  void getQueryKeyPoints(std::vector<cv::KeyPoint> &keyPoints) const;
598  void getQueryKeyPoints(std::vector<vpImagePoint> &keyPoints) const;
599 
605  inline std::vector<vpImagePoint> getRansacInliers() const {
606  return m_ransacInliers;
607  }
608 
614  inline std::vector<vpImagePoint> getRansacOutliers() const {
615  return m_ransacOutliers;
616  }
617 
623  inline cv::Mat getTrainDescriptors() const {
624  return m_trainDescriptors;
625  }
626 
627  void getTrainKeyPoints(std::vector<cv::KeyPoint> &keyPoints) const;
628  void getTrainKeyPoints(std::vector<vpImagePoint> &keyPoints) const;
629 
630  void getTrainPoints(std::vector<cv::Point3f> &points) const;
631  void getTrainPoints(std::vector<vpPoint> &points) const;
632 
633  void initMatcher(const std::string &matcherName);
634 
635  void insertImageMatching(const vpImage<unsigned char> &IRef, const vpImage<unsigned char> &ICurrent,
636  vpImage<unsigned char> &IMatching);
637  void insertImageMatching(const vpImage<unsigned char> &ICurrent, vpImage<unsigned char> &IMatching);
638 
639 #ifdef VISP_HAVE_XML2
640  void loadConfigFile(const std::string &configFile);
641 #endif
642 
643  void loadLearningData(const std::string &filename, const bool binaryMode=false, const bool append=false);
644 
645  void match(const cv::Mat &trainDescriptors, const cv::Mat &queryDescriptors,
646  std::vector<cv::DMatch> &matches, double &elapsedTime);
647 
648  unsigned int matchPoint(const vpImage<unsigned char> &I);
649  unsigned int matchPoint(const vpImage<unsigned char> &I, const vpImagePoint &iP,
650  const unsigned int height, const unsigned int width);
651  unsigned int matchPoint(const vpImage<unsigned char> &I, const vpRect& rectangle);
652 
654  bool (*func)(vpHomogeneousMatrix *)=NULL, const vpRect& rectangle=vpRect());
656  double &error, double &elapsedTime, bool (*func)(vpHomogeneousMatrix *)=NULL,
657  const vpRect& rectangle=vpRect());
658 
659  bool matchPointAndDetect(const vpImage<unsigned char> &I, vpRect &boundingBox, vpImagePoint &centerOfGravity,
660  const bool isPlanarObject=true, std::vector<vpImagePoint> *imPts1=NULL,
661  std::vector<vpImagePoint> *imPts2=NULL, double *meanDescriptorDistance=NULL,
662  double *detectionScore=NULL, const vpRect& rectangle=vpRect());
663 
664  bool matchPointAndDetect(const vpImage<unsigned char> &I, const vpCameraParameters &cam, vpHomogeneousMatrix &cMo,
665  double &error, double &elapsedTime, vpRect &boundingBox, vpImagePoint &centerOfGravity,
666  bool (*func)(vpHomogeneousMatrix *)=NULL, const vpRect& rectangle=vpRect());
667 
668  void reset();
669 
670  void saveLearningData(const std::string &filename, const bool binaryMode=false, const bool saveTrainingImages=true);
671 
677  inline void setCovarianceComputation(const bool& flag) {
678  m_computeCovariance = flag;
679  if(!m_useRansacVVS) {
680  std::cout << "Warning : The covariance matrix can only be computed with a Virtual Visual Servoing approach." << std::endl
681  << "Use setUseRansacVVS(true) to choose to use a pose estimation method based on a Virtual "
682  "Visual Servoing approach." << std::endl;
683  }
684  }
685 
691  inline void setDetectionMethod(const vpDetectionMethodType &method) {
692  m_detectionMethod = method;
693  }
694 
700  inline void setDetector(const vpFeatureDetectorType &detectorType) {
701  m_detectorNames.clear();
702  m_detectorNames.push_back(m_mapOfDetectorNames[detectorType]);
703  m_detectors.clear();
704  initDetector(m_mapOfDetectorNames[detectorType]);
705  }
706 
712  inline void setDetector(const std::string &detectorName) {
713  m_detectorNames.clear();
714  m_detectorNames.push_back(detectorName);
715  m_detectors.clear();
716  initDetector(detectorName);
717  }
718 
719 #if (VISP_HAVE_OPENCV_VERSION >= 0x020400 && VISP_HAVE_OPENCV_VERSION < 0x030000)
720 
727  template<typename T1, typename T2, typename T3> inline void setDetectorParameter(const T1 detectorName,
728  const T2 parameterName, const T3 value) {
729  if(m_detectors.find(detectorName) != m_detectors.end()) {
730  m_detectors[detectorName]->set(parameterName, value);
731  }
732  }
733 #endif
734 
740  inline void setDetectors(const std::vector<std::string> &detectorNames) {
741  m_detectorNames.clear();
742  m_detectors.clear();
743  m_detectorNames = detectorNames;
744  initDetectors(m_detectorNames);
745  }
746 
752  inline void setExtractor(const vpFeatureDescriptorType &extractorType) {
753  m_extractorNames.clear();
754  m_extractorNames.push_back(m_mapOfDescriptorNames[extractorType]);
755  m_extractors.clear();
756  initExtractor(m_mapOfDescriptorNames[extractorType]);
757  }
758 
764  inline void setExtractor(const std::string &extractorName) {
765  m_extractorNames.clear();
766  m_extractorNames.push_back(extractorName);
767  m_extractors.clear();
768  initExtractor(extractorName);
769  }
770 
771 #if (VISP_HAVE_OPENCV_VERSION >= 0x020400 && VISP_HAVE_OPENCV_VERSION < 0x030000)
772 
779  template<typename T1, typename T2, typename T3> inline void setExtractorParameter(const T1 extractorName,
780  const T2 parameterName, const T3 value) {
781  if(m_extractors.find(extractorName) != m_extractors.end()) {
782  m_extractors[extractorName]->set(parameterName, value);
783  }
784  }
785 #endif
786 
792  inline void setExtractors(const std::vector<std::string> &extractorNames) {
793  m_extractorNames.clear();
794  m_extractorNames = extractorNames;
795  m_extractors.clear();
796  initExtractors(m_extractorNames);
797  }
798 
804  inline void setImageFormat(const vpImageFormatType &imageFormat) {
805  m_imageFormat = imageFormat;
806  }
807 
822  inline void setMatcher(const std::string &matcherName) {
823  m_matcherName = matcherName;
824  initMatcher(m_matcherName);
825  }
826 
838  inline void setFilterMatchingType(const vpFilterMatchingType &filterType) {
839  m_filterType = filterType;
840 
841  //Use k-nearest neighbors (knn) to retrieve the two best matches for a keypoint
842  //So this is useful only for ratioDistanceThreshold method
843  if(filterType == ratioDistanceThreshold || filterType == stdAndRatioDistanceThreshold) {
844  m_useKnn = true;
845 
846  #if (VISP_HAVE_OPENCV_VERSION >= 0x020400 && VISP_HAVE_OPENCV_VERSION < 0x030000)
847  if(m_matcher != NULL && m_matcherName == "BruteForce") {
848  //if a matcher is already initialized, disable the crossCheck
849  //because it will not work with knnMatch
850  m_matcher->set("crossCheck", false);
851  }
852  #endif
853  } else {
854  m_useKnn = false;
855 
856  #if (VISP_HAVE_OPENCV_VERSION >= 0x020400 && VISP_HAVE_OPENCV_VERSION < 0x030000)
857  if(m_matcher != NULL && m_matcherName == "BruteForce") {
858  //if a matcher is already initialized, set the crossCheck mode if necessary
859  m_matcher->set("crossCheck", m_useBruteForceCrossCheck);
860  }
861  #endif
862  }
863  }
864 
870  inline void setMatchingFactorThreshold(const double factor) {
871  if(factor > 0.0) {
872  m_matchingFactorThreshold = factor;
873  } else {
874  throw vpException(vpException::badValue, "The factor must be positive.");
875  }
876  }
877 
883  inline void setMatchingRatioThreshold(const double ratio) {
884  if(ratio > 0.0 && (ratio < 1.0 || std::fabs(ratio - 1.0) < std::numeric_limits<double>::epsilon())) {
885  m_matchingRatioThreshold = ratio;
886  } else {
887  throw vpException(vpException::badValue, "The ratio must be in the interval ]0 ; 1].");
888  }
889  }
890 
896  inline void setRansacConsensusPercentage(const double percentage) {
897  if(percentage > 0.0 && (percentage < 100.0 || std::fabs(percentage - 100.0) < std::numeric_limits<double>::epsilon())) {
898  m_ransacConsensusPercentage = percentage;
899  } else {
900  throw vpException(vpException::badValue, "The percentage must be in the interval ]0 ; 100].");
901  }
902  }
903 
909  inline void setRansacIteration(const int nbIter) {
910  if(nbIter > 0) {
911  m_nbRansacIterations = nbIter;
912  } else {
913  throw vpException(vpException::badValue, "The number of iterations must be greater than zero.");
914  }
915  }
916 
922  inline void setRansacReprojectionError(const double reprojectionError) {
923  if(reprojectionError > 0.0) {
924  m_ransacReprojectionError = reprojectionError;
925  } else {
926  throw vpException(vpException::badValue, "The Ransac reprojection threshold must be positive as we deal with distance.");
927  }
928  }
929 
935  inline void setRansacMinInlierCount(const int minCount) {
936  if(minCount > 0) {
937  m_nbRansacMinInlierCount = minCount;
938  } else {
939  throw vpException(vpException::badValue, "The minimum number of inliers must be greater than zero.");
940  }
941  }
942 
948  inline void setRansacThreshold(const double threshold) {
949  if(threshold > 0.0) {
950  m_ransacThreshold = threshold;
951  } else {
952  throw vpException(vpException::badValue, "The Ransac threshold must be positive as we deal with distance.");
953  }
954  }
955 
961  inline void setUseAffineDetection(const bool useAffine) {
962  m_useAffineDetection = useAffine;
963  }
964 
965 #if (VISP_HAVE_OPENCV_VERSION >= 0x020400 && VISP_HAVE_OPENCV_VERSION < 0x030000)
966 
971  inline void setUseBruteForceCrossCheck(const bool useCrossCheck) {
972  //Only available with BruteForce and with k=1 (i.e not used with a ratioDistanceThreshold method)
973  if(m_matcher != NULL && !m_useKnn && m_matcherName == "BruteForce") {
974  m_matcher->set("crossCheck", useCrossCheck);
975  } else if(m_matcher != NULL && m_useKnn && m_matcherName == "BruteForce") {
976  std::cout << "Warning, you try to set the crossCheck parameter with a BruteForce matcher but knn is enabled";
977  std::cout << " (the filtering method uses a ratio constraint)" << std::endl;
978  }
979  }
980 #endif
981 
987  inline void setUseMatchTrainToQuery(const bool useMatchTrainToQuery) {
988  m_useMatchTrainToQuery = useMatchTrainToQuery;
989  }
990 
997  inline void setUseRansacConsensusPercentage(const bool usePercentage) {
998  m_useConsensusPercentage = usePercentage;
999  }
1000 
1006  inline void setUseRansacVVS(const bool ransacVVS) {
1007  m_useRansacVVS = ransacVVS;
1008  }
1009 
1015  inline void setUseSingleMatchFilter(const bool singleMatchFilter) {
1016  m_useSingleMatchFilter = singleMatchFilter;
1017  }
1018 
1019 private:
1021  bool m_computeCovariance;
1023  vpMatrix m_covarianceMatrix;
1025  int m_currentImageId;
1027  vpDetectionMethodType m_detectionMethod;
1029  double m_detectionScore;
1031  double m_detectionThreshold;
1033  double m_detectionTime;
1035  std::vector<std::string> m_detectorNames;
1037  // with a key based upon the detector name.
1038  std::map<std::string, cv::Ptr<cv::FeatureDetector> > m_detectors;
1040  double m_extractionTime;
1042  std::vector<std::string> m_extractorNames;
1044  // with a key based upon the extractor name.
1045  std::map<std::string, cv::Ptr<cv::DescriptorExtractor> > m_extractors;
1047  std::vector<cv::DMatch> m_filteredMatches;
1049  vpFilterMatchingType m_filterType;
1051  vpImageFormatType m_imageFormat;
1053  std::vector<std::vector<cv::DMatch> > m_knnMatches;
1055  std::map<vpFeatureDescriptorType, std::string> m_mapOfDescriptorNames;
1057  std::map<vpFeatureDetectorType, std::string> m_mapOfDetectorNames;
1059  std::map<int, int> m_mapOfImageId;
1061  std::map<int, vpImage<unsigned char> > m_mapOfImages;
1063  cv::Ptr<cv::DescriptorMatcher> m_matcher;
1065  std::string m_matcherName;
1067  std::vector<cv::DMatch> m_matches;
1069  double m_matchingFactorThreshold;
1071  double m_matchingRatioThreshold;
1073  double m_matchingTime;
1075  std::vector<std::pair<cv::KeyPoint, cv::Point3f> > m_matchRansacKeyPointsToPoints;
1077  int m_nbRansacIterations;
1079  int m_nbRansacMinInlierCount;
1081  std::vector<cv::Point3f> m_objectFilteredPoints;
1083  double m_poseTime;
1086  cv::Mat m_queryDescriptors;
1088  std::vector<cv::KeyPoint> m_queryFilteredKeyPoints;
1090  std::vector<cv::KeyPoint> m_queryKeyPoints;
1092  double m_ransacConsensusPercentage;
1094  std::vector<vpImagePoint> m_ransacInliers;
1096  std::vector<vpImagePoint> m_ransacOutliers;
1098  double m_ransacReprojectionError;
1100  double m_ransacThreshold;
1102  //detected in the train images).
1103  cv::Mat m_trainDescriptors;
1105  std::vector<cv::KeyPoint> m_trainKeyPoints;
1107  std::vector<cv::Point3f> m_trainPoints;
1109  std::vector<vpPoint> m_trainVpPoints;
1111  bool m_useAffineDetection;
1112 #if (VISP_HAVE_OPENCV_VERSION >= 0x020400 && VISP_HAVE_OPENCV_VERSION < 0x030000)
1113  bool m_useBruteForceCrossCheck;
1116 #endif
1117  bool m_useConsensusPercentage;
1120  bool m_useKnn;
1124  bool m_useMatchTrainToQuery;
1126  bool m_useRansacVVS;
1128  bool m_useSingleMatchFilter;
1129 
1130 
1131  void affineSkew(double tilt, double phi, cv::Mat& img, cv::Mat& mask, cv::Mat& Ai);
1132 
1133  double computePoseEstimationError(const std::vector<std::pair<cv::KeyPoint, cv::Point3f> > &matchKeyPoints,
1134  const vpCameraParameters &cam, const vpHomogeneousMatrix &cMo_est);
1135 
1136  void filterMatches();
1137 
1138  void init();
1139  void initDetector(const std::string &detectorNames);
1140  void initDetectors(const std::vector<std::string> &detectorNames);
1141 
1142  void initExtractor(const std::string &extractorName);
1143  void initExtractors(const std::vector<std::string> &extractorNames);
1144 
1145  void initFeatureNames();
1146 
1147  inline size_t myKeypointHash(const cv::KeyPoint &kp) {
1148  size_t _Val = 2166136261U, scale = 16777619U;
1149  Cv32suf u;
1150  u.f = kp.pt.x; _Val = (scale * _Val) ^ u.u;
1151  u.f = kp.pt.y; _Val = (scale * _Val) ^ u.u;
1152  u.f = kp.size; _Val = (scale * _Val) ^ u.u;
1153  //As the keypoint angle can be computed for certain type of keypoint only when extracting
1154  //the corresponding descriptor, the angle field is not taking into account for the hash
1155 // u.f = kp.angle; _Val = (scale * _Val) ^ u.u;
1156  u.f = kp.response; _Val = (scale * _Val) ^ u.u;
1157  _Val = (scale * _Val) ^ ((size_t) kp.octave);
1158  _Val = (scale * _Val) ^ ((size_t) kp.class_id);
1159  return _Val;
1160  }
1161 
1162 
1163 #if (VISP_HAVE_OPENCV_VERSION >= 0x030000)
1164  /*
1165  * Adapts a detector to detect points over multiple levels of a Gaussian
1166  * pyramid. Useful for detectors that are not inherently scaled.
1167  * From OpenCV 2.4.11 source code.
1168  */
1169  class PyramidAdaptedFeatureDetector: public cv::FeatureDetector {
1170  public:
1171  // maxLevel - The 0-based index of the last pyramid layer
1172  PyramidAdaptedFeatureDetector(const cv::Ptr<cv::FeatureDetector>& detector, int maxLevel = 2);
1173 
1174  // TODO implement read/write
1175  virtual bool empty() const;
1176 
1177  protected:
1178  virtual void detect(cv::InputArray image,
1179  CV_OUT std::vector<cv::KeyPoint>& keypoints, cv::InputArray mask =
1180  cv::noArray());
1181  virtual void detectImpl(const cv::Mat& image,
1182  std::vector<cv::KeyPoint>& keypoints, const cv::Mat& mask =
1183  cv::Mat()) const;
1184 
1185  cv::Ptr<cv::FeatureDetector> detector;
1186  int maxLevel;
1187  };
1188 
1189  /*
1190  * A class filters a vector of keypoints.
1191  * Because now it is difficult to provide a convenient interface for all usage scenarios of the keypoints filter class,
1192  * it has only several needed by now static methods.
1193  */
1194  class KeyPointsFilter {
1195  public:
1196  KeyPointsFilter() {
1197  }
1198 
1199  /*
1200  * Remove keypoints within borderPixels of an image edge.
1201  */
1202  static void runByImageBorder(std::vector<cv::KeyPoint>& keypoints,
1203  cv::Size imageSize, int borderSize);
1204  /*
1205  * Remove keypoints of sizes out of range.
1206  */
1207  static void runByKeypointSize(std::vector<cv::KeyPoint>& keypoints,
1208  float minSize, float maxSize = FLT_MAX);
1209  /*
1210  * Remove keypoints from some image by mask for pixels of this image.
1211  */
1212  static void runByPixelsMask(std::vector<cv::KeyPoint>& keypoints,
1213  const cv::Mat& mask);
1214  /*
1215  * Remove duplicated keypoints.
1216  */
1217  static void removeDuplicated(std::vector<cv::KeyPoint>& keypoints);
1218 
1219  /*
1220  * Retain the specified number of the best keypoints (according to the response)
1221  */
1222  static void retainBest(std::vector<cv::KeyPoint>& keypoints, int npoints);
1223  };
1224 
1225 #endif
1226 };
1227 
1228 #endif
1229 #endif
Implementation of a matrix and operations on matrices.
Definition: vpMatrix.h:97
void setRansacIteration(const int nbIter)
Definition: vpKeyPoint.h:909
class that defines what is a Keypoint. This class provides all the basic elements to implement classe...
void setUseRansacVVS(const bool ransacVVS)
Definition: vpKeyPoint.h:1006
Implementation of an homogeneous matrix and operations on such kind of matrices.
std::vector< std::pair< cv::KeyPoint, cv::KeyPoint > > getMatchQueryToTrainKeyPoints() const
Definition: vpKeyPoint.h:557
void setRansacThreshold(const double threshold)
Definition: vpKeyPoint.h:948
void setExtractor(const std::string &extractorName)
Definition: vpKeyPoint.h:764
void setUseSingleMatchFilter(const bool singleMatchFilter)
Definition: vpKeyPoint.h:1015
Class to define colors available for display functionnalities.
Definition: vpColor.h:121
std::map< vpFeatureDetectorType, std::string > getDetectorNames() const
Definition: vpKeyPoint.h:459
error that can be emited by ViSP classes.
Definition: vpException.h:73
void setDetectors(const std::vector< std::string > &detectorNames)
Definition: vpKeyPoint.h:740
static const vpColor green
Definition: vpColor.h:166
cv::Ptr< cv::DescriptorExtractor > getExtractor(const vpFeatureDescriptorType &type) const
Definition: vpKeyPoint.h:478
Class that defines what is a point.
Definition: vpPoint.h:59
cv::Mat getQueryDescriptors() const
Definition: vpKeyPoint.h:593
void setExtractors(const std::vector< std::string > &extractorNames)
Definition: vpKeyPoint.h:792
void setMatcher(const std::string &matcherName)
Definition: vpKeyPoint.h:822
void setUseMatchTrainToQuery(const bool useMatchTrainToQuery)
Definition: vpKeyPoint.h:987
cv::Ptr< cv::DescriptorMatcher > getMatcher() const
Definition: vpKeyPoint.h:539
vpFeatureDetectorType
Definition: vpKeyPoint.h:246
virtual unsigned int buildReference(const vpImage< unsigned char > &I)=0
double getDetectionTime() const
Definition: vpKeyPoint.h:415
Generic class defining intrinsic camera parameters.
vpFeatureDescriptorType
Definition: vpKeyPoint.h:274
void setDetector(const vpFeatureDetectorType &detectorType)
Definition: vpKeyPoint.h:700
double getMatchingTime() const
Definition: vpKeyPoint.h:530
void setDetectionMethod(const vpDetectionMethodType &method)
Definition: vpKeyPoint.h:691
void setUseBruteForceCrossCheck(const bool useCrossCheck)
Definition: vpKeyPoint.h:971
unsigned int getNbImages() const
Definition: vpKeyPoint.h:572
cv::Ptr< cv::FeatureDetector > getDetector(const std::string &name) const
Definition: vpKeyPoint.h:446
void setRansacMinInlierCount(const int minCount)
Definition: vpKeyPoint.h:935
vpMatrix getCovarianceMatrix() const
Definition: vpKeyPoint.h:394
void setImageFormat(const vpImageFormatType &imageFormat)
Definition: vpKeyPoint.h:804
virtual void display(const vpImage< unsigned char > &Iref, const vpImage< unsigned char > &Icurrent, unsigned int size=3)=0
void setRansacConsensusPercentage(const double percentage)
Definition: vpKeyPoint.h:896
virtual unsigned int matchPoint(const vpImage< unsigned char > &I)=0
vpImageFormatType getImageFormat() const
Definition: vpKeyPoint.h:521
void setUseAffineDetection(const bool useAffine)
Definition: vpKeyPoint.h:961
std::map< vpFeatureDescriptorType, std::string > getExtractorNames() const
Definition: vpKeyPoint.h:512
Class that allows keypoints detection (and descriptors extraction) and matching thanks to OpenCV libr...
Definition: vpKeyPoint.h:217
std::vector< vpImagePoint > getRansacOutliers() const
Definition: vpKeyPoint.h:614
vpDetectionMethodType
Definition: vpKeyPoint.h:231
void setDetectorParameter(const T1 detectorName, const T2 parameterName, const T3 value)
Definition: vpKeyPoint.h:727
vpFilterMatchingType
Definition: vpKeyPoint.h:222
cv::Mat getTrainDescriptors() const
Definition: vpKeyPoint.h:623
double getExtractionTime() const
Definition: vpKeyPoint.h:468
double getPoseTime() const
Definition: vpKeyPoint.h:584
void setDetector(const std::string &detectorName)
Definition: vpKeyPoint.h:712
Defines a rectangle in the plane.
Definition: vpRect.h:82
cv::Ptr< cv::DescriptorExtractor > getExtractor(const std::string &name) const
Definition: vpKeyPoint.h:499
void setExtractorParameter(const T1 extractorName, const T2 parameterName, const T3 value)
Definition: vpKeyPoint.h:779
void setUseRansacConsensusPercentage(const bool usePercentage)
Definition: vpKeyPoint.h:997
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
Definition: vpImagePoint.h:88
std::vector< vpImagePoint > getRansacInliers() const
Definition: vpKeyPoint.h:605
void setFilterMatchingType(const vpFilterMatchingType &filterType)
Definition: vpKeyPoint.h:838
void setMatchingFactorThreshold(const double factor)
Definition: vpKeyPoint.h:870
cv::Ptr< cv::FeatureDetector > getDetector(const vpFeatureDetectorType &type) const
Definition: vpKeyPoint.h:425
void setExtractor(const vpFeatureDescriptorType &extractorType)
Definition: vpKeyPoint.h:752
std::vector< cv::DMatch > getMatches() const
Definition: vpKeyPoint.h:548
void setRansacReprojectionError(const double reprojectionError)
Definition: vpKeyPoint.h:922
void setMatchingRatioThreshold(const double ratio)
Definition: vpKeyPoint.h:883
void setCovarianceComputation(const bool &flag)
Definition: vpKeyPoint.h:677