I don't know any direct function from opencv
but I wrote explicit approach to do that.
Assumption:
- Your background is
CV_8UC4
. In use of that sample you can easily extend that approach to another versions.
Code
void merge_images(cv::Mat* background, cv::Mat* upcoming, int x, int y)
{
auto handle_cv_8uc4 = [=](int i, int j)
{
if(upcoming->at<cv::Vec4b>(j, i)[3] > 10)//10 is only epsilon for trash hold, you can put also 0 or anything else.
{
background->at<cv::Vec4b>(y+j, x+i) = upcoming->at<cv::Vec4b>(j, i);
}
};
auto handle_cv_8uc3 = [=](int i, int j)
{
background->at<cv::Vec4b>(y+j, x+i)[0] = upcoming->at<cv::Vec3b>(j, i)[0];
background->at<cv::Vec4b>(y+j, x+i)[1] = upcoming->at<cv::Vec3b>(j, i)[1];
background->at<cv::Vec4b>(y+j, x+i)[2] = upcoming->at<cv::Vec3b>(j, i)[2];
background->at<cv::Vec4b>(y+j, x+i)[3] = 255;
};
for(int i = 0; i < upcoming->cols; i++)
{
for(int j = 0; j < upcoming->rows; j++)
{
if(j + y >= background->rows)
{
break;
}
if(x + i >= background->cols)
{
return;
}
switch(upcoming->channels())
{
case 3:
{
handle_cv_8uc3(i, j);
break;
}
case 4:
{
handle_cv_8uc4(i, j);
break;
}
default:
{
//maybe error?
}
}
}
}
}
I think this code explains itself. If something is unclear, feel free to ask.
Now, if you want to use that code, let say that you have background
and spr
and you want to put spr
to background
:
cv::Mat dst(background.rows, background.cols, CV_8UC4);
merge_images(&dst, &background, 0, 0);
merge_images(&dst, &spr, 50, 50);
Explanation
cv::Mat dst(background.rows, background.cols, CV_8UC4);
prepare matrix with size of background (to avoid modifying original background)
merge_images(&dst, &background, 0, 0);
add background to your prepared copy
merge_images(&dst, &spr, 50, 50);
add image such its left corner will be at (50,50)