计算两幅图的单应矩阵,实现图像拼接

单应矩阵是一个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 }

 

posted @ 2019-05-16 18:11  不拿曾经看以后  阅读(1806)  评论(0编辑  收藏  举报