drali - 1 year ago 85
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.

Answer Source

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

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

Explanation:

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.
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download