Search code examples
c++opencvimage-processingmasksmoothing

How to apply a non-binary mask on an image in OpenCV?


I'm using OpenCV and I have a gray-scale image that is the result of a smoothing operation on a binary mask:

mask

I would like to apply this mask to a given RGB image, but using the copyTo method with the mask option takes into account all the non-zero pixels of the mask. However, what I'm interested in is to obtain an output image whose RGB pixel values are the input values 'scaled' pixel-wise by the factor given by the gray-scale mask.

I have the feeling that this is possible by using the built-in functions of OpenCV, but so far I couldn't find any way to do what I want.

I would know how to do that from scratch in a brute force fashion, but I'd prefer - if possible - to use built-in functions.

Thank you in advance!


Solution

  • As @api55 pointed out, the solution to my problem is:

    1. Normalize the mask through the function cv::normalize
    2. Multiply the normalized mask with the input image through the function cv::multiply

    In particular, the type of the normalized mask must be set to CV_32F (otherwise it won't work). As a consequence, the input image has to be converted as well (e.g., with convertTo).

    Example code:

    cv::normalize(mask,mask,0.,1.,cv::NORM_MINMAX,CV_32F);
    image.convertTo(image,CV_32F);
    cv::multiply(image,mask,image);
    image.convertTo(image,CV_8U); // Convert back the input image to the original type