【问题标题】:How to merge two images in opencv?如何在opencv中合并两个图像?
【发布时间】:2012-04-21 06:23:56
【问题描述】:

我已经计算了单应性,取出了透视变换。我可以在一个窗口中显示两个图像但无法合并它们。这是我的示例图像->

我正在使用的代码 thiscode ->

cv::warpPerspective(image2,warpresult2,homography,cv::Size(2*image2.cols,image2.rows));


Mat imgResult(image1.rows,2*image1.cols,image1.type());

Mat roiImgResult_Left = imgResult(Rect(0,0,image1.cols,image1.rows)); 
Mat roiImgResult_Right = imgResult(Rect(image1.cols,0,image2.cols,image2.rows)); 

Mat roiImg1 = image1(Rect(0,0,image1.cols,image1.rows));
Mat roiImg2 = warpresult2(Rect(0,0,image2.cols,image2.rows));

roiImg1.copyTo(roiImgResult_Left); //Img1 will be on the left of imgResult
roiImg2.copyTo(roiImgResult_Right); //Img2 will be on the right of imgResult

imshow("Finalimg",imgResult);
imwrite("C:\\OpenCv_Projects\\outputimage.jpg",imgResult);
cvWaitKey(0);

我认为问题出在我给 roiImgResult_right 的坐标上。

输出图像是 -> 如您所见,图像未正确合并,右侧有黑色区域。如何也将其删除?

【问题讨论】:

    标签: visual-c++ image-processing opencv computer-vision image-stitching


    【解决方案1】:

    OpenCV 已经实现了图像拼接。如果你用“-D BUILD_EXAMPLES”编译,你可以使用二进制stitching_detailed。用法很简单:./stitching_detailed img1 img2 ...

    或者,您可以只使用stitcher 类(来自here 的示例):

    #include "opencv2/highgui/highgui.hpp"
    #include "opencv2/stitching/stitcher.hpp"
    
    using namespace std;
    using namespace cv;
    
    bool try_use_gpu = false;
    string result_name = "result.jpg";
    
    int main(int argc, char* argv[])
    {
        vector<Mat> imgs;
        // add images...
    
        Mat pano;
        Stitcher stitcher = Stitcher::createDefault(try_use_gpu);
        stitcher.stitch(imgs, pano);
        imwrite(result_name, pano);
    }
    

    【讨论】:

    • 我不想使用stitching_detailed 或stitcher 类。我想对其进行编码,因为它是我正在做的项目的一部分。顺便说一句谢谢:)
    • 我收到一个错误 - 无法打开包含文件:'opencv2/stitching/stitcher.hpp':没有这样的文件或目录。如何消除此错误。我的 opencv 文件夹中没有作为stitcher.hpp 的文件。我使用的是 opencv2.3.1。
    • 在你的opencv/modules目录下,有没有stitching子目录?如果没有,您必须查看 svn repo 以获得更高版本(标头存在于 svn trunk 中)。
    • 当我使用上面的代码时,我得到这个:错误 C2248:'cv::Stitcher::Stitcher':无法访问在类'cv::Stitcher'中声明的私有成员。如何访问缝合功能?
    • Stitcher::Stitch 是公开的,所以你必须指的是别的东西。也许您正在调用私有构造函数。
    【解决方案2】:
    • 图像混合:您可以使用拉普拉斯金字塔blending。使用 opencv 查看示例代码here。你可以使用任何你喜欢的掩码(这是一个二进制掩码)。

    • 创建全景图如果您想制作全景图,您可以使用 Min-Cut Stitching。一世 找到了这个做全景图的代码processing

    【讨论】:

    • 您的建议是下一步。首先我必须确保最终图像不会显示两个山峰而不是一个。感谢您的努力。
    • 如果是山的同一部分可以使用图像混合,如果不是使用创建全景的子弹
    【解决方案3】:

    如果你做的更仔细,比如不裁剪和堆叠,而是使用 alphaBlend,那么你会发现一些奇怪的东西。

    这是匹配的图像:

    这是包装好的 img2:

    这是做 alphablend 的掩码:

    这是 alphaBlended:


    我们可以很容易地在混合图像中找到鬼影。这是因为warpPerspectiveperspectiveTransform 无法真正找到real 相机投影方程。主要是因为图像面板是panel,但是cylindrical surfacespherical surface 或更复杂。所以我们所做的工作还不够。

    虽然好消息是OpenCV 提供High level stiching API,但我们可以通过OpenCV Stitching API 轻松进行拼接。结果如下。

    代码:

    //! 2018.01.16 14:43:26 CST
    //! 2018.01.16 17:32:15 CST
    #include <iostream>
    #include <fstream>
    #include "opencv2/imgcodecs.hpp"
    #include "opencv2/highgui.hpp"
    #include "opencv2/stitching.hpp"
    using namespace std;
    using namespace cv;
    
    Stitcher::Status stitchImages(vector<Mat>&imgs,string fname, Stitcher::Mode mode = Stitcher::PANORAMA, bool try_gpu=false) {
        Ptr<Stitcher> stitcher = Stitcher::create(mode, try_gpu);
        Mat pano;
        Stitcher::Status status = stitcher->stitch(imgs, pano);
        if (status != Stitcher::OK){
            cout << "Can't stitch images, error code = " << int(status) << endl;
            return -1;
        }
        imwrite(fname, pano);
        return status;
    }
    
    int main(int argc, char* argv[])
    {
    
        vector<string>fnames = {
            "img1.jpg", "img2.jpg"
        };
    
        vector<Mat> imgs;
        for(auto fname: fnames) {
            imgs.emplace_back(imread(fname));
        }
        stitchImages(imgs, "scans.png",Stitcher::SCANS );
        stitchImages(imgs, "pano.png",Stitcher::PANORAMA );
    }
    

    一些有用的链接:

    1. OpenCV 拼接:https://docs.opencv.org/3.3.0/d8/d19/tutorial_stitcher.html

    2. OpenCV C++ 中的 Alpha 混合:Combining 2 images with transparent mask in opencv

    3. OpenCV Python 中的 Alpha 混合: Gradient mask blending in opencv python

    【讨论】:

      【解决方案4】:

      您可以使用addWeighted() 函数轻松混合两个图像。 但要求是你必须制作相同大小的图像。

      如果图像大小不同,请先调整两个图像的大小。 然后调用下面的函数。

      addWeighted(src1, alpha, src2, beta, 0.0, dst);
      

      声明两个Mat文件

      src1 = imread("c://test//blend1.jpg");
      src2 = imread("c://test//blend2.jpg");
      

      同时声明alphabeta,然后将结果保存到Mat dst

      您也可以在这里获取详细信息Blending of Images using Opencv

      【讨论】:

        猜你喜欢
        • 2016-01-19
        • 1970-01-01
        • 2019-03-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-01-31
        • 2014-05-03
        • 2020-06-22
        相关资源
        最近更新 更多