Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Copy / blend images of different sizes using opencv

I am trying to blend two images. It is easy if they have the same size, but if one of the images is smaller or larger cv::addWeighted fails.

Image A (expected to be larger) Image B (expected to be smaller)

I tried to create a ROI - tried to create a third image of the size of A and copy B inside - I can't seem to get it right. Please help.

double alpha = 0.7; // something
int min_x = ( A.cols - B.cols)/2 );
int min_y = ( A.rows - B.rows)/2 );
int width, height;
if(min_x < 0) {
  min_x = 0; width = (*input_images).at(0).cols - 1;
}
else         width = (*input_images).at(1).cols - 1;
if(min_y < 0) {
  min_y = 0; height = (*input_images).at(0).rows - 1;
}
else         height = (*input_images).at(1).rows - 1;
cv::Rect roi = cv::Rect(min_x, min_y, width, height);            
cv::Mat larger_image(A);
// not sure how to copy B into roi, or even if it is necessary... and keep the images the same size
cv::addWeighted( larger_image, alpha, A, 1-alpha, 0.0, out_image, A.depth());

Even something like cvSetImageROI - may work but I can't find the c++ equivalent - may help - but I don't know how to use it to still keep the image content, only place another image inside ROI...

like image 386
Thalia Avatar asked Jul 23 '13 23:07

Thalia


1 Answers

// min_x, min_y should be valid in A and [width height] = size(B)
cv::Rect roi = cv::Rect(min_x, min_y, B.cols, B.rows);  

// "out_image" is the output ; i.e. A with a part of it blended with B
cv::Mat out_image = A.clone();

// Set the ROIs for the selected sections of A and out_image (the same at the moment)
cv::Mat A_roi= A(roi);
cv::Mat out_image_roi = out_image(roi);

// Blend the ROI of A with B into the ROI of out_image
cv::addWeighted(A_roi,alpha,B,1-alpha,0.0,out_image_roi);

Note that if you want to blend B directly into A, you just need roi.

cv::addWeighted(A(roi),alpha,B,1-alpha,0.0,A(roi));
like image 60
Jacob Avatar answered Sep 20 '22 00:09

Jacob