38 #ifndef _vpKeyPoint_h_
39 #define _vpKeyPoint_h_
51 #include <visp3/core/vpConfig.h>
52 #include <visp3/core/vpDisplay.h>
53 #include <visp3/core/vpImageConvert.h>
54 #include <visp3/core/vpPixelMeterConversion.h>
55 #include <visp3/core/vpPlane.h>
56 #include <visp3/core/vpPoint.h>
57 #include <visp3/vision/vpBasicKeyPoint.h>
58 #include <visp3/vision/vpPose.h>
59 #ifdef VISP_HAVE_MODULE_IO
60 # include <visp3/io/vpImageIo.h>
62 #include <visp3/core/vpConvert.h>
63 #include <visp3/core/vpCylinder.h>
64 #include <visp3/core/vpMeterPixelConversion.h>
65 #include <visp3/core/vpPolygon.h>
66 #include <visp3/vision/vpXmlConfigParserKeyPoint.h>
69 #if (VISP_HAVE_OPENCV_VERSION >= 0x020101)
71 # include <opencv2/calib3d/calib3d.hpp>
72 # include <opencv2/features2d/features2d.hpp>
73 # include <opencv2/imgproc/imgproc.hpp>
75 # if (VISP_HAVE_OPENCV_VERSION >= 0x040000) // Require opencv >= 4.0.0
76 # include <opencv2/imgproc/imgproc_c.h>
77 # include <opencv2/imgproc.hpp>
80 # if defined(VISP_HAVE_OPENCV_XFEATURES2D) // OpenCV >= 3.0.0
81 # include <opencv2/xfeatures2d.hpp>
82 # elif defined(VISP_HAVE_OPENCV_NONFREE) && (VISP_HAVE_OPENCV_VERSION >= 0x020400) && \
83 (VISP_HAVE_OPENCV_VERSION < 0x030000)
84 # include <opencv2/nonfree/nonfree.hpp>
87 # ifdef VISP_HAVE_XML2
88 # include <libxml/xmlwriter.h>
236 stdDistanceThreshold,
238 ratioDistanceThreshold,
241 stdAndRatioDistanceThreshold,
264 enum vpFeatureDetectorType {
265 #if (VISP_HAVE_OPENCV_VERSION >= 0x020403)
272 #if (VISP_HAVE_OPENCV_VERSION < 0x030000) || (defined(VISP_HAVE_OPENCV_XFEATURES2D))
275 #if defined(VISP_HAVE_OPENCV_NONFREE) || defined(VISP_HAVE_OPENCV_XFEATURES2D)
279 #if (VISP_HAVE_OPENCV_VERSION >= 0x030000)
284 #if (VISP_HAVE_OPENCV_VERSION >= 0x030100) && defined(VISP_HAVE_OPENCV_XFEATURES2D)
292 enum vpFeatureDescriptorType {
293 #if (VISP_HAVE_OPENCV_VERSION >= 0x020403)
296 #if (VISP_HAVE_OPENCV_VERSION < 0x030000) || (defined(VISP_HAVE_OPENCV_XFEATURES2D))
300 #if defined(VISP_HAVE_OPENCV_NONFREE) || defined(VISP_HAVE_OPENCV_XFEATURES2D)
304 #if (VISP_HAVE_OPENCV_VERSION >= 0x030000)
307 #if defined(VISP_HAVE_OPENCV_XFEATURES2D)
312 #if (VISP_HAVE_OPENCV_VERSION >= 0x030200) && defined(VISP_HAVE_OPENCV_XFEATURES2D)
314 DESCRIPTOR_BoostDesc,
320 vpKeyPoint(
const vpFeatureDetectorType &detectorType,
const vpFeatureDescriptorType &descriptorType,
321 const std::string &matcherName,
const vpFilterMatchingType &filterType = ratioDistanceThreshold);
322 vpKeyPoint(
const std::string &detectorName =
"ORB",
const std::string &extractorName =
"ORB",
323 const std::string &matcherName =
"BruteForce-Hamming",
324 const vpFilterMatchingType &filterType = ratioDistanceThreshold);
325 vpKeyPoint(
const std::vector<std::string> &detectorNames,
const std::vector<std::string> &extractorNames,
326 const std::string &matcherName =
"BruteForce",
327 const vpFilterMatchingType &filterType = ratioDistanceThreshold);
331 const unsigned int width);
335 std::vector<cv::Point3f> &points3f,
const bool append =
false,
const int class_id = -1);
337 const cv::Mat &trainDescriptors,
const std::vector<cv::Point3f> &points3f,
338 const bool append =
false,
const int class_id = -1);
340 static void compute3D(
const cv::KeyPoint &candidate,
const std::vector<vpPoint> &roi,
const vpCameraParameters &cam,
347 std::vector<cv::KeyPoint> &candidates,
348 const std::vector<vpPolygon> &polygons,
349 const std::vector<std::vector<vpPoint> > &roisPt,
350 std::vector<cv::Point3f> &points, cv::Mat *descriptors = NULL);
353 std::vector<vpImagePoint> &candidates,
354 const std::vector<vpPolygon> &polygons,
355 const std::vector<std::vector<vpPoint> > &roisPt,
356 std::vector<vpPoint> &points, cv::Mat *descriptors = NULL);
360 std::vector<cv::KeyPoint> &candidates,
const std::vector<vpCylinder> &cylinders,
361 const std::vector<std::vector<std::vector<vpImagePoint> > > &vectorOfCylinderRois,
362 std::vector<cv::Point3f> &points, cv::Mat *descriptors = NULL);
366 std::vector<vpImagePoint> &candidates,
const std::vector<vpCylinder> &cylinders,
367 const std::vector<std::vector<std::vector<vpImagePoint> > > &vectorOfCylinderRois,
368 std::vector<vpPoint> &points, cv::Mat *descriptors = NULL);
370 bool computePose(
const std::vector<cv::Point2f> &imagePoints,
const std::vector<cv::Point3f> &objectPoints,
374 bool computePose(
const std::vector<vpPoint> &objectVpPoints,
vpHomogeneousMatrix &cMo, std::vector<vpPoint> &inliers,
377 bool computePose(
const std::vector<vpPoint> &objectVpPoints,
vpHomogeneousMatrix &cMo, std::vector<vpPoint> &inliers,
378 std::vector<unsigned int> &inlierIndex,
double &elapsedTime,
387 void detect(
const cv::Mat &matImg, std::vector<cv::KeyPoint> &keyPoints,
const cv::Mat &mask = cv::Mat());
390 void detect(
const cv::Mat &matImg, std::vector<cv::KeyPoint> &keyPoints,
double &elapsedTime,
391 const cv::Mat &mask = cv::Mat());
393 void detectExtractAffine(
const vpImage<unsigned char> &I, std::vector<std::vector<cv::KeyPoint> > &listOfKeypoints,
394 std::vector<cv::Mat> &listOfDescriptors,
403 const std::vector<vpImagePoint> &ransacInliers = std::vector<vpImagePoint>(),
404 unsigned int crossSize = 3,
unsigned int lineThickness = 1);
407 std::vector<cv::Point3f> *trainPoints = NULL);
408 void extract(
const cv::Mat &matImg, std::vector<cv::KeyPoint> &keyPoints, cv::Mat &descriptors,
409 std::vector<cv::Point3f> *trainPoints = NULL);
411 double &elapsedTime, std::vector<cv::Point3f> *trainPoints = NULL);
412 void extract(
const cv::Mat &matImg, std::vector<cv::KeyPoint> &keyPoints, cv::Mat &descriptors,
double &elapsedTime,
413 std::vector<cv::Point3f> *trainPoints = NULL);
424 inline vpMatrix getCovarianceMatrix()
const
426 if (!m_computeCovariance) {
427 std::cout <<
"Warning : The covariance matrix has not been computed. "
428 "See setCovarianceComputation() to do it."
433 if (m_computeCovariance && !m_useRansacVVS) {
434 std::cout <<
"Warning : The covariance matrix can only be computed "
435 "with a Virtual Visual Servoing approach."
437 <<
"Use setUseRansacVVS(true) to choose to use a pose "
438 "estimation method based on a Virtual Visual Servoing "
444 return m_covarianceMatrix;
452 inline double getDetectionTime()
const {
return m_detectionTime; }
461 inline cv::Ptr<cv::FeatureDetector> getDetector(
const vpFeatureDetectorType &type)
const
463 std::map<vpFeatureDetectorType, std::string>::const_iterator it_name = m_mapOfDetectorNames.find(type);
464 if (it_name == m_mapOfDetectorNames.end()) {
465 std::cerr <<
"Internal problem with the feature type and the "
466 "corresponding name!"
470 std::map<std::string, cv::Ptr<cv::FeatureDetector> >::const_iterator findDetector =
471 m_detectors.find(it_name->second);
472 if (findDetector != m_detectors.end()) {
473 return findDetector->second;
476 std::cerr <<
"Cannot find: " << it_name->second << std::endl;
477 return cv::Ptr<cv::FeatureDetector>();
487 inline cv::Ptr<cv::FeatureDetector> getDetector(
const std::string &name)
const
489 std::map<std::string, cv::Ptr<cv::FeatureDetector> >::const_iterator findDetector = m_detectors.find(name);
490 if (findDetector != m_detectors.end()) {
491 return findDetector->second;
494 std::cerr <<
"Cannot find: " << name << std::endl;
495 return cv::Ptr<cv::FeatureDetector>();
501 inline std::map<vpFeatureDetectorType, std::string> getDetectorNames()
const {
return m_mapOfDetectorNames; }
508 inline double getExtractionTime()
const {
return m_extractionTime; }
517 inline cv::Ptr<cv::DescriptorExtractor> getExtractor(
const vpFeatureDescriptorType &type)
const
519 std::map<vpFeatureDescriptorType, std::string>::const_iterator it_name = m_mapOfDescriptorNames.find(type);
520 if (it_name == m_mapOfDescriptorNames.end()) {
521 std::cerr <<
"Internal problem with the feature type and the "
522 "corresponding name!"
526 std::map<std::string, cv::Ptr<cv::DescriptorExtractor> >::const_iterator findExtractor =
527 m_extractors.find(it_name->second);
528 if (findExtractor != m_extractors.end()) {
529 return findExtractor->second;
532 std::cerr <<
"Cannot find: " << it_name->second << std::endl;
533 return cv::Ptr<cv::DescriptorExtractor>();
543 inline cv::Ptr<cv::DescriptorExtractor> getExtractor(
const std::string &name)
const
545 std::map<std::string, cv::Ptr<cv::DescriptorExtractor> >::const_iterator findExtractor = m_extractors.find(name);
546 if (findExtractor != m_extractors.end()) {
547 return findExtractor->second;
550 std::cerr <<
"Cannot find: " << name << std::endl;
551 return cv::Ptr<cv::DescriptorExtractor>();
557 inline std::map<vpFeatureDescriptorType, std::string> getExtractorNames()
const {
return m_mapOfDescriptorNames; }
564 inline vpImageFormatType getImageFormat()
const {
return m_imageFormat; }
571 inline double getMatchingTime()
const {
return m_matchingTime; }
578 inline cv::Ptr<cv::DescriptorMatcher> getMatcher()
const {
return m_matcher; }
586 inline std::vector<cv::DMatch> getMatches()
const {
return m_filteredMatches; }
595 inline std::vector<std::pair<cv::KeyPoint, cv::KeyPoint> > getMatchQueryToTrainKeyPoints()
const
597 std::vector<std::pair<cv::KeyPoint, cv::KeyPoint> > matchQueryToTrainKeyPoints(m_filteredMatches.size());
598 for (
size_t i = 0; i < m_filteredMatches.size(); i++) {
599 matchQueryToTrainKeyPoints.push_back(
600 std::pair<cv::KeyPoint, cv::KeyPoint>(m_queryFilteredKeyPoints[(
size_t)m_filteredMatches[i].queryIdx],
601 m_trainKeyPoints[(
size_t)m_filteredMatches[i].trainIdx]));
603 return matchQueryToTrainKeyPoints;
611 inline unsigned int getNbImages()
const {
return static_cast<unsigned int>(m_mapOfImages.size()); }
613 void getObjectPoints(std::vector<cv::Point3f> &objectPoints)
const;
614 void getObjectPoints(std::vector<vpPoint> &objectPoints)
const;
621 inline double getPoseTime()
const {
return m_poseTime; }
629 inline cv::Mat getQueryDescriptors()
const {
return m_queryDescriptors; }
631 void getQueryKeyPoints(std::vector<cv::KeyPoint> &keyPoints)
const;
632 void getQueryKeyPoints(std::vector<vpImagePoint> &keyPoints)
const;
639 inline std::vector<vpImagePoint> getRansacInliers()
const {
return m_ransacInliers; }
646 inline std::vector<vpImagePoint> getRansacOutliers()
const {
return m_ransacOutliers; }
654 inline cv::Mat getTrainDescriptors()
const {
return m_trainDescriptors; }
656 void getTrainKeyPoints(std::vector<cv::KeyPoint> &keyPoints)
const;
657 void getTrainKeyPoints(std::vector<vpImagePoint> &keyPoints)
const;
659 void getTrainPoints(std::vector<cv::Point3f> &points)
const;
660 void getTrainPoints(std::vector<vpPoint> &points)
const;
662 void initMatcher(
const std::string &matcherName);
668 #ifdef VISP_HAVE_XML2
669 void loadConfigFile(
const std::string &configFile);
672 void loadLearningData(
const std::string &filename,
const bool binaryMode =
false,
const bool append =
false);
674 void match(
const cv::Mat &trainDescriptors,
const cv::Mat &queryDescriptors, std::vector<cv::DMatch> &matches,
675 double &elapsedTime);
679 const unsigned int width);
689 const bool isPlanarObject =
true, std::vector<vpImagePoint> *imPts1 = NULL,
690 std::vector<vpImagePoint> *imPts2 = NULL,
double *meanDescriptorDistance = NULL,
691 double *detectionScore = NULL,
const vpRect &rectangle =
vpRect());
694 double &error,
double &elapsedTime,
vpRect &boundingBox,
vpImagePoint ¢erOfGravity,
699 void saveLearningData(
const std::string &filename,
const bool binaryMode =
false,
700 const bool saveTrainingImages =
true);
708 inline void setCovarianceComputation(
const bool &flag)
710 m_computeCovariance = flag;
711 if (!m_useRansacVVS) {
712 std::cout <<
"Warning : The covariance matrix can only be computed "
713 "with a Virtual Visual Servoing approach."
715 <<
"Use setUseRansacVVS(true) to choose to use a pose "
716 "estimation method based on a Virtual "
717 "Visual Servoing approach."
727 inline void setDetectionMethod(
const vpDetectionMethodType &method) { m_detectionMethod = method; }
734 inline void setDetector(
const vpFeatureDetectorType &detectorType)
736 m_detectorNames.clear();
737 m_detectorNames.push_back(m_mapOfDetectorNames[detectorType]);
739 initDetector(m_mapOfDetectorNames[detectorType]);
747 inline void setDetector(
const std::string &detectorName)
749 m_detectorNames.clear();
750 m_detectorNames.push_back(detectorName);
752 initDetector(detectorName);
755 #if (VISP_HAVE_OPENCV_VERSION >= 0x020400 && VISP_HAVE_OPENCV_VERSION < 0x030000)
764 template <
typename T1,
typename T2,
typename T3>
765 inline void setDetectorParameter(
const T1 detectorName,
const T2 parameterName,
const T3 value)
767 if (m_detectors.find(detectorName) != m_detectors.end()) {
768 m_detectors[detectorName]->set(parameterName, value);
779 inline void setDetectors(
const std::vector<std::string> &detectorNames)
781 m_detectorNames.clear();
783 m_detectorNames = detectorNames;
784 initDetectors(m_detectorNames);
792 inline void setExtractor(
const vpFeatureDescriptorType &extractorType)
794 m_extractorNames.clear();
795 m_extractorNames.push_back(m_mapOfDescriptorNames[extractorType]);
796 m_extractors.clear();
797 initExtractor(m_mapOfDescriptorNames[extractorType]);
806 inline void setExtractor(
const std::string &extractorName)
808 m_extractorNames.clear();
809 m_extractorNames.push_back(extractorName);
810 m_extractors.clear();
811 initExtractor(extractorName);
814 #if (VISP_HAVE_OPENCV_VERSION >= 0x020400 && VISP_HAVE_OPENCV_VERSION < 0x030000)
823 template <
typename T1,
typename T2,
typename T3>
824 inline void setExtractorParameter(
const T1 extractorName,
const T2 parameterName,
const T3 value)
826 if (m_extractors.find(extractorName) != m_extractors.end()) {
827 m_extractors[extractorName]->set(parameterName, value);
838 inline void setExtractors(
const std::vector<std::string> &extractorNames)
840 m_extractorNames.clear();
841 m_extractorNames = extractorNames;
842 m_extractors.clear();
843 initExtractors(m_extractorNames);
851 inline void setImageFormat(
const vpImageFormatType &imageFormat) { m_imageFormat = imageFormat; }
868 inline void setMatcher(
const std::string &matcherName)
870 m_matcherName = matcherName;
871 initMatcher(m_matcherName);
889 inline void setFilterMatchingType(
const vpFilterMatchingType &filterType)
891 m_filterType = filterType;
895 if (filterType == ratioDistanceThreshold || filterType == stdAndRatioDistanceThreshold) {
898 #if (VISP_HAVE_OPENCV_VERSION >= 0x020400 && VISP_HAVE_OPENCV_VERSION < 0x030000)
899 if (m_matcher != NULL && m_matcherName ==
"BruteForce") {
902 m_matcher->set(
"crossCheck",
false);
908 #if (VISP_HAVE_OPENCV_VERSION >= 0x020400 && VISP_HAVE_OPENCV_VERSION < 0x030000)
909 if (m_matcher != NULL && m_matcherName ==
"BruteForce") {
912 m_matcher->set(
"crossCheck", m_useBruteForceCrossCheck);
924 inline void setMatchingFactorThreshold(
const double factor)
927 m_matchingFactorThreshold = factor;
938 inline void setMatchingRatioThreshold(
const double ratio)
940 if (ratio > 0.0 && (ratio < 1.0 || std::fabs(ratio - 1.0) < std::numeric_limits<double>::epsilon())) {
941 m_matchingRatioThreshold = ratio;
953 inline void setRansacConsensusPercentage(
const double percentage)
955 if (percentage > 0.0 &&
956 (percentage < 100.0 || std::fabs(percentage - 100.0) < std::numeric_limits<double>::epsilon())) {
957 m_ransacConsensusPercentage = percentage;
968 m_ransacFilterFlag = flag;
977 inline void setRansacIteration(
const int nbIter)
980 m_nbRansacIterations = nbIter;
991 inline void setRansacParallel(
const bool parallel)
993 m_ransacParallel = parallel;
1002 inline void setRansacParallelNbThreads(
const unsigned int nthreads)
1004 m_ransacParallelNbThreads = nthreads;
1014 inline void setRansacReprojectionError(
const double reprojectionError)
1016 if (reprojectionError > 0.0) {
1017 m_ransacReprojectionError = reprojectionError;
1020 "threshold must be positive "
1021 "as we deal with distance.");
1030 inline void setRansacMinInlierCount(
const int minCount)
1033 m_nbRansacMinInlierCount = minCount;
1045 inline void setRansacThreshold(
const double threshold)
1047 if (threshold > 0.0) {
1048 m_ransacThreshold = threshold;
1061 inline void setUseAffineDetection(
const bool useAffine) { m_useAffineDetection = useAffine; }
1063 #if (VISP_HAVE_OPENCV_VERSION >= 0x020400 && VISP_HAVE_OPENCV_VERSION < 0x030000)
1070 inline void setUseBruteForceCrossCheck(
const bool useCrossCheck)
1074 if (m_matcher != NULL && !m_useKnn && m_matcherName ==
"BruteForce") {
1075 m_matcher->set(
"crossCheck", useCrossCheck);
1076 }
else if (m_matcher != NULL && m_useKnn && m_matcherName ==
"BruteForce") {
1077 std::cout <<
"Warning, you try to set the crossCheck parameter with a "
1078 "BruteForce matcher but knn is enabled";
1079 std::cout <<
" (the filtering method uses a ratio constraint)" << std::endl;
1090 inline void setUseMatchTrainToQuery(
const bool useMatchTrainToQuery)
1092 m_useMatchTrainToQuery = useMatchTrainToQuery;
1102 inline void setUseRansacConsensusPercentage(
const bool usePercentage) { m_useConsensusPercentage = usePercentage; }
1111 inline void setUseRansacVVS(
const bool ransacVVS) { m_useRansacVVS = ransacVVS; }
1119 inline void setUseSingleMatchFilter(
const bool singleMatchFilter) { m_useSingleMatchFilter = singleMatchFilter; }
1124 bool m_computeCovariance;
1128 int m_currentImageId;
1131 vpDetectionMethodType m_detectionMethod;
1133 double m_detectionScore;
1136 double m_detectionThreshold;
1138 double m_detectionTime;
1140 std::vector<std::string> m_detectorNames;
1144 std::map<std::string, cv::Ptr<cv::FeatureDetector> > m_detectors;
1146 double m_extractionTime;
1148 std::vector<std::string> m_extractorNames;
1152 std::map<std::string, cv::Ptr<cv::DescriptorExtractor> > m_extractors;
1154 std::vector<cv::DMatch> m_filteredMatches;
1156 vpFilterMatchingType m_filterType;
1158 vpImageFormatType m_imageFormat;
1161 std::vector<std::vector<cv::DMatch> > m_knnMatches;
1163 std::map<vpFeatureDescriptorType, std::string> m_mapOfDescriptorNames;
1165 std::map<vpFeatureDetectorType, std::string> m_mapOfDetectorNames;
1168 std::map<int, int> m_mapOfImageId;
1171 std::map<int, vpImage<unsigned char> > m_mapOfImages;
1174 cv::Ptr<cv::DescriptorMatcher> m_matcher;
1176 std::string m_matcherName;
1178 std::vector<cv::DMatch> m_matches;
1180 double m_matchingFactorThreshold;
1182 double m_matchingRatioThreshold;
1184 double m_matchingTime;
1186 std::vector<std::pair<cv::KeyPoint, cv::Point3f> > m_matchRansacKeyPointsToPoints;
1188 int m_nbRansacIterations;
1190 int m_nbRansacMinInlierCount;
1193 std::vector<cv::Point3f> m_objectFilteredPoints;
1198 cv::Mat m_queryDescriptors;
1200 std::vector<cv::KeyPoint> m_queryFilteredKeyPoints;
1202 std::vector<cv::KeyPoint> m_queryKeyPoints;
1205 double m_ransacConsensusPercentage;
1209 std::vector<vpImagePoint> m_ransacInliers;
1211 std::vector<vpImagePoint> m_ransacOutliers;
1213 bool m_ransacParallel;
1215 unsigned int m_ransacParallelNbThreads;
1218 double m_ransacReprojectionError;
1221 double m_ransacThreshold;
1225 cv::Mat m_trainDescriptors;
1227 std::vector<cv::KeyPoint> m_trainKeyPoints;
1230 std::vector<cv::Point3f> m_trainPoints;
1233 std::vector<vpPoint> m_trainVpPoints;
1236 bool m_useAffineDetection;
1237 #if (VISP_HAVE_OPENCV_VERSION >= 0x020400 && VISP_HAVE_OPENCV_VERSION < 0x030000)
1238 bool m_useBruteForceCrossCheck;
1243 bool m_useConsensusPercentage;
1252 bool m_useMatchTrainToQuery;
1254 bool m_useRansacVVS;
1257 bool m_useSingleMatchFilter;
1259 void affineSkew(
double tilt,
double phi, cv::Mat &img, cv::Mat &mask, cv::Mat &Ai);
1261 double computePoseEstimationError(
const std::vector<std::pair<cv::KeyPoint, cv::Point3f> > &matchKeyPoints,
1264 void filterMatches();
1267 void initDetector(
const std::string &detectorNames);
1268 void initDetectors(
const std::vector<std::string> &detectorNames);
1270 void initExtractor(
const std::string &extractorName);
1271 void initExtractors(
const std::vector<std::string> &extractorNames);
1273 void initFeatureNames();
1275 inline size_t myKeypointHash(
const cv::KeyPoint &kp)
1277 size_t _Val = 2166136261U, scale = 16777619U;
1280 _Val = (scale * _Val) ^ u.u;
1282 _Val = (scale * _Val) ^ u.u;
1284 _Val = (scale * _Val) ^ u.u;
1290 _Val = (scale * _Val) ^ u.u;
1291 _Val = (scale * _Val) ^ ((
size_t)kp.octave);
1292 _Val = (scale * _Val) ^ ((
size_t)kp.class_id);
1296 #if (VISP_HAVE_OPENCV_VERSION >= 0x030000)
1302 class PyramidAdaptedFeatureDetector :
public cv::FeatureDetector
1306 PyramidAdaptedFeatureDetector(
const cv::Ptr<cv::FeatureDetector> &detector,
int maxLevel = 2);
1309 virtual bool empty()
const;
1312 virtual void detect(cv::InputArray image, CV_OUT std::vector<cv::KeyPoint> &keypoints,
1313 cv::InputArray mask = cv::noArray());
1314 virtual void detectImpl(
const cv::Mat &image, std::vector<cv::KeyPoint> &keypoints,
1315 const cv::Mat &mask = cv::Mat())
const;
1317 cv::Ptr<cv::FeatureDetector> detector;
1327 class KeyPointsFilter
1330 KeyPointsFilter() {}
1335 static void runByImageBorder(std::vector<cv::KeyPoint> &keypoints, cv::Size imageSize,
int borderSize);
1339 static void runByKeypointSize(std::vector<cv::KeyPoint> &keypoints,
float minSize,
float maxSize = FLT_MAX);
1343 static void runByPixelsMask(std::vector<cv::KeyPoint> &keypoints,
const cv::Mat &mask);
1347 static void removeDuplicated(std::vector<cv::KeyPoint> &keypoints);
1353 static void retainBest(std::vector<cv::KeyPoint> &keypoints,
int npoints);