1 #include <stdio.h> 2 #include <iostream> 3 #include "opencv2/core/core.hpp" 4 #include "opencv2/features2d/features2d.hpp" 5 #include "opencv2/highgui/highgui.hpp" 6 7 using namespace cv; 8 9 void readme(); 10 11 /** @function main */ 12 int main( int argc, char** argv ) 13 { 14 if( argc != 3 ) 15 { readme(); return -1; } 16 17 Mat img_1 = imread( argv[1], CV_LOAD_IMAGE_GRAYSCALE ); 18 Mat img_2 = imread( argv[2], CV_LOAD_IMAGE_GRAYSCALE ); 19 20 if( !img_1.data || !img_2.data ) 21 { std::cout<< " --(!) Error reading images " << std::endl; return -1; } 22 23 //-- Step 1: Detect the keypoints using SURF Detector 24 int minHessian = 400; 25 26 SurfFeatureDetector detector( minHessian ); 27 28 std::vector<KeyPoint> keypoints_1, keypoints_2; 29 30 detector.detect( img_1, keypoints_1 ); 31 detector.detect( img_2, keypoints_2 ); 32 33 //-- Step 2: Calculate descriptors (feature vectors) 34 SurfDescriptorExtractor extractor; 35 36 Mat descriptors_1, descriptors_2; 37 38 extractor.compute( img_1, keypoints_1, descriptors_1 ); 39 extractor.compute( img_2, keypoints_2, descriptors_2 ); 40 41 //-- Step 3: Matching descriptor vectors using FLANN matcher 42 FlannBasedMatcher matcher; 43 std::vector< DMatch > matches; 44 matcher.match( descriptors_1, descriptors_2, matches ); 45 46 double max_dist = 0; double min_dist = 100; 47 48 //-- Quick calculation of max and min distances between keypoints 49 for( int i = 0; i < descriptors_1.rows; i++ ) 50 { double dist = matches[i].distance; 51 if( dist < min_dist ) min_dist = dist; 52 if( dist > max_dist ) max_dist = dist; 53 } 54 55 printf("-- Max dist : %f \n", max_dist ); 56 printf("-- Min dist : %f \n", min_dist ); 57 58 //-- Draw only "good" matches (i.e. whose distance is less than 2*min_dist ) 59 //-- PS.- radiusMatch can also be used here. 60 std::vector< DMatch > good_matches; 61 62 for( int i = 0; i < descriptors_1.rows; i++ ) 63 { if( matches[i].distance < 2*min_dist ) 64 { good_matches.push_back( matches[i]); } 65 } 66 67 //-- Draw only "good" matches 68 Mat img_matches; 69 drawMatches( img_1, keypoints_1, img_2, keypoints_2, 70 good_matches, img_matches, Scalar::all(-1), Scalar::all(-1), 71 vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS ); 72 73 //-- Show detected matches 74 imshow( "Good Matches", img_matches ); 75 76 for( int i = 0; i < good_matches.size(); i++ ) 77 { printf( "-- Good Match [%d] Keypoint 1: %d -- Keypoint 2: %d \n", i, good_matches[i].queryIdx, good_matches[i].trainIdx ); } 78 79 waitKey(0); 80 81 return 0; 82 } 83 84 /** @function readme */ 85 void readme() 86 { std::cout << " Usage: ./SURF_FlannMatcher <img1> <img2>" << std::endl; }