22

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

图2

我正在使用此代码的代码->

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 的坐标上。

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

4

4 回答 4

17

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

或者,您可以只使用stitcher 类(此处的示例):

#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);
}
于 2012-04-21T06:53:34.450 回答
7
  • 图像混合:您可以使用拉普拉斯金字塔混合。使用 opencv在此处查看示例代码你可以使用任何你喜欢的掩码(这是一个二进制掩码)。

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

于 2012-04-21T08:21:15.570 回答
2

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

这是匹配的图像:

在此处输入图像描述

这是包装好的 img2:

在此处输入图像描述

这是做 alphablend 的掩码:

在此处输入图像描述

这是 alphaBlended:

在此处输入图像描述


我们可以很容易地在混合图像中找到鬼影。这是因为warpPerspectiveperspectiveTransform不能真正找到real相机投影方程。主要是因为图像面板是 a panel,但 acylindrical 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 混合:在 opencv 中将 2 个图像与透明蒙版结合

  3. OpenCV Python 中的 Alpha 混合: opencv python 中的渐变蒙版混合

于 2018-01-16T09:37:49.810 回答
1

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

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

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

声明两个Mat文件

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

还要声明alpha然后beta将结果保存到Mat dst.

您还可以在此处获取详细信息Blending of Images using Opencv

于 2016-06-25T08:15:52.343 回答