drali - 4 months ago 20

Python Question

I am working on a pyqt project with numpy and cv2. Basically, I want to use a binary numpy mask

`(1024, 1024)`

`(1024, 1024, 4)`

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

Yes! Use `NumPy broadcasting`

to clean it up and have a `one-liner`

, like so -

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

**Explanation:**

- Use
`mask.T`

to do the`np.transpose`

operation done at the end. - 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`

. - Finally, we perform the element-wise multiplication itself, which in fact would be a
`broadcasted`

operation.