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