计算两幅图的单应矩阵,实现图像拼接
单应矩阵是一个3x3的矩阵,它有着特殊的属性可用于特定条件下的双视角图像。
我们知道,3D点与它在相机图像中像素点之间存在的关系可以用3x4矩阵表示。设想一下,同一场景中的两个视图的区别仅仅是一个纯粹的的旋转,那么可以发现这个矩阵的第4列都是由0组成的,没有平移向量。因此投影关系变成了3x3矩阵,即单应矩阵。
也意味着,在特殊情况下,同一个点在不同的视图中存在线性关系。
测试1:图像的拼接
1 #include<iostream> 2 #include<opencv2/core/core.hpp> 3 #include<opencv2/highgui/highgui.hpp> 4 #include<opencv2/features2d/features2d.hpp> 5 #include<opencv2/calib3d/calib3d.hpp> 6 #include<opencv2/opencv.hpp> 7 #include<opencv2/stitching/stitcher.hpp> 8 using namespace cv; 9 int main(int argc, char* argv[]){ 10 11 if (argc!=3){ 12 std::cout << "usage: feature_extraction imge1 image2" << std::endl; 13 return 1; 14 } 15 //read image 16 Mat image1 =imread(argv[1],CV_LOAD_IMAGE_COLOR); 17 Mat image2 = imread(argv[2],CV_LOAD_IMAGE_COLOR); 18 //keypoint descriptor 19 vector<KeyPoint> keypoint1,keypoint2; 20 Mat descriptor1,descriptor2; 21 ORB orb; 22 orb(image1,cv::Mat(),keypoint1,descriptor1); 23 orb(image2,cv::Mat(),keypoint2,descriptor2); 24 Mat outimage; 25 drawKeypoints(image1,keypoint1,outimage); 26 //match 27 vector<DMatch> matches; 28 BFMatcher matcher(NORM_HAMMING); 29 matcher.match(descriptor1,descriptor2,matches); 30 vector<DMatch> good_matches; 31 double mindist=1000,maxdist=0; 32 for(int i=0;i<matches.size();i++){ 33 if(matches[i].distance <= max(2*mindist,30.0)) 34 good_matches.push_back(matches[i]); 35 } 36 Mat good_matches_out; 37 drawMatches(image1,keypoint1,image2,keypoint2,good_matches,good_matches_out); 38 namedWindow("优化后匹配点",0); 39 resizeWindow("优化后匹配点",1241,376); 40 imshow("优化后匹配点",good_matches_out); 41 imwrite("优化后匹配点.png",good_matches_out); 42 std::vector<cv::Point2f> points1, points2; 43 for (std::vector<cv::DMatch>::const_iterator it= matches.begin(); 44 it!= matches.end(); ++it) { 45 46 // Get the position of left keypoints 47 float x= keypoint1[it->queryIdx].pt.x; 48 float y= keypoint1[it->queryIdx].pt.y; 49 points1.push_back(cv::Point2f(x,y)); 50 // Get the position of right keypoints 51 x= keypoint2[it->trainIdx].pt.x; 52 y= keypoint2[it->trainIdx].pt.y; 53 points2.push_back(cv::Point2f(x,y)); 54 } 55 std::cout << points1.size() << " " << points2.size() << std::endl; 56 Mat fundamental_matrix; 57 fundamental_matrix = findFundamentalMat (points1,points2,CV_FM_8POINT); 58 std::cout <<"Fundamental matrix="<< fundamental_matrix<<std::endl; 59 std::vector<uchar>inliers(points1.size(),0); 60 Mat homography_matrix =findHomography(Mat(points1),Mat(points2),inliers,CV_RANSAC,1.); 61 std::cout << "homography_matrix="<<homography_matrix<<std::endl; 62 Mat result; 63 warpPerspective(image1,result,homography_matrix,Size(1.5*image1.cols,image1.rows)); 64 Mat half(result, Rect(0,0,image2.cols,image2.rows)); 65 image2.copyTo(half); 66 namedWindow("result",0); 67 resizeWindow("result",640,320); 68 imshow("result",result); 69 imwrite("result.png",result); 70 waitKey(0); 71 return 0; 72 }
作者:YFzhao
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.