1/* 2 * RobustMatcher.cpp 3 * 4 * Created on: Jun 4, 2014 5 * Author: eriba 6 */ 7 8#include "RobustMatcher.h" 9#include <time.h> 10 11#include <opencv2/features2d/features2d.hpp> 12 13RobustMatcher::~RobustMatcher() 14{ 15 // TODO Auto-generated destructor stub 16} 17 18void RobustMatcher::computeKeyPoints( const cv::Mat& image, std::vector<cv::KeyPoint>& keypoints) 19{ 20 detector_->detect(image, keypoints); 21} 22 23void RobustMatcher::computeDescriptors( const cv::Mat& image, std::vector<cv::KeyPoint>& keypoints, cv::Mat& descriptors) 24{ 25 extractor_->compute(image, keypoints, descriptors); 26} 27 28int RobustMatcher::ratioTest(std::vector<std::vector<cv::DMatch> > &matches) 29{ 30 int removed = 0; 31 // for all matches 32 for ( std::vector<std::vector<cv::DMatch> >::iterator 33 matchIterator= matches.begin(); matchIterator!= matches.end(); ++matchIterator) 34 { 35 // if 2 NN has been identified 36 if (matchIterator->size() > 1) 37 { 38 // check distance ratio 39 if ((*matchIterator)[0].distance / (*matchIterator)[1].distance > ratio_) 40 { 41 matchIterator->clear(); // remove match 42 removed++; 43 } 44 } 45 else 46 { // does not have 2 neighbours 47 matchIterator->clear(); // remove match 48 removed++; 49 } 50 } 51 return removed; 52} 53 54void RobustMatcher::symmetryTest( const std::vector<std::vector<cv::DMatch> >& matches1, 55 const std::vector<std::vector<cv::DMatch> >& matches2, 56 std::vector<cv::DMatch>& symMatches ) 57{ 58 59 // for all matches image 1 -> image 2 60 for (std::vector<std::vector<cv::DMatch> >::const_iterator 61 matchIterator1 = matches1.begin(); matchIterator1 != matches1.end(); ++matchIterator1) 62 { 63 64 // ignore deleted matches 65 if (matchIterator1->empty() || matchIterator1->size() < 2) 66 continue; 67 68 // for all matches image 2 -> image 1 69 for (std::vector<std::vector<cv::DMatch> >::const_iterator 70 matchIterator2 = matches2.begin(); matchIterator2 != matches2.end(); ++matchIterator2) 71 { 72 // ignore deleted matches 73 if (matchIterator2->empty() || matchIterator2->size() < 2) 74 continue; 75 76 // Match symmetry test 77 if ((*matchIterator1)[0].queryIdx == 78 (*matchIterator2)[0].trainIdx && 79 (*matchIterator2)[0].queryIdx == 80 (*matchIterator1)[0].trainIdx) 81 { 82 // add symmetrical match 83 symMatches.push_back( 84 cv::DMatch((*matchIterator1)[0].queryIdx, 85 (*matchIterator1)[0].trainIdx, 86 (*matchIterator1)[0].distance)); 87 break; // next match in image 1 -> image 2 88 } 89 } 90 } 91 92} 93 94void RobustMatcher::robustMatch( const cv::Mat& frame, std::vector<cv::DMatch>& good_matches, 95 std::vector<cv::KeyPoint>& keypoints_frame, const cv::Mat& descriptors_model ) 96{ 97 98 // 1a. Detection of the ORB features 99 this->computeKeyPoints(frame, keypoints_frame); 100 101 // 1b. Extraction of the ORB descriptors 102 cv::Mat descriptors_frame; 103 this->computeDescriptors(frame, keypoints_frame, descriptors_frame); 104 105 // 2. Match the two image descriptors 106 std::vector<std::vector<cv::DMatch> > matches12, matches21; 107 108 // 2a. From image 1 to image 2 109 matcher_->knnMatch(descriptors_frame, descriptors_model, matches12, 2); // return 2 nearest neighbours 110 111 // 2b. From image 2 to image 1 112 matcher_->knnMatch(descriptors_model, descriptors_frame, matches21, 2); // return 2 nearest neighbours 113 114 // 3. Remove matches for which NN ratio is > than threshold 115 // clean image 1 -> image 2 matches 116 ratioTest(matches12); 117 // clean image 2 -> image 1 matches 118 ratioTest(matches21); 119 120 // 4. Remove non-symmetrical matches 121 symmetryTest(matches12, matches21, good_matches); 122 123} 124 125void RobustMatcher::fastRobustMatch( const cv::Mat& frame, std::vector<cv::DMatch>& good_matches, 126 std::vector<cv::KeyPoint>& keypoints_frame, 127 const cv::Mat& descriptors_model ) 128{ 129 good_matches.clear(); 130 131 // 1a. Detection of the ORB features 132 this->computeKeyPoints(frame, keypoints_frame); 133 134 // 1b. Extraction of the ORB descriptors 135 cv::Mat descriptors_frame; 136 this->computeDescriptors(frame, keypoints_frame, descriptors_frame); 137 138 // 2. Match the two image descriptors 139 std::vector<std::vector<cv::DMatch> > matches; 140 matcher_->knnMatch(descriptors_frame, descriptors_model, matches, 2); 141 142 // 3. Remove matches for which NN ratio is > than threshold 143 ratioTest(matches); 144 145 // 4. Fill good matches container 146 for ( std::vector<std::vector<cv::DMatch> >::iterator 147 matchIterator= matches.begin(); matchIterator!= matches.end(); ++matchIterator) 148 { 149 if (!matchIterator->empty()) good_matches.push_back((*matchIterator)[0]); 150 } 151 152} 153