diff --git a/src/examples/yaml/ACTIVESEARCH.yaml b/src/examples/yaml/ACTIVESEARCH.yaml index 1f6a69213de6647d3e2849de3c92279d6fa6e83e..7dcc3e5cb260e6428b52ede79e962755c6f7961a 100644 --- a/src/examples/yaml/ACTIVESEARCH.yaml +++ b/src/examples/yaml/ACTIVESEARCH.yaml @@ -27,6 +27,9 @@ matcher: type: "FLANNBASED" match type: 1 # Match type. MATCH = 1, KNNMATCH = 2, RADIUSMATCH = 3 min normalized score: 0.85 + filtering: + ransac epipolar distance: 3 # Distance to epipolar [pixels] + ransac confidence prob: 0.97 # Confidence probability algorithm: type: "ACTIVESEARCH" diff --git a/src/examples/yaml/BRUTEFORCE.yaml b/src/examples/yaml/BRUTEFORCE.yaml index 5edfa46f734e157bbc8b785f5624eb8a23a299de..65715f3596f5359eb4674b55a29196e0dd81df6d 100644 --- a/src/examples/yaml/BRUTEFORCE.yaml +++ b/src/examples/yaml/BRUTEFORCE.yaml @@ -3,3 +3,7 @@ sensor: matcher: type: "BRUTEFORCE" + match type: 1 # Match type. MATCH = 1, KNNMATCH = 2, RADIUSMATCH = 3 + filtering: + ransac epipolar distance: 3 # Distance to epipolar [pixels] + ransac confidence prob: 0.97 # Confidence probability \ No newline at end of file diff --git a/src/examples/yaml/BRUTEFORCE_HAMMING.yaml b/src/examples/yaml/BRUTEFORCE_HAMMING.yaml index 42e63bcd38a163fb826ce967a23ebe00187f52ca..53f97299301719f89459b3b8ff8d662e49798b93 100644 --- a/src/examples/yaml/BRUTEFORCE_HAMMING.yaml +++ b/src/examples/yaml/BRUTEFORCE_HAMMING.yaml @@ -4,3 +4,6 @@ sensor: matcher: type: "BRUTEFORCE_HAMMING" match type: 1 # Match type. MATCH = 1, KNNMATCH = 2, RADIUSMATCH = 3 + filtering: + ransac epipolar distance: 3 # Distance to epipolar [pixels] + ransac confidence prob: 0.97 # Confidence probability \ No newline at end of file diff --git a/src/examples/yaml/BRUTEFORCE_HAMMING_2.yaml b/src/examples/yaml/BRUTEFORCE_HAMMING_2.yaml index fb95ed69bd93a53a1bee4d66366de5e3a7690960..e43ae7a08bf11ec2534567631f530b8567ab0295 100644 --- a/src/examples/yaml/BRUTEFORCE_HAMMING_2.yaml +++ b/src/examples/yaml/BRUTEFORCE_HAMMING_2.yaml @@ -4,3 +4,6 @@ sensor: matcher: type: "BRUTEFORCE_HAMMING_2" match type: 1 # Match type. MATCH = 1, KNNMATCH = 2, RADIUSMATCH = 3 + filtering: + ransac epipolar distance: 3 # Distance to epipolar [pixels] + ransac confidence prob: 0.97 # Confidence probability \ No newline at end of file diff --git a/src/examples/yaml/BRUTEFORCE_L1.yaml b/src/examples/yaml/BRUTEFORCE_L1.yaml index 73ebe115e60b6b70962412e295e48c96dbd2c7fa..e9bd4afdc1f63a614e8ad8915b312b02050b71ce 100644 --- a/src/examples/yaml/BRUTEFORCE_L1.yaml +++ b/src/examples/yaml/BRUTEFORCE_L1.yaml @@ -4,3 +4,6 @@ sensor: matcher: type: "BRUTEFORCE_L1" match type: 1 # Match type. MATCH = 1, KNNMATCH = 2, RADIUSMATCH = 3 + filtering: + ransac epipolar distance: 3 # Distance to epipolar [pixels] + ransac confidence prob: 0.97 # Confidence probability \ No newline at end of file diff --git a/src/examples/yaml/FLANNBASED.yaml b/src/examples/yaml/FLANNBASED.yaml index 67900bea6add5ca691408a697394f4eccd7d5bd3..e7d046ade12bfd62fbc41bb26d258a1220af4810 100644 --- a/src/examples/yaml/FLANNBASED.yaml +++ b/src/examples/yaml/FLANNBASED.yaml @@ -3,4 +3,7 @@ sensor: matcher: type: "FLANNBASED" - match type: 1 # Match type. MATCH = 1, KNNMATCH = 2, RADIUSMATCH = 3 \ No newline at end of file + match type: 1 # Match type. MATCH = 1, KNNMATCH = 2, RADIUSMATCH = 3 + filtering: + ransac epipolar distance: 3 # Distance to epipolar [pixels] + ransac confidence prob: 0.97 # Confidence probability \ No newline at end of file diff --git a/src/examples/yaml/TRACKFEATURES.yaml b/src/examples/yaml/TRACKFEATURES.yaml index 378bf044d875d7d868cd98f6e8159865d704935b..bee58a1fbfcecac501c32db81168f73fef8209fa 100644 --- a/src/examples/yaml/TRACKFEATURES.yaml +++ b/src/examples/yaml/TRACKFEATURES.yaml @@ -24,10 +24,16 @@ matcher: type: "FLANNBASED" match type: 1 # Match type. MATCH = 1, KNNMATCH = 2, RADIUSMATCH = 3 min normalized score: 0.85 + filtering: + ransac epipolar distance: 3 # Distance to epipolar [pixels] + ransac confidence prob: 0.97 # Confidence probability algorithm: type: "TRACKFEATURES" draw results: true min features to track: 10 max new features: 100 - min response new features: 80 \ No newline at end of file + min response new features: 80 + target roi: + width: 20 + height: 20 \ No newline at end of file diff --git a/src/matchers/bruteforce/matcher_bruteforce_load_yaml.cpp b/src/matchers/bruteforce/matcher_bruteforce_load_yaml.cpp index 3dd4bd17debdcb41314402835a078cd801170dfa..7142209f001e35434ba86e227807c537c874fa35 100644 --- a/src/matchers/bruteforce/matcher_bruteforce_load_yaml.cpp +++ b/src/matchers/bruteforce/matcher_bruteforce_load_yaml.cpp @@ -27,6 +27,11 @@ static ParamsBasePtr createParamsBRUTEFORCEMatcher(const std::string & _filename params_ptr->match_type = d_yaml["match type"].as<int>(); if (d_yaml["min normalized score"]) params_ptr->min_norm_score = d_yaml["min normalized score"].as<double>(); + Node filters = d_yaml["filtering"]; + if (filters["ransac epipolar distance"]) + params_ptr->ransac_epipolar_distance = filters["ransac epipolar distance"].as<double>(); + if (filters["ransac confidence prob"]) + params_ptr->ransac_confidence_prob = filters["ransac confidence prob"].as<double>(); }else { std::cerr << "Bad configuration file. Wrong type " << d_yaml["type"].as<string>() << std::endl; diff --git a/src/matchers/matcher_base.cpp b/src/matchers/matcher_base.cpp index 0edd244f3394e17e20dc7b82b3ca3e5eeedd5658..f7eafd1b17991a61073fd42c2b4dbb6e17e7dc59 100644 --- a/src/matchers/matcher_base.cpp +++ b/src/matchers/matcher_base.cpp @@ -180,22 +180,15 @@ 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, +void MatcherBase::ransacTest(const KeyPointVector& _raw_kps1, const KeyPointVector& _raw_kps2, - DMatchVector& _inlier_matches, + const DMatchVector& _raw_matches, KeyPointVector& _inlier_kps1, - KeyPointVector& _inlier_kps2) + KeyPointVector& _inlier_kps2, + DMatchVector& _inlier_matches) { - // 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)); @@ -205,11 +198,11 @@ void MatcherBase::ransacTest(const DMatchVector& _raw_matches, // 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 + raw_pts2, // matching points + inliers, // match status (inlier ou outlier) + CV_FM_RANSAC, // RANSAC method + params_base_ptr_->ransac_epipolar_distance, // distance to epipolar line + params_base_ptr_->ransac_confidence_prob); // confidence probability // extract the surviving (inliers) matches std::vector<uchar>::const_iterator itIn = inliers.begin(); @@ -224,8 +217,6 @@ void MatcherBase::ransacTest(const DMatchVector& _raw_matches, _inlier_kps2.push_back(_raw_kps1[itM->trainIdx]); } } - - std::cout << "Number of matched points (after cleaning): " << _inlier_matches.size() << std::endl; } diff --git a/src/matchers/matcher_base.h b/src/matchers/matcher_base.h index 39c73509ac6f620b963ef393c60a9b37b4c80fdb..73a05b6dd4f397fcf01816466902b55a0d18cc65 100644 --- a/src/matchers/matcher_base.h +++ b/src/matchers/matcher_base.h @@ -36,8 +36,11 @@ enum MATCH_TYPE{ struct MatcherParamsBase: public ParamsBase { std::string type; - int match_type = MATCH; // Type of Match. MATCH = 1, KNNMATCH = 2, RADIUSMATCH = 3 + int match_type = MATCH; //< Type of Match. MATCH = 1, KNNMATCH = 2, RADIUSMATCH = 3 double min_norm_score; //< [-1..0]: awful match; 1: perfect match; out of [-1,1]: error + Scalar ransac_epipolar_distance; //< distance to epipolar line + Scalar ransac_confidence_prob; //< confidence probability + MatcherParamsBase(const std::string& _type): type(_type){} virtual ~MatcherParamsBase(){} }; @@ -88,12 +91,12 @@ class MatcherBase : public VUBase, public std::enable_shared_from_this<MatcherBa cv::DMatch& _match); // Identify good matches using RANSAC - void ransacTest(const DMatchVector& _raw_matches, - const KeyPointVector& _raw_kps1, + void ransacTest(const KeyPointVector& _raw_kps1, const KeyPointVector& _raw_kps2, - DMatchVector& _inlier_matches, + const DMatchVector& _raw_matches, KeyPointVector& _inlier_kps1, - KeyPointVector& _inlier_kps2); + KeyPointVector& _inlier_kps2, + DMatchVector& _inlier_matches); void filterByDistance(const int& _max_pixel_dist, const float& _percentage, diff --git a/src/test/data/ACTIVESEARCH.yaml b/src/test/data/ACTIVESEARCH.yaml index 04333b0f33bd0b83e685e50fc6a0d11ad6c94bb0..9fab948877fc630f462801366c9ad1bdac6f98ee 100644 --- a/src/test/data/ACTIVESEARCH.yaml +++ b/src/test/data/ACTIVESEARCH.yaml @@ -27,6 +27,9 @@ matcher: type: "FLANNBASED" match type: 1 # Match type. MATCH = 1, KNNMATCH = 2, RADIUSMATCH = 3 min normalized score: 0.85 + filtering: + ransac epipolar distance: 3 # Distance to epipolar [pixels] + ransac confidence prob: 0.97 # Confidence probability algorithm: type: "ACTIVESEARCH" diff --git a/src/test/data/BRUTEFORCE.yaml b/src/test/data/BRUTEFORCE.yaml index 3af86a3f82b84c3b788ee02ec120e1d535ec38a8..4ee5f19325988479ea744a098435919de284dc9c 100644 --- a/src/test/data/BRUTEFORCE.yaml +++ b/src/test/data/BRUTEFORCE.yaml @@ -3,3 +3,6 @@ sensor: matcher: type: "BRUTEFORCE" match type: 1 # Match type. MATCH = 1, KNNMATCH = 2, RADIUSMATCH = 3 + filtering: + ransac epipolar distance: 3 # Distance to epipolar [pixels] + ransac confidence prob: 0.97 # Confidence probability \ No newline at end of file diff --git a/src/test/data/BRUTEFORCE_HAMMING.yaml b/src/test/data/BRUTEFORCE_HAMMING.yaml index 081dd31ba753865c75286014b69027b5bf5a8755..248752a8d7f9bb50faef8cf2cb8c43283c10e808 100644 --- a/src/test/data/BRUTEFORCE_HAMMING.yaml +++ b/src/test/data/BRUTEFORCE_HAMMING.yaml @@ -3,3 +3,6 @@ sensor: matcher: type: "BRUTEFORCE_HAMMING" match type: 1 # Match type. MATCH = 1, KNNMATCH = 2, RADIUSMATCH = 3 + filtering: + ransac epipolar distance: 3 # Distance to epipolar [pixels] + ransac confidence prob: 0.97 # Confidence probability \ No newline at end of file diff --git a/src/test/data/BRUTEFORCE_HAMMING_2.yaml b/src/test/data/BRUTEFORCE_HAMMING_2.yaml index 0da3073ce04918e19cc94e8aebd35b7922ff54b5..d415f81318b11973f00c7a304fbc3d24c19c8830 100644 --- a/src/test/data/BRUTEFORCE_HAMMING_2.yaml +++ b/src/test/data/BRUTEFORCE_HAMMING_2.yaml @@ -3,3 +3,6 @@ sensor: matcher: type: "BRUTEFORCE_HAMMING_2" match type: 1 # Match type. MATCH = 1, KNNMATCH = 2, RADIUSMATCH = 3 + filtering: + ransac epipolar distance: 3 # Distance to epipolar [pixels] + ransac confidence prob: 0.97 # Confidence probability \ No newline at end of file diff --git a/src/test/data/BRUTEFORCE_L1.yaml b/src/test/data/BRUTEFORCE_L1.yaml index 128fcf4366ca896f4f79a1cdf2ea8fc4facc9841..23d7c087edca40a194e7078fe02c1034a3c10e4d 100644 --- a/src/test/data/BRUTEFORCE_L1.yaml +++ b/src/test/data/BRUTEFORCE_L1.yaml @@ -2,4 +2,7 @@ sensor: type: "USB_CAM" matcher: type: "BRUTEFORCE_L1" - match type: 1 # Match type. MATCH = 1, KNNMATCH = 2, RADIUSMATCH = 3 + match type: 1 # Match type. MATCH = 1, KNNMATCH = 2, RADIUSMATCH = 3 + filtering: + ransac epipolar distance: 3 # Distance to epipolar [pixels] + ransac confidence prob: 0.97 # Confidence probability \ No newline at end of file diff --git a/src/test/data/FLANNBASED.yaml b/src/test/data/FLANNBASED.yaml index 67900bea6add5ca691408a697394f4eccd7d5bd3..e7d046ade12bfd62fbc41bb26d258a1220af4810 100644 --- a/src/test/data/FLANNBASED.yaml +++ b/src/test/data/FLANNBASED.yaml @@ -3,4 +3,7 @@ sensor: matcher: type: "FLANNBASED" - match type: 1 # Match type. MATCH = 1, KNNMATCH = 2, RADIUSMATCH = 3 \ No newline at end of file + match type: 1 # Match type. MATCH = 1, KNNMATCH = 2, RADIUSMATCH = 3 + filtering: + ransac epipolar distance: 3 # Distance to epipolar [pixels] + ransac confidence prob: 0.97 # Confidence probability \ No newline at end of file diff --git a/src/test/data/TRACKFEATURES.yaml b/src/test/data/TRACKFEATURES.yaml index 43d5a68981d9107339ddd92b84619ae7aa4c279f..38150db1dadf66e3b4f6c4c79a3f871b6e70ef8a 100644 --- a/src/test/data/TRACKFEATURES.yaml +++ b/src/test/data/TRACKFEATURES.yaml @@ -24,10 +24,16 @@ matcher: type: "FLANNBASED" match type: 1 # Match type. MATCH = 1, KNNMATCH = 2, RADIUSMATCH = 3 min normalized score: 0.85 + filtering: + ransac epipolar distance: 3 # Distance to epipolar [pixels] + ransac confidence prob: 0.97 # Confidence probability algorithm: type: "TRACKFEATURES" draw results: true min features to track: 10 max new features: 100 - min response new features: 80 \ No newline at end of file + min response new features: 80 + target roi: + width: 20 + height: 20 \ No newline at end of file diff --git a/src/test/data/base_classes.yaml b/src/test/data/base_classes.yaml index 9f8fabd1f46edf5c63e27371a4438c93affbfec6..5fedf9f4c53cd888e5c41c321d7478e2e426dd2e 100644 --- a/src/test/data/base_classes.yaml +++ b/src/test/data/base_classes.yaml @@ -27,6 +27,9 @@ matcher: type: "BRUTEFORCE" match type: 1 # Match type. MATCH = 1, KNNMATCH = 2, RADIUSMATCH = 3 min normalized score: 0.85 + filtering: + ransac epipolar distance: 3 # Distance to epipolar [pixels] + ransac confidence prob: 0.97 # Confidence probability algorithm: type: "OPTFLOWPYRLK" diff --git a/src/test/gtest_matcher_base.cpp b/src/test/gtest_matcher_base.cpp index 72329fd366a7925d8199f992ed6591d1d1424c70..f630872c8b3327f1501f388c9ca6720557fdab60 100644 --- a/src/test/gtest_matcher_base.cpp +++ b/src/test/gtest_matcher_base.cpp @@ -48,6 +48,60 @@ TEST(MatcherBase, getParams) ASSERT_EQ(params->match_type,1); } +TEST(MatcherBase, ransacTest) +{ + cv::Mat image1 = cv::imread(filename1, CV_LOAD_IMAGE_GRAYSCALE); + ASSERT_TRUE(image1.data)<< "Failed to load image " << filename1 << std::endl; + cv::Mat image2 = cv::imread(filename2, CV_LOAD_IMAGE_GRAYSCALE); + ASSERT_TRUE(image1.data)<< "Failed to load image " << filename2 << std::endl; + + // Define detector + std::string det_name = vision_utils::readYamlType(yaml_file_params, "detector"); + ASSERT_TRUE(det_name.compare("ORB")==0); + vision_utils::DetectorBasePtr det_ptr = vision_utils::setupDetector(det_name, det_name + " detector", yaml_file_params); + det_ptr = std::static_pointer_cast<vision_utils::DetectorORB>(det_ptr); + ASSERT_TRUE(det_ptr!=NULL); + + // Define descriptor + std::string des_name = vision_utils::readYamlType(yaml_file_params, "descriptor"); + ASSERT_TRUE(des_name.compare("ORB")==0); + vision_utils::DescriptorBasePtr des_ptr = vision_utils::setupDescriptor(des_name, des_name + " descriptor", yaml_file_params); + des_ptr = std::static_pointer_cast<vision_utils::DescriptorORB>(des_ptr); + ASSERT_TRUE(des_ptr!=NULL); + + // Image 1 + KeyPointVector kpts1 = det_ptr->detect(image1); + cv::Mat desc1 = des_ptr->getDescriptor(image1,kpts1); + ASSERT_TRUE(kpts1.size() == desc1.rows); + + // Image 2 + KeyPointVector kpts2 = det_ptr->detect(image2); + cv::Mat desc2 = des_ptr->getDescriptor(image2,kpts2); + ASSERT_TRUE(kpts2.size() == desc2.rows); + + // Define matcher + vision_utils::MatcherParamsBasePtr params_ptr = std::make_shared<vision_utils::MatcherParamsBase>(matcher_name); + vision_utils::MatcherBasePtr mat_ptr; + + // MATCH type + params_ptr->match_type = vision_utils::MATCH; + mat_ptr = vision_utils::setupMatcher(matcher_name, matcher_name, params_ptr); + params_ptr = mat_ptr->getParams(); + ASSERT_EQ(params_ptr->match_type,1); + + // match + DMatchVector matches; + mat_ptr->match(desc1,desc2,des_ptr->getSize(),matches); + ASSERT_TRUE(matches.size()-75>0); + + KeyPointVector inlier_kpts1; + KeyPointVector inlier_kpts2; + DMatchVector inlier_matches; + mat_ptr->ransacTest(kpts1, kpts2, matches, + inlier_kpts1, inlier_kpts2, inlier_matches); + ASSERT_TRUE(inlier_matches.size()<23); +} + int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv);