18

I want to cover a image with a transparent solid color overlay in the shape of a black-white mask

Currently I'm using the following java code to implement this.

redImg = new Mat(image.size(), image.type(), new Scalar(255, 0, 0));
redImg.copyTo(image, mask);

I'm not familiar with the python api.

So I want to know if there any alternative api in python. Is there any better implementation?

image:

src img

mask:

mask

what i want:

what i want

Will Li
  • 495
  • 1
  • 3
  • 12

3 Answers3

24

Now after I deal with all this Python, OpenCV, Numpy thing for a while, I find out it's quite simple to implement this with code:

image[mask] = (0, 0, 255)

-------------- the original answer --------------

I solved this by the following code:

redImg = np.zeros(image.shape, image.dtype)
redImg[:,:] = (0, 0, 255)
redMask = cv2.bitwise_and(redImg, redImg, mask=mask)
cv2.addWeighted(redMask, 1, image, 1, 0, image)
Will Li
  • 495
  • 1
  • 3
  • 12
  • 3
    Regarding your updated answer, I think you still need `addWeighted` otherwise you won't overlay with transparency. – Antonio Feb 05 '21 at 10:13
3

The idea is to convert the mask to a binary format where pixels are either 0 (black) or 255 (white). White pixels represent sections that are kept while black sections are thrown away. Then set all white pixels on the mask to your desired BGR color.

Input image and mask

Result

Code

import cv2

image = cv2.imread('1.jpg')
mask = cv2.imread('mask.jpg', 0)
mask = cv2.threshold(mask, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
image[mask==255] = (36,255,12)

cv2.imshow('image', image)
cv2.imshow('mask', mask)
cv2.waitKey()
nathancy
  • 42,661
  • 14
  • 115
  • 137
0

this is what worked for me:

red = np.ones(mask.shape)
red = red*255
img[:,:,0][mask>0] = red[mask>0]

so I made a 2d array with solid 255 values and replaced it with my image's red band in pixels where the mask is not zero. redmask