ORB-GMS-RANSAC图像对齐

 1 #include <iostream>
 2 #include <opencv2/core.hpp>   //基础数据类型实现
 3 #include <opencv2/highgui.hpp> //图像的输入输出
 4 #include <opencv2/imgproc.hpp>  //图像处理
 5 #include <opencv2/flann.hpp>   //快速最近邻匹配算法
 6 #include <opencv2/calib3d.hpp> 
 7 #include <opencv2/features2d.hpp>  //一些特征检测的算法库,如FAST
 8 #include <opencv2/xfeatures2d.hpp>//一些算法,如GMS匹配算法(特征点细筛)
 9 //#include <stdlib.h>
10 
11 
12 using namespace cv;
13 using namespace std;
14 using namespace cv::xfeatures2d;
15 
16 
17 int main()
18 {
19     Mat img_1 = imread("D:\g.jpg");
20     Mat img_2 = imread("D:\dd.jpg");
21     //Ptr<Feature2D> sift = xfeatures2d::SIFT::create();
22     //Ptr<Feature2D> surf = xfeatures2d::SURF::create();
23     Ptr<ORB> orb = ORB::create(5000);   //定义了orb类对象并初始化
24     orb->setFastThreshold(0);       //FAST焦点检测算法阈值设定,0最大限度的检出角点。
25 
26     vector<KeyPoint> keypoints_1, keypoints_2;//定义了两个数组,未初始化
27     Mat descriptors_1, descriptors_2;//定义了两个结构变量,未初始化
28 
29     //sift->detect(img_1, keypoints_1);
30     //sift->compute(img_1, keypoints_1, descriptors);
31 
32     orb->detectAndCompute(img_1, Mat(), keypoints_1, descriptors_1);
33     orb->detectAndCompute(img_2, Mat(), keypoints_2, descriptors_2);  
34 
35     //orb ->detect(img_1, keypoints_1);
36     //orb ->compute(img_1, keypoints_1, descriptors_1);  关键点->描述子
37 
38     //orb->detect(img_2, keypoints_2);
39     //orb->compute(img_2, keypoints_2, descriptors_2);
40 
41     Mat ShowKeypoints1, ShowKeypoints2;      //定义了两个结构化类型变量
42     drawKeypoints(img_1, keypoints_1, ShowKeypoints1);  //调用函数画出检测到的关键点
43     drawKeypoints(img_2, keypoints_2, ShowKeypoints2);
44     imshow("Result_1", ShowKeypoints1);  //设置显示窗口名称
45     imshow("Result_2", ShowKeypoints2);
46 
47     vector<DMatch> matchesAll, matchesGMS;  //定义两个数组对象
48     BFMatcher matcher(NORM_HAMMING);//定义一个类对象,暴力匹配算法-第一轮,得到gms的输入。
49 
50     matcher.match(descriptors_1, descriptors_2, matchesAll); //针对前面生成的描述子暴力匹配,这个matchAll是被匹配的点构成的数组。
51     cout << "matchesAll: " << matchesAll.size() << endl;   //输出orb完全匹配的特征点对数
52     matchGMS(img_1.size(), img_2.size(), keypoints_1, keypoints_2, matchesAll, matchesGMS);//GMS网格运动统计继续筛选匹配特征点
53     std::cout << "matchesGMS: " << matchesGMS.size() << std::endl;//输出gms筛选后匹配的特征点对数
54 
55     std::vector<Point2f> points1, points2;
56     for (size_t i = 0; i < matchesGMS.size(); i++)   //这里是暴力匹配作剔除后剩下的点
57     {
58         //queryIdx是对齐图像的描述子和特征点的下标。
59         points1.push_back(keypoints_1[matchesGMS[i].queryIdx].pt);
60         //queryIdx是是样本图像的描述子和特征点的下标。
61         points2.push_back(keypoints_2[matchesGMS[i].trainIdx].pt);
62     }
63     Mat im1Reg, h;
64     // Find homography 计算Homography,RANSAC随机抽样一致性算法
65     h = findHomography(points1, points2, RANSAC);//这个函数参数远比这个多,很多参数缺省取了默认值,输入两张图片各自匹配点的矩阵,和匹配方法
66 
67                                                  // Use homography to warp image 映射   
68     warpPerspective(img_1, im1Reg, h, img_2.size()); 
69 
70     Mat finalMatches;
71     drawMatches(img_1, keypoints_1, img_2, keypoints_2, matchesGMS, finalMatches, Scalar::all(-1), Scalar::all(-1),//匹配的点及连接线的颜色随机;未被匹配的单点颜色随机。
72         std::vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);//画出匹配示意图,参数中有GMS运动估计筛选后的匹配点
73     imshow("Matches GMS", finalMatches);//显示
74     //system("pause");
75     imwrite("MatchesGMS.jpg", finalMatches);//保存
76     //看matchGMS的结构,将其分为两个新的keypoints,然后直接配对
77 
78     string outFilename("aligned.jpg");
79     cout << "Saving aligned image : " << outFilename << endl; 
80     imwrite(outFilename, im1Reg);  //校准后图像
81     imshow("aligned ", im1Reg);
82 
83     waitKey(0);
84     return 0;
85 }

算法存在的问题:只能对齐两个特征完全一样的图,只是因为类似拍摄角度产生的差别,换句话说这种基于特征的对齐对于特征变化非常敏感。在此项目中很多位置的特征是不固定的,比如器件上的标码,比如线的形态不同,而且器件的缺失也会影响。不适用于接线盒项目。

原文地址:https://www.cnblogs.com/Henry-ZHAO/p/12727261.html