1 #include <opencv2/features2d.hpp> 2 #include <opencv2/imgcodecs.hpp> 3 #include <opencv2/opencv.hpp> 4 #include <vector> 5 #include <iostream> 6 7 using namespace std; 8 using namespace cv; 9 10 const float inlier_threshold = 2.5f; // Distance threshold to identify inliers 11 const float nn_match_ratio = 0.8f; // Nearest neighbor matching ratio 12 13 int main(void) 14 { 15 Mat img1 = imread("../data/graf1.png", IMREAD_GRAYSCALE); 16 Mat img2 = imread("../data/graf3.png", IMREAD_GRAYSCALE); 17 18 Mat homography; 19 FileStorage fs("../data/H1to3p.xml", FileStorage::READ); 20 fs.getFirstTopLevelNode() >> homography; 21 22 vector<KeyPoint> kpts1, kpts2; 23 Mat desc1, desc2; 24 25 Ptr<AKAZE> akaze = AKAZE::create(); 26 akaze->detectAndCompute(img1, noArray(), kpts1, desc1); 27 akaze->detectAndCompute(img2, noArray(), kpts2, desc2); 28 29 BFMatcher matcher(NORM_HAMMING); 30 vector< vector<DMatch> > nn_matches; 31 matcher.knnMatch(desc1, desc2, nn_matches, 2); 32 33 vector<KeyPoint> matched1, matched2, inliers1, inliers2; 34 vector<DMatch> good_matches; 35 for(size_t i = 0; i < nn_matches.size(); i++) { 36 DMatch first = nn_matches[i][0]; 37 float dist1 = nn_matches[i][0].distance; 38 float dist2 = nn_matches[i][1].distance; 39 40 if(dist1 < nn_match_ratio * dist2) { 41 matched1.push_back(kpts1[first.queryIdx]); 42 matched2.push_back(kpts2[first.trainIdx]); 43 } 44 } 45 46 for(unsigned i = 0; i < matched1.size(); i++) { 47 Mat col = Mat::ones(3, 1, CV_64F); 48 col.at<double>(0) = matched1[i].pt.x; 49 col.at<double>(1) = matched1[i].pt.y; 50 51 col = homography * col; 52 col /= col.at<double>(2); 53 double dist = sqrt( pow(col.at<double>(0) - matched2[i].pt.x, 2) + 54 pow(col.at<double>(1) - matched2[i].pt.y, 2)); 55 56 if(dist < inlier_threshold) { 57 int new_i = static_cast<int>(inliers1.size()); 58 inliers1.push_back(matched1[i]); 59 inliers2.push_back(matched2[i]); 60 good_matches.push_back(DMatch(new_i, new_i, 0)); 61 } 62 } 63 64 Mat res; 65 drawMatches(img1, inliers1, img2, inliers2, good_matches, res); 66 imwrite("res.png", res); 67 68 double inlier_ratio = inliers1.size() * 1.0 / matched1.size(); 69 cout << "A-KAZE Matching Results" << endl; 70 cout << "*******************************" << endl; 71 cout << "# Keypoints 1: \t" << kpts1.size() << endl; 72 cout << "# Keypoints 2: \t" << kpts2.size() << endl; 73 cout << "# Matches: \t" << matched1.size() << endl; 74 cout << "# Inliers: \t" << inliers1.size() << endl; 75 cout << "# Inliers Ratio: \t" << inlier_ratio << endl; 76 cout << endl; 77 78 return 0; 79 } 80