c++ opencv利用不同角度拍摄的特定场景图像,实现图像拼接,要求用C++和OPENCV编程实现。要求三张图片拼接,且代码超过200行
时间: 2023-12-24 20:05:42 浏览: 122
以下是利用不同角度拍摄的特定场景图像进行图像拼接的C++代码,使用OpenCV库实现。
```cpp
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
int main(int argc, char** argv)
{
// 读取三张图片
Mat img1 = imread("img1.jpg", IMREAD_COLOR);
Mat img2 = imread("img2.jpg", IMREAD_COLOR);
Mat img3 = imread("img3.jpg", IMREAD_COLOR);
// 如果读取失败,输出错误信息
if(img1.empty() || img2.empty() || img3.empty())
{
cerr << "Failed to read image(s)." << endl;
return -1;
}
// 转换为灰度图像
Mat gray1, gray2, gray3;
cvtColor(img1, gray1, COLOR_BGR2GRAY);
cvtColor(img2, gray2, COLOR_BGR2GRAY);
cvtColor(img3, gray3, COLOR_BGR2GRAY);
// 检测特征点并计算描述符
Ptr<FeatureDetector> detector = ORB::create();
vector<KeyPoint> keypoints1, keypoints2, keypoints3;
detector->detect(gray1, keypoints1);
detector->detect(gray2, keypoints2);
detector->detect(gray3, keypoints3);
Ptr<DescriptorExtractor> descriptor = ORB::create();
Mat descriptors1, descriptors2, descriptors3;
descriptor->compute(gray1, keypoints1, descriptors1);
descriptor->compute(gray2, keypoints2, descriptors2);
descriptor->compute(gray3, keypoints3, descriptors3);
// 匹配特征点
Ptr<DescriptorMatcher> matcher = DescriptorMatcher::create("BruteForce-Hamming");
vector<DMatch> matches12, matches23;
matcher->match(descriptors1, descriptors2, matches12);
matcher->match(descriptors2, descriptors3, matches23);
// 选择最佳匹配
double min_dist = 100.0;
for(int i = 0; i < matches12.size(); i++)
{
if(matches12[i].distance < min_dist)
min_dist = matches12[i].distance;
}
vector<DMatch> good_matches12, good_matches23;
for(int i = 0; i < matches12.size(); i++)
{
if(matches12[i].distance < 2 * min_dist)
good_matches12.push_back(matches12[i]);
}
min_dist = 100.0;
for(int i = 0; i < matches23.size(); i++)
{
if(matches23[i].distance < min_dist)
min_dist = matches23[i].distance;
}
for(int i = 0; i < matches23.size(); i++)
{
if(matches23[i].distance < 2 * min_dist)
good_matches23.push_back(matches23[i]);
}
// 提取匹配点对应的特征点坐标
vector<Point2f> points1, points2, points3;
for(int i = 0; i < good_matches12.size(); i++)
{
points1.push_back(keypoints1[good_matches12[i].queryIdx].pt);
points2.push_back(keypoints2[good_matches12[i].trainIdx].pt);
}
for(int i = 0; i < good_matches23.size(); i++)
{
points2.push_back(keypoints2[good_matches23[i].queryIdx].pt);
points3.push_back(keypoints3[good_matches23[i].trainIdx].pt);
}
// 计算图像间的变换矩阵
Mat H12 = findHomography(points1, points2, RANSAC);
Mat H23 = findHomography(points2, points3, RANSAC);
// 计算输出图像的大小
int cols1 = img1.cols, cols2 = img2.cols, cols3 = img3.cols;
int rows1 = img1.rows, rows2 = img2.rows, rows3 = img3.rows;
int cols = cols1 + cols2 + cols3, rows = max(max(rows1, rows2), rows3);
// 创建输出图像
Mat output(rows, cols, CV_8UC3, Scalar(0, 0, 0));
// 变换图像并拼接
warpPerspective(img1, output(Rect(0, 0, cols1, rows1)), H12, Size(cols1, rows1));
warpPerspective(img2, output(Rect(cols1, 0, cols2, rows2)), Mat::eye(3, 3, CV_32F), Size(cols2, rows2));
warpPerspective(img3, output(Rect(cols1 + cols2, 0, cols3, rows3)), H23, Size(cols3, rows3));
// 显示拼接结果
namedWindow("Output", WINDOW_NORMAL);
imshow("Output", output);
waitKey(0);
return 0;
}
```
上述代码实现了利用ORB算法检测图像特征点,使用RANSAC算法估计图像间的变换矩阵,最后变换并拼接三张图像。其中,变换矩阵采用单应性矩阵,用于将某一张图像中的特征点映射到另一张图像上。此方法可以用于拼接多张不同角度拍摄的特定场景图像。
阅读全文