BF和FLANN特征匹配

Posted jack-elvis

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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;    

 

 技术图片

 

 

 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
", maxDist);  //两幅图中特征点距离最大值
55     printf("min distance : %f
", minDist);  //两幅图中特征点距离最小值
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
", maxDist);  //两幅图中特征点距离最大值
13     printf("min distance : %f
", minDist);  //两幅图中特征点距离最小值

 

 

 

以上是关于BF和FLANN特征匹配的主要内容,如果未能解决你的问题,请参考以下文章

Opencv实现图像无缝拼接,Sift查找特征点,Flann进行匹配

OpenCV实现摄像机标定和像素转换,surf寻找特征点,FLANN匹配算子进行匹配

原神位置检测【OpenCV 特征匹配】

opencv之SURF图像匹配

多张图像的 OpenCV 特征匹配

第十八节图像描述符匹配算法