識別特徵點並實現匹配
博主剛剛入門SLAM,之後可能會更多分享SLAM相關的學習總結。
剛剛學習1個多星期的SLAM,感覺自己的知識基礎、論文閱讀能力嚴重不足。幸好有高翔的《視覺SLAM十四講》,由此書入門,覺得更容易了一些。之後應該會把全書通讀一遍,而後找時間進行筆記整理和分享,也便於自己以後的複習。
我是看過1,2講後直接入手第7講,由於有需求的督促想盡快達到應用級別的瞭解,後續再補上數學基礎。
紙上得來終覺淺,深知此事要躬行。讀懂ch7的代碼後,博主重寫了一遍以加深印象,也加了一些備註以共查看。
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace std;
using namespace cv;
int main ( int argc, char** argv )
{
if ( argc != 3 )
{
cout<<"usage: feature_extraction img1 img2"<<endl;
return 1;
}
//1.Input two pictures
Mat img_1 = imread( argv[1], CV_LOAD_IMAGE_COLOR );
Mat img_2 = imread( argv[2], CV_LOAD_IMAGE_COLOR );
//2.perpararory work
//(1)Save key points(FAST)
std::vector<KeyPoint> keypoints_1, Keypoints_2;
//(2)Save descriptors (BRIEF)
Mat descriptors_1, descriptors_2;
//(3)Save results of matching
std::vector<DMatch> matches;
//(4)Create KeyPoint detector( a tool for geting keypoints)
Ptr<FeatureDetector> detector = ORB::create();
//(5)Create descriptor extractor( a tool for geting descriptor)
Ptr<DescriptorExtractor> extractor = ORB::create();
//(6)Create descriptor matcher( a tool for geting keypoint pairing in two pictures by descriptor)
Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create( "BruteForce-Hamming" );
//3.Get key points
detector->detect( img_1, keypoints_1 );
detector->detect( img_2, Keypoints_2 );
//4.Draw key points and disply the image
Mat outimg_1;
drawKeypoints( img_1, keypoints_1, outimg_1, Scalar::all(-1), DrawMatchesFlags::DEFAULT);
imshow( "ORB key points" , outimg_1 );
//5.Get keypoints descriptions
extractor->compute(img_1, keypoints_1, descriptors_1);
extractor->compute(img_2, Keypoints_2, descriptors_2);
//6.Get matches
matcher->match(descriptors_1, descriptors_2, matches);
//7.Draw all matches and disply picture
Mat img_match;
drawMatches(img_1, keypoints_1, img_2, Keypoints_2, matches, img_match);
imshow( "all matches" , img_match );
//8.Remove inaccurate matches(optimization)
//Get minimum and maximum distances
double min_dist=100000.0, max_dist=0.0;
for(int i=0; i<descriptors_1.rows; i++){
double temp_dist = matches[i].distance;
if(min_dist>temp_dist) min_dist = temp_dist;
if(max_dist<temp_dist) max_dist = temp_dist;
}
//Ouput minimum and maximum distances
cout<<"maximum distance: "<<max_dist<<endl;
cout<<"minimum distance: "<<min_dist<<endl;
//Remove inaccurate matches
std::vector<DMatch> accurate_match;
for(int i=0; i<descriptors_1.rows; i++){
if( matches[i].distance < max(min_dist*2, 40.0) )
accurate_match.push_back(matches[i]);
}
//Show result
Mat img_accurate_match;
drawMatches(img_1, keypoints_1, img_2, Keypoints_2, accurate_match, img_accurate_match);
imshow( "opimized matches" , img_accurate_match );
//pause
waitKey(0);
return 0;
}