AKAZE_match.cpp 3.4 KB

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