38 #ifndef __vpKeyPoint_h__
39 #define __vpKeyPoint_h__
51 #include <visp/vpConfig.h>
52 #include <visp/vpBasicKeyPoint.h>
53 #include <visp/vpImageConvert.h>
54 #include <visp/vpPoint.h>
55 #include <visp/vpDisplay.h>
56 #include <visp/vpPlane.h>
57 #include <visp/vpPixelMeterConversion.h>
58 #include <visp/vpMbEdgeTracker.h>
59 #include <visp/vpIoTools.h>
60 #include <visp/vpPose.h>
61 #include <visp/vpImageIo.h>
62 #include <visp/vpPolygon.h>
63 #include <visp/vpXmlConfigParserKeyPoint.h>
64 #include <visp/vpConvert.h>
67 #if (VISP_HAVE_OPENCV_VERSION >= 0x020101)
69 #include <opencv2/features2d/features2d.hpp>
70 #include <opencv2/calib3d/calib3d.hpp>
72 #if defined(VISP_HAVE_OPENCV_XFEATURES2D) // OpenCV >= 3.0.0
73 # include <opencv2/xfeatures2d.hpp>
74 #elif defined(VISP_HAVE_OPENCV_NONFREE) && (VISP_HAVE_OPENCV_VERSION >= 0x020400) && (VISP_HAVE_OPENCV_VERSION < 0x030000)
75 # include <opencv2/nonfree/nonfree.hpp>
79 # include <libxml/xmlwriter.h>
223 } vpFilterMatchingType;
230 } vpDetectionMethodType;
233 vpKeyPoint(
const std::string &detectorName=
"ORB",
const std::string &extractorName=
"ORB",
234 const std::string &matcherName=
"BruteForce-Hamming",
const vpFilterMatchingType &filterType=ratioDistanceThreshold);
235 vpKeyPoint(
const std::vector<std::string> &detectorNames,
const std::vector<std::string> &extractorNames,
236 const std::string &matcherName=
"BruteForce",
const vpFilterMatchingType &filterType=ratioDistanceThreshold);
240 const vpImagePoint &iP,
const unsigned int height,
const unsigned int width);
244 std::vector<cv::Point3f> &points3f,
bool append=
false);
246 const cv::Mat &trainDescriptors,
const std::vector<cv::Point3f> &points3f,
bool append=
false);
248 static void compute3D(
const cv::KeyPoint &candidate,
const std::vector<vpPoint> &roi,
251 static void compute3D(
const vpImagePoint &candidate,
const std::vector<vpPoint> &roi,
255 std::vector<cv::KeyPoint> &candidate, std::vector<vpPolygon> &polygons, std::vector<std::vector<vpPoint> > &roisPt,
256 std::vector<cv::Point3f> &points, cv::Mat *descriptors=NULL);
259 std::vector<vpImagePoint> &candidate, std::vector<vpPolygon> &polygons, std::vector<std::vector<vpPoint> > &roisPt,
260 std::vector<vpPoint> &points, cv::Mat *descriptors=NULL);
262 bool computePose(
const std::vector<cv::Point2f> &imagePoints,
const std::vector<cv::Point3f> &objectPoints,
267 std::vector<vpPoint> &inliers,
double &elapsedTime,
bool (*func)(
vpHomogeneousMatrix *)=NULL);
274 void detect(
const cv::Mat &matImg, std::vector<cv::KeyPoint> &keyPoints,
double &elapsedTime,
275 const cv::Mat &mask=cv::Mat());
277 void detectExtractAffine(
const vpImage<unsigned char> &I, std::vector<std::vector<cv::KeyPoint> >& listOfKeypoints,
278 std::vector<cv::Mat>& listOfDescriptors,
285 unsigned int crossSize,
unsigned int lineThickness=1,
288 const std::vector<vpImagePoint> &ransacInliers=std::vector<vpImagePoint>(),
unsigned int crossSize=3,
289 unsigned int lineThickness=1);
291 void extract(
const vpImage<unsigned char> &I, std::vector<cv::KeyPoint> &keyPoints, cv::Mat &descriptors,
double &elapsedTime);
292 void extract(
const cv::Mat &matImg, std::vector<cv::KeyPoint> &keyPoints, cv::Mat &descriptors,
double &elapsedTime);
302 if(!m_computeCovariance) {
303 std::cout <<
"Warning : The covariance matrix has not been computed. See setCovarianceComputation() to do it." << std::endl;
307 if(m_computeCovariance && !m_useRansacVVS) {
308 std::cout <<
"Warning : The covariance matrix can only be computed with a Virtual Visual Servoing approach." << std::endl
309 <<
"Use setUseRansacVVS(true) to choose to use a pose estimation method based on a Virtual Visual Servoing approach."
314 return m_covarianceMatrix;
323 return m_detectionTime;
332 return m_extractionTime;
341 return m_matchingTime;
350 return m_filteredMatches;
359 return m_matchQueryToTrainKeyPoints;
368 return static_cast<unsigned int>(m_mapOfImages.size());
371 void getObjectPoints(std::vector<cv::Point3f> &objectPoints)
const;
372 void getObjectPoints(std::vector<vpPoint> &objectPoints)
const;
389 return m_queryDescriptors;
392 void getQueryKeyPoints(std::vector<cv::KeyPoint> &keyPoints)
const;
393 void getQueryKeyPoints(std::vector<vpImagePoint> &keyPoints)
const;
401 return m_ransacInliers;
410 return m_ransacOutliers;
419 return m_trainDescriptors;
422 void getTrainKeyPoints(std::vector<cv::KeyPoint> &keyPoints)
const;
423 void getTrainKeyPoints(std::vector<vpImagePoint> &keyPoints)
const;
425 void getTrainPoints(std::vector<cv::Point3f> &points)
const;
426 void getTrainPoints(std::vector<vpPoint> &points)
const;
428 void initMatcher(
const std::string &matcherName);
434 #ifdef VISP_HAVE_XML2
435 void loadConfigFile(
const std::string &configFile);
438 void loadLearningData(
const std::string &filename,
const bool binaryMode=
false,
const bool append=
false);
440 void match(
const cv::Mat &trainDescriptors,
const cv::Mat &queryDescriptors,
441 std::vector<cv::DMatch> &matches,
double &elapsedTime);
445 const unsigned int height,
const unsigned int width);
452 const bool isPlanarObject=
true, std::vector<vpImagePoint> *imPts1=NULL,
453 std::vector<vpImagePoint> *imPts2=NULL,
double *meanDescriptorDistance=NULL,
454 double *detectionScore=NULL);
457 double &error,
double &elapsedTime,
vpRect &boundingBox,
vpImagePoint ¢erOfGravity,
460 void saveLearningData(
const std::string &filename,
const bool binaryMode=
false,
const bool saveTrainingImages=
true);
468 m_computeCovariance = flag;
469 if(!m_useRansacVVS) {
470 std::cout <<
"Warning : The covariance matrix can only be computed with a Virtual Visual Servoing approach." << std::endl
471 <<
"Use setUseRansacVVS(true) to choose to use a pose estimation method based on a Virtual "
472 "Visual Servoing approach." << std::endl;
482 m_detectionMethod = method;
491 m_detectorNames.clear();
492 m_detectorNames.push_back(detectorName);
494 initDetector(detectorName);
505 const T2 parameterName,
const T3 value) {
506 if(m_detectors.find(detectorName) != m_detectors.end()) {
507 m_detectors[detectorName]->set(parameterName, value);
516 inline void setDetectors(
const std::vector<std::string> &detectorNames) {
517 m_detectorNames.clear();
519 m_detectorNames = detectorNames;
520 initDetectors(m_detectorNames);
529 m_extractorNames.clear();
530 m_extractorNames.push_back(extractorName);
531 m_extractors.clear();
532 initExtractor(extractorName);
543 const T2 parameterName,
const T3 value) {
544 if(m_extractors.find(extractorName) != m_extractors.end()) {
545 m_extractors[extractorName]->set(parameterName, value);
555 m_extractorNames.clear();
556 m_extractorNames = extractorNames;
557 m_extractors.clear();
558 initExtractors(m_extractorNames);
576 m_matcherName = matcherName;
577 initMatcher(m_matcherName);
592 m_filterType = filterType;
596 if(filterType == ratioDistanceThreshold || filterType == stdAndRatioDistanceThreshold) {
610 m_matchingFactorThreshold = factor;
622 if(ratio > 0.0 && (ratio < 1.0 || std::fabs(ratio - 1.0) < std::numeric_limits<double>::epsilon())) {
623 m_matchingRatioThreshold = ratio;
635 if(percentage > 0.0 && (percentage < 100.0 || std::fabs(percentage - 100.0) < std::numeric_limits<double>::epsilon())) {
636 m_ransacConsensusPercentage = percentage;
649 m_nbRansacIterations = nbIter;
661 if(reprojectionError > 0.0) {
662 m_ransacReprojectionError = reprojectionError;
675 m_nbRansacMinInlierCount = minCount;
687 if(threshold > 0.0) {
688 m_ransacThreshold = threshold;
700 m_useAffineDetection = useAffine;
703 #if (VISP_HAVE_OPENCV_VERSION >= 0x020400)
711 if(m_matcher != NULL && !m_useKnn && m_matcherName ==
"BruteForce") {
712 m_matcher->set(
"crossCheck", useCrossCheck);
724 m_useConsensusPercentage = usePercentage;
733 m_useRansacVVS = ransacVVS;
738 bool m_computeCovariance;
742 int m_currentImageId;
744 vpDetectionMethodType m_detectionMethod;
746 double m_detectionScore;
748 double m_detectionThreshold;
750 double m_detectionTime;
752 std::vector<std::string> m_detectorNames;
755 std::map<std::string, cv::Ptr<cv::FeatureDetector> > m_detectors;
757 double m_extractionTime;
759 std::vector<std::string> m_extractorNames;
762 std::map<std::string, cv::Ptr<cv::DescriptorExtractor> > m_extractors;
764 std::vector<cv::DMatch> m_filteredMatches;
766 vpFilterMatchingType m_filterType;
768 std::vector<std::vector<cv::DMatch> > m_knnMatches;
770 std::map<int, int> m_mapOfImageId;
772 std::map<int, vpImage<unsigned char> > m_mapOfImages;
774 cv::Ptr<cv::DescriptorMatcher> m_matcher;
776 std::string m_matcherName;
778 std::vector<cv::DMatch> m_matches;
780 double m_matchingFactorThreshold;
782 double m_matchingRatioThreshold;
784 double m_matchingTime;
786 std::vector<std::pair<cv::KeyPoint, cv::KeyPoint> > m_matchQueryToTrainKeyPoints;
788 std::vector<std::pair<cv::KeyPoint, cv::Point3f> > m_matchRansacKeyPointsToPoints;
790 std::vector<std::pair<cv::KeyPoint, cv::KeyPoint> > m_matchRansacQueryToTrainKeyPoints;
792 int m_nbRansacIterations;
794 int m_nbRansacMinInlierCount;
796 std::vector<cv::Point3f> m_objectFilteredPoints;
801 cv::Mat m_queryDescriptors;
803 std::vector<cv::KeyPoint> m_queryFilteredKeyPoints;
805 std::vector<cv::KeyPoint> m_queryKeyPoints;
807 double m_ransacConsensusPercentage;
809 std::vector<vpImagePoint> m_ransacInliers;
811 std::vector<vpImagePoint> m_ransacOutliers;
813 double m_ransacReprojectionError;
815 double m_ransacThreshold;
818 cv::Mat m_trainDescriptors;
820 std::vector<cv::KeyPoint> m_trainKeyPoints;
822 std::vector<cv::Point3f> m_trainPoints;
824 std::vector<vpPoint> m_trainVpPoints;
826 bool m_useAffineDetection;
829 bool m_useBruteForceCrossCheck;
831 bool m_useConsensusPercentage;
838 void affineSkew(
double tilt,
double phi, cv::Mat& img, cv::Mat& mask, cv::Mat& Ai);
840 double computePoseEstimationError(
const std::vector<std::pair<cv::KeyPoint, cv::Point3f> > &matchKeyPoints,
843 void filterMatches();
846 void initDetector(
const std::string &detectorNames);
847 void initDetectors(
const std::vector<std::string> &detectorNames);
849 void initExtractor(
const std::string &extractorName);
850 void initExtractors(
const std::vector<std::string> &extractorNames);
Definition of the vpMatrix class.
void setRansacIteration(const int nbIter)
class that defines what is a Keypoint. This class provides all the basic elements to implement classe...
void setUseRansacVVS(const bool ransacVVS)
The class provides a data structure for the homogeneous matrices as well as a set of operations on th...
std::vector< std::pair< cv::KeyPoint, cv::KeyPoint > > getMatchQueryToTrainKeyPoints() const
void setRansacThreshold(const double threshold)
void setExtractor(const std::string &extractorName)
Class to define colors available for display functionnalities.
error that can be emited by ViSP classes.
void setDetectors(const std::vector< std::string > &detectorNames)
static const vpColor green
Class that defines what is a point.
cv::Mat getQueryDescriptors() const
void setExtractors(const std::vector< std::string > &extractorNames)
void setMatcher(const std::string &matcherName)
virtual unsigned int buildReference(const vpImage< unsigned char > &I)=0
double getDetectionTime() const
Generic class defining intrinsic camera parameters.
double getMatchingTime() const
void setDetectionMethod(const vpDetectionMethodType &method)
void setUseBruteForceCrossCheck(const bool useCrossCheck)
unsigned int getNbImages() const
void setRansacMinInlierCount(const int minCount)
vpMatrix getCovarianceMatrix() const
virtual void display(const vpImage< unsigned char > &Iref, const vpImage< unsigned char > &Icurrent, unsigned int size=3)=0
void setRansacConsensusPercentage(const double percentage)
virtual unsigned int matchPoint(const vpImage< unsigned char > &I)=0
void setUseAffineDetection(const bool useAffine)
Class that allows keypoints detection (and descriptors extraction) and matching thanks to OpenCV libr...
std::vector< vpImagePoint > getRansacOutliers() const
void setDetectorParameter(const T1 detectorName, const T2 parameterName, const T3 value)
cv::Mat getTrainDescriptors() const
double getExtractionTime() const
double getPoseTime() const
void setDetector(const std::string &detectorName)
Defines a rectangle in the plane.
void setExtractorParameter(const T1 extractorName, const T2 parameterName, const T3 value)
void setUseRansacConsensusPercentage(const bool usePercentage)
Class that defines a 2D point in an image. This class is useful for image processing and stores only ...
std::vector< vpImagePoint > getRansacInliers() const
void setFilterMatchingType(const vpFilterMatchingType &filterType)
void setMatchingFactorThreshold(const double factor)
std::vector< cv::DMatch > getMatches() const
void setRansacReprojectionError(const double reprojectionError)
void setMatchingRatioThreshold(const double ratio)
void setCovarianceComputation(const bool &flag)