opencv实践项目-多张图片拼接之stitcher

1.简介

OpenCV从2.4.x版本之后多出来一个新的模型 图像拼接,该模块通过简单的高级API设置,可以获得比较好的图像拼接效果,OpenCV官方提供了一个高度集成的API函数 Stitcher,只要两行代码就可以得到一个很好的拼接图像。

Ptr<Stitcher> stitcher = Stitcher::create(mode);
Stitcher::Status status = stitcher->stitch(imgs, pano);

其中第一行代码是创建拼接Stitcher的指针,第二行代码是调用拼接算法,

imgs表示的输入参数,是一系列Mat对象的vector。

pano表示的输出结果,是拼接之后的Mat对象

2. 拼接算法流程

stitching拼接算法 流程图示如下:
在这里插入图片描述
可见图像拼接是一个很复杂的算法,是由一系列的基础算法构成,这些基础算法如果你不是很了解,其实很难实现自己的图像拼接,这其中影响拼接算法stitch工作最常见几个算法子模块为:

  • 特征发现与描述子
    常见的特征可以选择SIFT、SURF、AKAZE、ORB等特征算子进行匹配

  • 相机参数
    不同的相机参数与设置会导致不同的结果

  • 融合方式(blender)
    不同的融合方式,也会导致不同结果

  • 各种阈值设置,特别是config threshold,如果无法特征匹配,记得把这个阈值调小点

3. 代码演示

#include <opencv2/opencv.hpp>
#include <iostream>
 
using namespace cv;
using namespace std;
 
int main(int argc, char** argv) {
    vector<string> files;
    glob("D:/images/zsxq/1", files);
    vector<Mat> images;
    for (int i = 0; i < files.size(); i++) {
        printf("image file : %s \n", files[i].c_str());
        images.push_back(imread(files[i]));
    }
 
    // 设置拼接模式与参数
    Mat result1, result2, result3;
    Stitcher::Mode mode = Stitcher::PANORAMA;
    Ptr<Stitcher> stitcher = Stitcher::create(mode);
 
    // 拼接方式-多通道融合
    auto blender = detail::Blender::createDefault(detail::Blender::MULTI_BAND, true);
    stitcher->setBlender(blender);
 
    // 拼接
    Stitcher::Status status = stitcher->stitch(images, result1);
 
    // 平面曲翘拼接
    auto plane_warper = makePtr<cv::PlaneWarper>();
    stitcher->setWarper(plane_warper);
    status = stitcher->stitch(images, result2);
 
    // 鱼眼拼接
    auto fisheye_warper = makePtr<cv::FisheyeWarper>();
    stitcher->setWarper(fisheye_warper);
    status = stitcher->stitch(images, result3);
 
    // 检查返回
    if (status != Stitcher::OK)
    {
        cout << "Can't stitch images, error code = " << int(status) << endl;
        return EXIT_FAILURE;
    }
    imwrite("D:/result1.png", result1);
    imwrite("D:/result2.png", result2);
    imwrite("D:/result3.png", result3);
 
    waitKey(0);
    return 0;
}

另外在拼接的时候可以设置不同warper,这样会对拼接之后的图像生成不同效果,常见的效果包括

  • 默认

  • 环视(平面曲翘)

  • 鱼眼相机

原图:
img1
在这里插入图片描述
img2
在这里插入图片描述
img3
在这里插入图片描述
img4
在这里插入图片描述

效果图:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
参考链接:
https://blog.csdn.net/qq_42722197/article/details/128021635

以下是使用OpenCV和Qt实现多张图片全景拼接的示例代码: ```cpp #include <opencv2/opencv.hpp> #include <QImage> #include <QPixmap> #include <QFileDialog> #include <QMessageBox> using namespace cv; void stitchImages(const std::vector<Mat>& images, Mat& result) { // Create a Stitcher object cv::Ptr<Stitcher> stitcher = Stitcher::create(Stitcher::PANORAMA); // Stitch the images Stitcher::Status status = stitcher->stitch(images, result); if (status != Stitcher::OK) { QMessageBox::warning(nullptr, "Error", "Failed to stitch images!"); } } QImage matToQImage(const cv::Mat& mat) { if (mat.type() == CV_8UC1) { // Grayscale image return QImage(mat.data, mat.cols, mat.rows, static_cast<int>(mat.step), QImage::Format_Grayscale8); } else if (mat.type() == CV_8UC3) { // Color image cv::Mat rgbMat; cv::cvtColor(mat, rgbMat, cv::COLOR_BGR2RGB); return QImage(rgbMat.data, rgbMat.cols, rgbMat.rows, static_cast<int>(rgbMat.step), QImage::Format_RGB888); } else { QMessageBox::warning(nullptr, "Error", "Unknown image type!"); return QImage(); } } int main(int argc, char** argv) { // Read the input images QStringList fileNames = QFileDialog::getOpenFileNames(nullptr, "Select Images", ".", "Images (*.png *.jpg *.jpeg)"); if (fileNames.isEmpty()) { return 0; } std::vector<cv::Mat> images; for (const auto& fileName : fileNames) { cv::Mat image = cv::imread(fileName.toStdString()); if (image.empty()) { QMessageBox::warning(nullptr, "Error", "Failed to read image!"); return 0; } images.push_back(image); } // Stitch the images cv::Mat result; stitchImages(images, result); // Convert the result to a QImage and display it QImage resultImage = matToQImage(result); if (resultImage.isNull()) { QMessageBox::warning(nullptr, "Error", "Failed to convert image!"); return 0; } QPixmap pixmap = QPixmap::fromImage(resultImage); QLabel label; label.setPixmap(pixmap); label.show(); return QApplication(argc, argv).exec(); } ``` 这个示例代码首先使用Qt的文件对话框选择输入图像,然后使用OpenCV的 `Stitcher` 类将所有图像拼接成一个全景图像。最后,将结果转换为 `QImage` 并使用 `QLabel` 显示。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值