1

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 Answer 1

2

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)
Sign up to request clarification or add additional context in comments.

8 Comments

So how would look the whole code for multiplying the colored binary mask to the image?
this is the thing: you don't need to add your mask anymore since you are applying changes directly on your images. What would count as a mask would be the [v,v,v] you pass as an argument
I would not. I merely gave a workaround to achieve what you are looking for without using complex functions from a complex library. It involves changing slightly the way you look at your problem and thus your code. If you want to use Open CV at any cost and not change a line of your code nor try what I just posted, my solution is not the one you are looking for
I would like to try your solution, the thing is that i just do not understand how to apply your idea. I got three things: an image (3D RGB array), a mask (2D Binary) and a color (a 3 channel tuple). Starting from this, how do i apply your code?
ah, ok, I just understand what you're trying to do. The filter you want to apply is not uniform but only on the "masked parts", right? I edit my answer
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.