How to merge two images in opencv?

末鹿安然 提交于 2019-11-28 17:55:56

OpenCV already has image stitching implemented. If you compile with "-D BUILD_EXAMPLES", you can use the binary stitching_detailed. The usage is simple: ./stitching_detailed img1 img2 ...

Or, you can just use the stitcher class (example from 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);
}
  • Image Blending: You may use a laplacian pyramid blending. see a sample code here using opencv. You can use whatever mask you like (which is a binary mask).

  • create Panorama If you want to make a panorama, you may use Min-Cut Stitching. I found this code which do the panorama processing.

You can easily blend two images using the addWeighted() function. But the requirement is that you have to make the images of the same size.

If the images are not of same size first resize the two images. Then call the following function.

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

Declare the two Mat files

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

Also declare alpha and beta then save the result to Mat dst.

You can also get the details here Blending of Images using Opencv

If you do more carefully, such as do not crop and stack, but use alphaBlend, then you will find something strange.

This is the matched image:

This is the wrapped img2:

This is the mask to do alphablend:

This is the alphaBlended:


We can easily find the ghost in the blended image. This is because the warpPerspective and perspectiveTransform can't really find the real camera projection equation. Mostly because the image panel is a panel, but a cylindrical surface or spherical surface or more complex. So the job we have done is not enough.

While the good new is OpenCV provides High level stiching API, We can do stitching easily by OpenCV Stitching API. Here is the result.

Code:

//! 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 );
}

Some useful links:

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

  2. Alpha Blending in OpenCV C++ : Combining 2 images with transparent mask in opencv

  3. Alpha Blending in OpenCV Python: Gradient mask blending in opencv python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!