4

I want to create a mask operation...

I have two input images, of the same size (do they have to have the same depth/number of channels ? I'd like to be anything, likely 3 channels, CV_32FC3 or gray...) and I created a mask, of the same size (rows and cols)

cv::Mat mask = cv::Mat(image1.rows, image1.cols, CV_8UC1);

The mask is created with areas of black and white.

I would like to create a new cv::Mat, that will have image1 where mask has 1, and image2 where mask has 0.

I looked into cv::filter2D and copyTo... Also looked at addWeighted, but I don't want to blend them - the areas for each image should be completely separate. A roi would not help - the mask is likely to not contain a rectangle, but one or more polygons.

I can't find something that does what I want.

Is there any OpenCV function that combines my images based on the mask ? Or do I have to create my own, looping through rows and cols ?

Thank you.

Thalia
  • 13,637
  • 22
  • 96
  • 190
  • In the new/edited case, you should create two separate masks, MASK1 and MASK2. Apply MASK1 to IMAGE1, and MASK2 to IMAGE2, leaving you with RESULT1 and RESULT2. Now you just need to copy a portion of one image over the other image. – Cloud Jun 05 '13 at 22:34
  • Thank you, the second reference you gave me worked, I was able to copy one image to result, then copyTo with mask the second image. I am still playing with it, I am getting assertion errors when images are not same depth... but that is a different story I guess. – Thalia Jun 05 '13 at 22:36
  • No problem. The easiest solution is to make the two resultant images the same depth (ideally, make both use the higher bit depth of the two), then you're doing a pixel copy operation. A simple approach would effectively be: "for each black pixel in MASK2, copy the pixels from the same location in RESULT2 to the same spot in RESULT1". – Cloud Jun 05 '13 at 23:20
  • I have been trying to get a 1 channel to a 3 channel conversion, so far not much success... I know how to convert depth, and I would make a temp for the lowest image, with the same depth as the highest. But I'm still experimenting 1 to 3 channel... So I'm close :-) Looked at cv::merge and cvtColor – Thalia Jun 05 '13 at 23:25
  • 1
    A grayscale-to-RGB conversion would be likely what you are looking for: http://stackoverflow.com/questions/14571790/convert-image-color-from-grayscale-to-rgb-opencv-c – Cloud Jun 05 '13 at 23:27
  • Thanks, I have tried earlier, didn't exactly work - but this eventually did: http://stackoverflow.com/questions/9970660/convert-1-channel-image-to-3-channel I'm happy :-) – Thalia Jun 05 '13 at 23:30
  • The cvtConvert version is good now too. Things don't always work for me the first time :-) – Thalia Jun 05 '13 at 23:34

1 Answers1

5

Just use the bitwise_and() function and you're set. The references below include a full working example.

References:


  1. How to "zero" everything within a masked part of an image in OpenCV
  2. OpenCV bitwise_and + mask
Community
  • 1
  • 1
Cloud
  • 18,753
  • 15
  • 79
  • 153