diff --git a/src/examples/yaml/fundamental_matrix.yaml b/src/examples/yaml/fundamental_matrix.yaml index da5949a696f6071f752482cd19a2fed564aa9529..ef24ff4c86d73352d05d0c375e2724a852d29dbe 100644 --- a/src/examples/yaml/fundamental_matrix.yaml +++ b/src/examples/yaml/fundamental_matrix.yaml @@ -1,13 +1,13 @@ detector: type: "AGAST" - threshold: 10 + threshold: 9 nonmaxSuppression: true - detection type: 3 # AGAST_5_8=0, AGAST_7_12d=1, AGAST_7_12s=2, OAST_9_16=3, THRESHOLD=10000, NONMAX_SUPPRESSION=10001 + detection type: 0 # AGAST_5_8=0, AGAST_7_12d=1, AGAST_7_12s=2, OAST_9_16=3, THRESHOLD=10000, NONMAX_SUPPRESSION=10001 descriptor: type: "BRIEF" bytes: 32 - use_orientation: false + use_orientation: true matcher: type: "FLANNBASED" # BRUTEFORCE, BRUTEFORCE_HAMMING, BRUTEFORCE_HAMMING_2, BRUTEFORCE_L1, FLANNBASED diff --git a/src/matchers/matcher_base.cpp b/src/matchers/matcher_base.cpp index 8ee93a2e2c58eb57f502a87dd5ef98a359d0af0f..0edd244f3394e17e20dc7b82b3ca3e5eeedd5658 100644 --- a/src/matchers/matcher_base.cpp +++ b/src/matchers/matcher_base.cpp @@ -180,6 +180,55 @@ void MatcherBase::filterByDistance(const int& _max_pixel_dist, const float& _img std::cerr << "[" << name_ << "]: Wrong input type in filterByDistance method." << std::endl; } +void MatcherBase::ransacTest(const DMatchVector& _raw_matches, + const KeyPointVector& _raw_kps1, + const KeyPointVector& _raw_kps2, + DMatchVector& _inlier_matches, + KeyPointVector& _inlier_kps1, + KeyPointVector& _inlier_kps2) +{ + // To be set outside + Scalar distance = 3.0;// distance to epipolar line + Scalar confidence = 0.99; // confidence probability + + + // Convert keypoints into Point2f + PointVector raw_pts1, raw_pts2; + + std::vector<cv::Point2f> raw_pts1, raw_pts2; + for (std::vector<cv::DMatch>::const_iterator it= _raw_matches.begin(); it!= _raw_matches.end(); ++it) + { + raw_pts1.push_back(cv::Point2f(_raw_kps1[it->queryIdx].pt.x, _raw_kps1[it->queryIdx].pt.y)); + raw_pts2.push_back(cv::Point2f(_raw_kps2[it->trainIdx].pt.x, _raw_kps2[it->trainIdx].pt.y)); + } + + // Compute F matrix using RANSAC + std::vector<uchar> inliers(raw_pts1.size(),0); + cv::Mat fundemental= cv::findFundamentalMat(raw_pts1, + raw_pts2, // matching points + inliers, // match status (inlier ou outlier) + CV_FM_RANSAC, // RANSAC method + distance, // distance to epipolar line + confidence); // confidence probability + + // extract the surviving (inliers) matches + std::vector<uchar>::const_iterator itIn = inliers.begin(); + std::vector<cv::DMatch>::const_iterator itM= _raw_matches.begin(); + // for all raw matches + for ( ;itIn!= inliers.end(); ++itIn, ++itM) + { + if (*itIn)// it is a valid match + { + _inlier_matches.push_back(*itM); + _inlier_kps1.push_back(_raw_kps1[itM->queryIdx]); + _inlier_kps2.push_back(_raw_kps1[itM->trainIdx]); + } + } + + std::cout << "Number of matched points (after cleaning): " << _inlier_matches.size() << std::endl; +} + + cv::Mat MatcherBase::drawMatches(const cv::Mat _img1, const cv::Mat _img2, KeyPointVector _kpts12_img1, KeyPointVector _kpts12_img2) { // Concatenate images diff --git a/src/matchers/matcher_base.h b/src/matchers/matcher_base.h index d5710d2b1df4c74366d6c2220c62484fb1ba0cd5..ca30b6011dcc5811b8ec43b2f2b2d01f32f20565 100644 --- a/src/matchers/matcher_base.h +++ b/src/matchers/matcher_base.h @@ -25,9 +25,9 @@ VU_PTR_TYPEDEFS(MatcherBase); VU_STRUCT_PTR_TYPEDEFS(MatcherParamsBase); enum MATCH_TYPE{ - MATCH = 1, - KNNMATCH = 2, - RADIUSMATCH = 3 + MATCH = 1, + KNNMATCH = 2, + RADIUSMATCH = 3 }; /** \brief Class parameters @@ -35,13 +35,13 @@ enum MATCH_TYPE{ */ struct MatcherParamsBase: public ParamsBase { - std::string type; - int match_type = MATCH; // Type of Match. MATCH = 1, KNNMATCH = 2, RADIUSMATCH = 3 - int roi_width = 20; // ROI width around a keypoint to search for a match. - int roi_height = 20; // ROI height around a keypoint to search for a match. - double min_norm_score; //< [-1..0]: awful match; 1: perfect match; out of [-1,1]: error - MatcherParamsBase(const std::string& _type): type(_type){} - virtual ~MatcherParamsBase(){} + std::string type; + int match_type = MATCH; // Type of Match. MATCH = 1, KNNMATCH = 2, RADIUSMATCH = 3 + int roi_width = 20; // ROI width around a keypoint to search for a match. + int roi_height = 20; // ROI height around a keypoint to search for a match. + double min_norm_score; //< [-1..0]: awful match; 1: perfect match; out of [-1,1]: error + MatcherParamsBase(const std::string& _type): type(_type){} + virtual ~MatcherParamsBase(){} }; /** \brief base class for Matcher base @@ -50,7 +50,7 @@ struct MatcherParamsBase: public ParamsBase */ class MatcherBase : public VUBase, public std::enable_shared_from_this<MatcherBase> { - public: + public: /** * \brief Constructor without parameters @@ -72,23 +72,77 @@ class MatcherBase : public VUBase, public std::enable_shared_from_this<MatcherBa void setParams(const MatcherParamsBasePtr _params); - std::vector<Scalar> match(const cv::Mat& _desc1, const cv::Mat& _desc2, const int& desc_size_bytes, DMatchVector& matches, cv::InputArray _mask=cv::noArray()); - std::vector<Scalar> match(const cv::Mat& _desc1, const cv::Mat& _desc2, const int& desc_size_bytes, std::vector< DMatchVector >& matches, cv::InputArray _mask=cv::noArray()); - Scalar match(const cv::Mat& _desc1, const cv::Mat& _desc2, const int& desc_size_bytes, cv::DMatch& _match); - - void filterByDistance(const int& _max_pixel_dist, const float& _percentage, const KeyPointVector& _kpts1,const KeyPointVector& _kpts2, const DMatchVector& _dirty, const int& _img_width, const int& _img_height, DMatchVector& _filtered_matches, KeyPointVector& _filtered_kpts, KeyPointVector& _filtered_kpts_prev); - void filterByDistance(const int& _max_pixel_dist, const float& _percentage, const KeyPointVector& _kpts1,const KeyPointVector& _kpts2, const std::vector< DMatchVector >& _dirty, const int& _img_width, const int& _img_height, DMatchVector& _filtered_matches, KeyPointVector& _filtered_kpts, KeyPointVector& _filtered_kpts_prev); + std::vector<Scalar> match(const cv::Mat& _desc1, + const cv::Mat& _desc2, + const int& desc_size_bytes, + DMatchVector& matches, + cv::InputArray _mask=cv::noArray()); + + std::vector<Scalar> match(const cv::Mat& _desc1, + const cv::Mat& _desc2, + const int& desc_size_bytes, + std::vector< DMatchVector >& matches, + cv::InputArray _mask=cv::noArray()); + + Scalar match(const cv::Mat& _desc1, + const cv::Mat& _desc2, + const int& desc_size_bytes, + cv::DMatch& _match); + + // Identify good matches using RANSAC + void ransacTest(const DMatchVector& _raw_matches, + const KeyPointVector& _raw_kps1, + const KeyPointVector& _raw_kps2, + DMatchVector& _inlier_matches, + KeyPointVector& _inlier_kps1, + KeyPointVector& _inlier_kps2); + + void filterByDistance(const int& _max_pixel_dist, + const float& _percentage, + const KeyPointVector& _kpts1, + const KeyPointVector& _kpts2, + const DMatchVector& _dirty, + const int& _img_width, + const int& _img_height, + DMatchVector& _filtered_matches, + KeyPointVector& _filtered_kpts, + KeyPointVector& _filtered_kpts_prev); + void filterByDistance(const int& _max_pixel_dist, + const float& _percentage, + const KeyPointVector& _kpts1, + const KeyPointVector& _kpts2, + const std::vector< DMatchVector >& _dirty, + const int& _img_width, + const int& _img_height, + DMatchVector& _filtered_matches, + KeyPointVector& _filtered_kpts, + KeyPointVector& _filtered_kpts_prev); // Factory method - static MatcherBasePtr create(const std::string& _unique_name, const ParamsBasePtr _params); - - cv::Mat drawMatches(const cv::Mat _img1, const cv::Mat _img2, KeyPointVector _kpts12_img1, KeyPointVector _kpts12_img2); - - cv::Mat drawMatches(const cv::Mat& _img1, const cv::Mat& _img2, const cv::Mat& _img3, KeyPointVector _kpts12_img1, KeyPointVector _kpts12_img2, KeyPointVector _kpts23_img2, KeyPointVector _kpts23_img3); - - cv::Mat drawMatches(const cv::Mat& _img1, const cv::Mat& _img2, const cv::Mat& _img3, KeyPointVector _kpts123_img1, KeyPointVector _kpts123_img2, KeyPointVector _kpts123_img3); - - protected: + static MatcherBasePtr create(const std::string& _unique_name, + const ParamsBasePtr _params); + + cv::Mat drawMatches(const cv::Mat _img1, + const cv::Mat _img2, + KeyPointVector _kpts12_img1, + KeyPointVector _kpts12_img2); + + cv::Mat drawMatches(const cv::Mat& _img1, + const cv::Mat& _img2, + const cv::Mat& _img3, + KeyPointVector _kpts12_img1, + KeyPointVector _kpts12_img2, + KeyPointVector _kpts23_img2, + KeyPointVector _kpts23_img3); + + cv::Mat drawMatches(const cv::Mat& _img1, + const cv::Mat& _img2, + const cv::Mat& _img3, + KeyPointVector _kpts123_img1, + KeyPointVector _kpts123_img2, + KeyPointVector _kpts123_img3); + + protected: std::string name_;