drali drali - 4 months ago 20
Python Question

How to convert 1-channel numpy matrix to 4-channel monochromatic image

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.


Yes! Use NumPy broadcasting to clean it up and have a one-liner, like so -

transposed = mask.T[...,None]*color


  1. Use mask.T to do the np.transpose operation done at the end.
  2. Use [...,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.
  3. Finally, we perform the element-wise multiplication itself, which in fact would be a broadcasted operation.