BF和FLANN特征匹配
BF特征点匹配原理: 暴力匹配
(段匹配)
1 #include <opencv2/opencv.hpp> 2 #include <opencv2/xfeatures2d.hpp> 3 #include <iostream> 4 5 using namespace cv; 6 using namespace std; 7 using namespace cv::xfeatures2d; 8 9 int main(int argc, char** argv) { 10 Mat img1 = imread("L:/4-1.jpg", IMREAD_GRAYSCALE); 11 Mat img2 = imread("L:/4.jpg", IMREAD_GRAYSCALE); 12 if (!img1.data || !img2.data) { 13 return -1; 14 } 15 imshow("image1", img1); 16 imshow("image2", img2); 17 18 int minHessian = 400; //海深矩阵参数 19 Ptr<SURF> detector = SURF::create(minHessian); //SURF指针,创建海深矩阵 20 vector<KeyPoint> keypoints_1; //创建关键点1 21 vector<KeyPoint> keypoints_2; //创建关键点2 22 23 Mat descriptor_1, descriptor_2; //描述子1和2 24 detector->detectAndCompute(img1, Mat(), keypoints_1, descriptor_1); //检测图1 25 detector->detectAndCompute(img2, Mat(), keypoints_2, descriptor_2); //检测图2 26 27 BFMatcher matcher(NORM_L2); //BF匹配函数 28 vector<DMatch> matches; //matches变量 29 matcher.match(descriptor_1, descriptor_2, matches); //matcher函数里match方法 30 31 Mat matchesImg; 32 drawMatches(img1, keypoints_1, img2, keypoints_2, matches, matchesImg);//绘制匹配图像 33 imshow("Descriptor Demo", matchesImg); 34 35 waitKey(0); 36 return 0; 37 }
效果:
FLANN(快速最近邻特征匹配):
快速最近邻逼近搜索函数库(Fast Approximate NearestNeighbor Search Library)
参数介绍:
1. vector<DMatch> matches;
根据queryIdx和trainIdx索引号即可在vector<KeyPoint> keypoints找到对应的匹配点
2.drawMatches函数:
代码如下:
1 #include <opencv2/opencv.hpp> 2 #include <opencv2/xfeatures2d.hpp> 3 #include <iostream> 4 #include <math.h> 5 6 using namespace cv; 7 using namespace std; 8 using namespace cv::xfeatures2d; 9 10 int main(int argc, char** argv) { 11 Mat img1 = imread("L:/4-1.jpg", IMREAD_GRAYSCALE); 12 Mat img2 = imread("L:/4.jpg", IMREAD_GRAYSCALE); 13 if (!img1.data || !img2.data) { 14 return -1; 15 } 16 imshow("object image", img1); 17 imshow("object in scene", img2); 18 19 // surf featurs extraction 20 int minHessian = 400; 21 Ptr<SURF> detector = SURF::create(minHessian); 22 vector<KeyPoint> keypoints_obj; 23 vector<KeyPoint> keypoints_scene; 24 Mat descriptor_obj, descriptor_scene; 25 detector->detectAndCompute(img1, Mat(), keypoints_obj, descriptor_obj); 26 detector->detectAndCompute(img2, Mat(), keypoints_scene, descriptor_scene); 27 28 // matching 29 FlannBasedMatcher matcher; //matcher函数 30 vector<DMatch> matches; 31 /* 32 matches变量,变量的特性有: 33 queryIdx:descriptorsLeft的索引 34 trainIdx:descriptorRight的索引 35 imgIdx: 匹配图像的索引,例如已知一幅图像的sift描述子,与其他十幅图像的描述子进行匹配, 36 找最相似的图像,则imgIdx此时就有用了 37 distance:两个描述子之间的距离 38 */ 39 matcher.match(descriptor_obj, descriptor_scene, matches); 40 //matcher.match方法,将两幅图匹配的特征点放入matches 41 42 // find good matched points 43 double minDist = 1000; //最小值设为最大 44 double maxDist = 0; //最大值设为最小 45 for (int i = 0; i < descriptor_obj.rows; i++) { 46 double dist = matches[i].distance; 47 if (dist > maxDist) { //以maxDist初值为0,找最大值赋给maxDist 48 maxDist = dist; 49 } 50 if (dist < minDist) { 51 minDist = dist; //以minDist初值为1000,找最小值赋给minDist 52 } 53 } 54 printf("max distance : %f\n", maxDist); //矩阵descriptor_obj中特征点距离最大值 55 printf("min distance : %f\n", minDist); //矩阵descriptor_obj中特征点距离最小值 56 vector<DMatch> goodMatches; 57 for (int i = 0; i < descriptor_obj.rows; i++) { 58 double dist = matches[i].distance; 59 if (dist < max(3 * minDist, 0.02)) { 60 //这里的max(3 * minDist, 0.02)是取3 * minDist与0.02的最大值 61 //一般情况下dist< 3 * minDist就是goodMatches特征点 62 goodMatches.push_back(matches[i]); 63 } 64 } 65 66 Mat matchesImg; 67 drawMatches(img1, keypoints_obj, img2, keypoints_scene, goodMatches, matchesImg, 68 Scalar::all(-1),Scalar::all(-1), vector<char>(), 69 DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS); 70 /*drawMatches函数: 71 1. img1 – 源图像1 72 2. keypoints1 –源图像1的特征点. 73 3. img2 – 源图像2. 74 4. keypoints2 – 源图像2的特征点 75 5. matches1to2 – 源图像1的特征点匹配源图像2的特征点[matches[i]] . 76 6. outImg – 输出图像具体由flags决定. 77 7. matchColor – 匹配的颜色(特征点和连线), 若matchColor == Scalar::all(-1),颜色随机. 78 8. singlePointColor – 单个点的颜色,即未配对的特征点,若matchColor == Scalar::all(-1),颜色随机. 79 matchesMask – Mask决定哪些点将被画出,若为空,则画出所有匹配点. 80 9. flags – Fdefined by DrawMatchesFlags. 81 */ 82 imshow("Flann Matching Result", matchesImg); 83 84 waitKey(0); 85 return 0; 86 }
结果:
总结:
学会了一种在数组中找最大最小值得方法:(冒泡排序)
1 double minDist = 1000; //最小值设为最大 2 double maxDist = 0; //最大值设为最小 3 for (int i = 0; i < descriptor_obj.rows; i++) { 4 double dist = matches[i].distance; 5 if (dist > maxDist) { //以maxDist初值为0,找最大值赋给maxDist 6 maxDist = dist; 7 } 8 if (dist < minDist) { 9 minDist = dist; //以minDist初值为1000,找最小值赋给minDist 10 } 11 } 12 printf("max distance : %f\n", maxDist); //两幅图中特征点距离最大值 13 printf("min distance : %f\n", minDist); //两幅图中特征点距离最小值