简体   繁体   中英

Python OpenCV - apply colored mask to image

I got the following things:

  • an Image read with OpenCV (numpy array)
  • a binary mask of the same size as the image
  • a color string like 'red' , 'blue' , etc

Q : how do i color the mask before i add it to the image? explicitly: how do i add color channels to a binary mask given a color string

I know how to add the mask (for example with cv2.addWeighted(mask,alpha,image,1-alpha,0,image) ) , but i dont know how to convert the binary mask to color space with a simple color 'string' as input. I know this works in PIL with rgb = PIL.ImageColor.getrgb(color) , but i dont know how to do this with OpenCV!

EDIT : i managed to get the colors in channel tuples (0,0,0) and currently my workaround is:

mask = cv2.cvtColor(mask, cv2.COLOR_GRAY2RGB)
mask[np.where((mask == [1,1,1]).all(axis = 2))] = color
cv2.addWeighted(mask,alpha,image,1-alpha,0,image)

but the problem is, now the image is greyscale with a colored map... So the first line needs to be exchanged

You could use a simpler and more native approach. What is a color filter if not a uniform shift you apply on one of your channels? I generally just use np.power . Provided that img is a 3D RGB matrix of your image:

img = np.power(img,[1.5, 1.0, 1.0]) # shift the reds
img = np.power(img,[1.0, 1.5, 1.0]) # shift the greens
img = np.power(img,[1.2, 1.2, 1.0]) # orange type? (I suck at color mixing, you'll find out the one you need to shift) (since all your colors are made from a combination of these three basic ones)

I just stopped using openCV and PIL (which is deprecated, by the way, have a look at skimage ) when I discovered this trick

To apply your filter only on the masked section, you could do this:

mask =  numpy.expand_dims(mask, 2) 
mask = numpy.repeat(mask, 3, axis=2) # give the mask the same shape as your image
colors = {"red": [0.1,0.,0.], "blue": [0.,0.,0.1]} # a dictionary for your colors, experiment with the values
colored_mask = numpy.multiply(mask, colors["red"])  # broadcast multiplication (thanks to the multiplication by 0, you'll end up with values different from 0 only on the relevant channels and the right regions)
img = img+colored_mask # element-wise sum (sinc img and mask have the same shape)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM