1 //#include "pch.h" //opencv4.0要去掉 2 #include <iostream> 3 #include <stdlib.h> 4 #include <opencv2/imgproc.hpp> 5 #include <opencv2/opencv.hpp> 6 #include "opencv2/xfeatures2d.hpp" 7 #include "opencv2/features2d.hpp" 8 9 using namespace std; 10 using namespace cv; 11 using namespace cv::xfeatures2d; 12 13 //最大特征点数 14 const int MAX_FEATURES = 500; 15 //好的特征点数 16 const float GOOD_MATCH_PERCENT = 0.15f; 17 18 /** 19 * @brief 图像对齐 20 * 21 * @param im1 对齐图像 22 * @param im2 模板图像 23 * @param im1Reg 输出图像 24 * @param h 25 */ 26 void alignImages(Mat &im1, Mat &im2, Mat &im1Reg, Mat &h) //引用传递,传入是实参的的别名,实际是实参的地址,因此调用被调函数后,实参会被间接修改。,这么看:Mat& arg 27 //和函数的 值传递 相反。 28 { 29 // Convert images to grayscale 30 Mat im1Gray, im2Gray; 31 //转换为灰度图 32 cvtColor(im1, im1Gray, COLOR_BGR2GRAY); //opencv4.0这里CV_BGR2GRAY要改成COLOR_BGR2GRAY 33 cvtColor(im2, im2Gray, COLOR_BGR2GRAY); 34 35 // Variables to store keypoints and descriptors 36 //关键点 37 std::vector<KeyPoint> keypoints1, keypoints2;//定义装有KeyPoint数据类型的的数组变量, keypoints1, keypoints2。如:vector<int> x,y 38 //特征描述符 39 Mat descriptors1, descriptors2; 40 41 // Detect ORB features and compute descriptors. 计算ORB特征和描述子 42 Ptr<Feature2D> orb = ORB::create(MAX_FEATURES);//opencv中ORB函数是纯虚函数,继承自feature2D,无法通过实例化对象调用,只能通过指针调用。 43 orb->detectAndCompute(im1Gray, Mat(), keypoints1, descriptors1); 44 orb->detectAndCompute(im2Gray, Mat(), keypoints2, descriptors2); 45 46 // Match features. 特征点匹配 47 std::vector<DMatch> matches; 48 //汉明距离进行特征点匹配 49 Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create("BruteForce-Hamming");//虚函数调用 50 matcher->match(descriptors1, descriptors2, matches, Mat()); 51 52 // Sort matches by score 按照特征点匹配结果从优到差排列 53 std::sort(matches.begin(), matches.end()); 54 55 // Remove not so good matches 移除不好的特征点 56 const int numGoodMatches = matches.size() * GOOD_MATCH_PERCENT; 57 matches.erase(matches.begin() + numGoodMatches, matches.end());//0.15*matchPoints_size 58 59 // Draw top matches 60 Mat imMatches; 61 //画出特征点匹配图 62 drawMatches(im1, keypoints1, im2, keypoints2, matches, imMatches); 63 imwrite("matches.jpg", imMatches); //暴力匹配后剔除差的匹配点后 打印的特征点匹配关系图 64 65 // Extract location of good matches 66 std::vector<Point2f> points1, points2; 67 68 //保存对应点 69 for (size_t i = 0; i < matches.size(); i++) //这里是暴力匹配作剔除后剩下的点 70 { 71 //queryIdx是对齐图像的描述子和特征点的下标。 72 points1.push_back(keypoints1[matches[i].queryIdx].pt); 73 //queryIdx是是样本图像的描述子和特征点的下标。 74 points2.push_back(keypoints2[matches[i].trainIdx].pt); 75 } 76 77 // Find homography 计算Homography,RANSAC随机抽样一致性算法 78 h = findHomography(points1, points2, RANSAC);//这个函数参数远比这个多,很多省略了,输入两张图片各自匹配点的矩阵,和匹配方法 79 80 // Use homography to warp image 映射 81 warpPerspective(im1, im1Reg, h, im2.size()); //弯曲视角,(待配准图,结果图,单应矩阵,) 82 } 83 84 int main() 85 { 86 // Read reference image 读取参考图像 87 string refFilename("D://aa.jpg"); //基准图像 88 cout << "Reading reference image : " << refFilename << endl; 89 Mat imReference = imread(refFilename); 90 91 // Read image to be aligned 读取对准图像 92 string imFilename("D://a.jpg"); //待校准图像 93 cout << "Reading image to align : " << imFilename << endl; 94 Mat im = imread(imFilename); 95 96 // Registered image will be resotred in imReg. 97 // The estimated homography will be stored in h. 98 //结果图像,单应性矩阵 99 Mat imReg, h; 100 101 // Align images 102 cout << "Aligning images ..." << endl; 103 alignImages(im, imReference, imReg, h);//(待配准图,参照图,结果图,单应矩阵) 104 105 // Write aligned image to disk. 106 string outFilename("aligned.jpg"); 107 cout << "Saving aligned image : " << outFilename << endl; 108 imwrite(outFilename, imReg); //校准后图像 109 110 /* Print estimated homography 111 [0.4260230318277862, 2.205599317460628, 7.436838081684622; 112 -0.8418214464779903, 1.649310552258939, 1202.559886226323; 113 0.0003634828675145606, 0.001245337973396314, 1]*/ 114 cout << "Estimated homography : " << h << endl; //这里输出到控制台了,要想保存需要输出重定向 115 system("pause"); 116 return 0; 117 } 118