简体   繁体   中英

Overlay multiple images onto a base image of same size using OpenCV C++

在此处输入图片说明 在此处输入图片说明 I have a set of 193 images(Img0, Img1, Img2,...Imgx) of the same size(40x40) which needs to be overlayed onto the first image in this(that is Img0). I tried different solutions available here but it's working only for overlaying 2 images. I want this to be done using OpenCV& C++. I am pasting the code below.

#include <opencv2\highgui\highgui.hpp>
#include <iostream>
#include <stdio.h>using namespace cv;
using namespace std;
int main(int argc, char **argv)
{    

    string arrOfimages[193];
    stringstream str;
    int a = 1;

    for (int index = 0; index < 193 ; index++)
    {
        str << "C:/<path>/Img" << a << ".bmp";
        arrOfimages[index] = str.str();
        str.str("");
        a++;
    }

    Mat src1;
    Mat srcOut;
    src1 = imread(arrOfimages[0]);
    imshow("base", src1);

    for(int i = 0; i < 193; i++)
    {
        addWeighted(src1, 0.5, imread(arrOfimages[i+1]), 0.5, 0.0, srcOut, -1);
    }

    imshow("summation", srcOut);
    waitKey(0);
    return 0;

}

    }

I am not able to figure out what I am doing wrong here. Can someone help? Thanks a lot!

I am getting out of memory errors, assertion failed etc.

The problem is here:

for(int i = 0; i < 193; i++)
{
    addWeighted(src1, 0.5, imread(arrOfimages[i+1]), 0.5, 0.0, srcOut, -1);
}

You are adding +1 to the i which at the end will be 193 and out of bounds. You should just use int i=1 instead, like this:

for(int i = 1; i < 193; i++)
{
    addWeighted(src1, 0.5, imread(arrOfimages[i]), 0.5, 0.0, srcOut, -1);
}

Also, you add src1 and a new image and copy the output to srcOut... And in the next iteration you do it but with a next image, at the end you will have in srcOut only the result of adding the first and the last image. If you want to overlay all of them it should be something more like:

for(int i = 1; i < 193; i++)
{
    addWeighted(src1, 0.5, imread(arrOfimages[i]), 0.5, 0.0, srcOut, -1);
    src1 = srcOut;
}

Just as a note, the previous loop:

stringstream str;
int a = 1;

for (int index = 0; index < 193 ; index++)
{
    str << "C:/<path>/KCF" << a << ".bmp";
    arrOfimages[index] = str.str();
    str.str("");
    a++;
}

can be written like this:

for (int index = 0; index < 193 ; index++)
{
    stringstream str;
    str << R"(C:\<path>\KCF)" << (a+1) << ".bmp";
    arrOfimages[index] = str.str();
}

Update:

You would like to have is a blended image that preserves the black spots. To do that you can use bitwise_and from opencv like this:

cv::Mat srcOut = cv::imread(arrOfImages[0], cv::IMREAD_GRAYSCALE);
for(int i = 1; i < 193; i++)
{
    cv::bitwise_and(srcOut, cv::imread(arrOfImages[1], cv::IMREAD_GRAYSCALE), srcOut)
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM