inapathtolearn
inapathtolearn

Reputation: 75

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

enter image description here enter image description here 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.

Upvotes: 1

Views: 991

Answers (1)

api55
api55

Reputation: 11420

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)
}

Upvotes: 2

Related Questions