OpenCv3 VS C++ 影象識別(下)
阿新 • • 發佈:2019-01-13
總結一下:
cv::KeyPoint——關鍵點
cv::Feature2D——找到關鍵點或計算描述符的抽象類,如上一節的FastFeatureDetector即派生於Feature2D,定義了detect、compute、detectAndCompute等方法
cv::DMatch——匹配器
cv::DescriptorMatcher——關鍵點匹配的抽象類,在這一節我們將在程式碼中具體使用它們,它定義了match、knnMatch、radiusMatch等方法
#include <opencv2/features2d.hpp> #include <opencv2/imgcodecs.hpp> #include <opencv2/opencv.hpp> #include <vector> #include <iostream> using namespace std; using namespace cv; const float inlier_threshold = 2.5f; // Distance threshold to identify inliers const float nn_match_ratio = 0.8f; // Nearest neighbor matching ratio int main(void) { //1.載入圖片和homography矩陣 Mat img1 = imread("C:\\Users\\ttp\\Desktop\\5.jpg", IMREAD_GRAYSCALE); Mat img2 = imread("C:\\Users\\ttp\\Desktop\\4.jpg", IMREAD_GRAYSCALE); Mat homography; /*FileStorage fs("../data/H1to3p.xml", FileStorage::READ); fs.getFirstTopLevelNode() >> homography;*/ homography = (Mat_<double>(3, 3) << 7.6285898e-01, -2.9922929e-01, 2.2567123e+02, 3.3443473e-01, 1.0143901e+00, -7.6999973e+01, 3.4663091e-04, -1.4364524e-05, 1.0000000e+00); //2.使用AKAZE檢測關鍵點(keypoints)和計算描述符(descriptors) vector<KeyPoint> kpts1, kpts2; //關鍵點 Mat desc1, desc2; //描述符 Ptr<AKAZE> akaze = AKAZE::create(); akaze->detectAndCompute(img1, noArray(), kpts1, desc1); akaze->detectAndCompute(img2, noArray(), kpts2, desc2); //3.使用brute-force介面卡來找到 2-nn 匹配 BFMatcher matcher(NORM_HAMMING); //暴力匹配 vector< vector<DMatch> > nn_matches; matcher.knnMatch(desc1, desc2, nn_matches, 2); //4.Use 2-nn matches to find correct keypoint matches vector<KeyPoint> matched1, matched2, inliers1, inliers2; vector<DMatch> good_matches; for (size_t i = 0; i < nn_matches.size(); i++) { DMatch first = nn_matches[i][0]; float dist1 = nn_matches[i][0].distance; float dist2 = nn_matches[i][1].distance; if (dist1 < nn_match_ratio * dist2) { matched1.push_back(kpts1[first.queryIdx]); matched2.push_back(kpts2[first.trainIdx]); } } //5.Check if our matches fit in the homography model for (unsigned i = 0; i < matched1.size(); i++) { Mat col = Mat::ones(3, 1, CV_64F); col.at<double>(0) = matched1[i].pt.x; col.at<double>(1) = matched1[i].pt.y; col = homography * col; col /= col.at<double>(2); double dist = sqrt(pow(col.at<double>(0) - matched2[i].pt.x, 2) + pow(col.at<double>(1) - matched2[i].pt.y, 2)); if (dist < inlier_threshold) { int new_i = static_cast<int>(inliers1.size()); inliers1.push_back(matched1[i]); inliers2.push_back(matched2[i]); good_matches.push_back(DMatch(new_i, new_i, 0)); } } Mat res; drawMatches(img1, inliers1, img2, inliers2, good_matches, res); imshow("res", res); double inlier_ratio = inliers1.size() * 1.0 / matched1.size(); cout << "A-KAZE Matching Results" << endl; cout << "*******************************" << endl; cout << "# Keypoints 1: \t" << kpts1.size() << endl; cout << "# Keypoints 2: \t" << kpts2.size() << endl; cout << "# Matches: \t" << matched1.size() << endl; cout << "# Inliers: \t" << inliers1.size() << endl; cout << "# Inliers Ratio: \t" << inlier_ratio << endl; cout << endl; waitKey(0); return 0; }