0
votes

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

1

1 Answers

2
votes

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)