OpenCv-C++-FLANN特徵匹配演算法
阿新 • • 發佈:2018-12-23
FLANN(快速最近鄰逼近搜尋函式庫),它是一個演算法庫,包含一系列演算法庫,OpenCv中集成了FLANN的一部分匹配演算法,主要對高維資料搜尋比較快。
相比於上一篇的暴力匹配演算法,FLANN更加精確,不會有過多的描述特徵匹配到。
匹配基本步驟:
檢測->提取->計算得到描述子->特徵比對
實現程式碼:
#include<opencv2/opencv.hpp> #include<iostream> #include<opencv2/xfeatures2d.hpp> #include<math.h> using namespace cv; using namespace std; using namespace cv::xfeatures2d; //檢測計算和繪製時,源圖(img1)在前面,目標影象(img2)在後面 Mat img1, img2; int main(int argc, char**argv) { img1 = imread("D:/test/BookAll.png", 0); img2 = imread("D:/test/Bookinscene.png", 0); if (!img1.data || !img2.data) { cout << "圖片為空!" << endl; return -1; } int minHesssion = 400; Ptr<SURF> detector = SURF::create(minHesssion); //也可以用SIRF,但是效率比SURF低 vector<KeyPoint> keypoints_obj; //存放img1的特徵值 vector<KeyPoint> keypoints_scene; //存放img2的特徵值 Mat descript_obj, descript_scene; detector->detectAndCompute(img1, Mat(), keypoints_obj, descript_obj); //檢測並計算特徵描述子 detector->detectAndCompute(img2, Mat(), keypoints_scene, descript_scene); FlannBasedMatcher fbmatcher; vector<DMatch>matches; fbmatcher.match(descript_obj, descript_scene, matches); //特徵描述子匹配 //找出最優特徵點 double minDist = 1000; //初始化最大最小距離 double maxDist = 0; for (int i = 0; i < descript_obj.rows; i++) { double dist = matches[i].distance; if (dist > maxDist) { maxDist = dist; } if (dist < minDist) { minDist = dist; } } printf("maxDist:%f\n", maxDist); printf("minDist:%f\n", minDist); vector<DMatch> goodMatches; for (int i = 0; i < descript_obj.rows; i++) { double dist = matches[i].distance; if (dist < max(2 * minDist, 0.02)) { goodMatches.push_back(matches[i]); } } Mat resultImg; drawMatches(img1, keypoints_obj, img2, keypoints_scene, goodMatches, resultImg, Scalar::all(-1), Scalar::all(-1), vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS ); imshow("input image1", img1); imshow("input image2", img2); imshow("FlannBasedMatcher demo", resultImg); waitKey(0); return 0; }
需要匹配的圖片1(目標圖片):
需要匹配的圖片2(源圖片):
執行結果:
1、當if (dist < max(2 * minDist, 0.02)) { goodMatches.push_back(matches[i]); }
中為(2 * minDist)
所得結果是:
查詢的結果很精確,但匹配到的共有描述子很少。
2、當if (dist < max(3 * minDist, 0.02)) { goodMatches.push_back(matches[i]); }
中為(3 * minDist)
所得結果是:
查詢的結果較為精確,匹配到的共有描述子稍多,但比之暴力匹配,已經很精準了。
注:這裡的(n * minDist)中的n可以取成小數,如:1.5,2.5等等,根據情況而定。