Reputation: 307
I am working on a pyqt project with numpy and cv2. Basically, I want to use a binary numpy mask (1024, 1024)
to create a 4 channel monochromatic image (1024, 1024, 4)
, where all 1s from the mask are pink and all 0s are invisible. Then I convert the image and show it as overlay in my QScene to highlight some pixels in another image.
My current approach does the job, but is too slow and I'm sure that numpy provides something more convenient.
color = (255, 0, 238, 100)
r = (mask * color[0]).reshape((w*h))
g = (mask * color[1]).reshape((w*h))
b = (mask * color[2]).reshape((w*h))
a = (mask * color[3]).reshape((w*h))
rgba = np.dstack((r, g, b, a)).reshape((w, h, 4))
transposed = np.transpose(rgba, axes=[1, 0, 2])
Is there a better way to show a mask overlay? I don't insist on using numpy, however, it is important that I can set the color, as I will be needing several colors.
Upvotes: 2
Views: 737
Reputation: 221554
Yes! Use NumPy broadcasting
to clean it up and have a one-liner
, like so -
transposed = mask.T[...,None]*color
Explanation:
mask.T
to do the np.transpose
operation done at the end.[...,None]
on the transposed array to basically push all its dimensions to the front and create a singleton dim (dim with length=1
) as the last axis. For introducing this new axis, we have used an alias for np.newaxis
- None
. Thus, we would achieve broadcasting for the transposed array along its last axis aligned with the elements of color
.broadcasted
operation.You can perform the creation of new axis part at the start and then use np.transpose
or np.swapaxes
and this would be closer to your original code. So, alternatively we could have :
transposed = mask[:,:,None].transpose(1,0,2)*color
and,
transposed = mask[:,:,None].swapaxes(0,1)*color
Upvotes: 3