opencv全景图像拼接c++源代码
时间: 2023-07-24 20:29:15 浏览: 123
以下是使用OpenCV实现全景图像拼接的C++源代码:
```cpp
#include <opencv2/opencv.hpp>
#include <iostream>
#include <vector>
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
// 读取图像
vector<Mat> imgs;
for (int i = 1; i <= 5; i++)
{
Mat img = imread(format("image%d.jpg", i));
if (img.empty())
{
cout << "Can't read image " << i << endl;
return -1;
}
imgs.push_back(img);
}
// 特征提取与匹配
Ptr<Feature2D> detector = ORB::create();
vector<vector<KeyPoint>> keypoints(imgs.size());
vector<Mat> descriptors(imgs.size());
for (int i = 0; i < imgs.size(); i++)
{
detector->detectAndCompute(imgs[i], noArray(), keypoints[i], descriptors[i]);
}
Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create("BruteForce-Hamming");
vector<vector<DMatch>> matches(imgs.size() - 1);
for (int i = 0; i < matches.size(); i++)
{
matcher->match(descriptors[i], descriptors[i + 1], matches[i]);
}
// 计算单应性矩阵
vector<Point2f> pts1, pts2;
for (int i = 0; i < matches.size(); i++)
{
for (int j = 0; j < matches[i].size(); j++)
{
int queryIdx = matches[i][j].queryIdx;
int trainIdx = matches[i][j].trainIdx;
pts1.push_back(keypoints[i][queryIdx].pt);
pts2.push_back(keypoints[i + 1][trainIdx].pt);
}
}
Mat H = findHomography(pts2, pts1, RANSAC);
// 计算输出图像大小
vector<Point2f> corners(imgs.size());
corners[0] = Point2f(0, 0);
vector<Point2f> border(4);
border[0] = Point2f(0, 0);
border[1] = Point2f(imgs[0].cols, 0);
border[2] = Point2f(imgs[0].cols, imgs[0].rows);
border[3] = Point2f(0, imgs[0].rows);
perspectiveTransform(border, corners[0].reshape(2), H);
float xMin = corners[0].x, xMax = corners[0].x;
float yMin = corners[0].y, yMax = corners[0].y;
for (int i = 1; i < imgs.size(); i++)
{
corners[i] = Point2f(0, 0);
perspectiveTransform(border, corners[i].reshape(2), H);
xMin = min(xMin, corners[i].x);
xMax = max(xMax, corners[i].x);
yMin = min(yMin, corners[i].y);
yMax = max(yMax, corners[i].y);
}
int width = cvRound(xMax - xMin);
int height = cvRound(yMax - yMin);
Mat panorama(height, width, CV_8UC3, Scalar(0, 0, 0));
// 拼接图像
warpPerspective(imgs[0], panorama(Rect(cvRound(corners[0].x - xMin), cvRound(corners[0].y - yMin), imgs[0].cols, imgs[0].rows)), H, panorama.size());
for (int i = 1; i < imgs.size(); i++)
{
Mat H1 = H.clone();
H1.at<double>(0, 2) -= xMin;
H1.at<double>(1, 2) -= yMin;
warpPerspective(imgs[i], panorama(Rect(0, 0, imgs[i].cols, imgs[i].rows)), H1, panorama.size());
}
// 显示结果
imshow("Panorama", panorama);
waitKey(0);
return 0;
}
```
注:该代码使用ORB特征提取和汉明距离匹配算法,可根据实际情况进行调整。
阅读全文