将Numpy数组中的一个通道广播到三个通道

26

我有一张RGB图像img,其形状为(2560L, 1920L, 3L),还有一个单通道图像mask,其形状为(2560L, 1920L)。现在,我想将这个mask的形状变为(2560L, 1920L, 3L),即将这个单通道数据复制到所有三个通道中。

我是这样做的。

np.array([[[j,j,j] for j in i] for i in mask])

使用 numpy 有更快的方法吗?

4个回答

18
np.repeat(mask.reshape(2560L, 1920L, 1L), 3, axis=2)

5
更简洁: np.repeat(mask[..., np.newaxis], 3, axis=2) - Mateen Ulhaq

12

如果您确实希望掩码为(2560, 1920, 3),则可以沿着一个轴简单地扩展它(有几种方法可以做到这一点,但这种方法非常直接):

>>> mask = np.random.random_integers(0, 255, (15, 12))
>>> mask_3d = mask[:, :, None] * np.ones(3, dtype=int)[None, None, :]
>>> mask.shape
(15L, 12L)
>>> mask_3d.shape
(15L, 12L, 3L)

然而,一般来说,你可以直接使用这些广播方式。例如,如果你想通过掩膜来乘以图像:

>>> img = np.random.random_integers(0, 255, (15, 12, 3))
>>> img.shape
(15L, 12L, 3L)
>>> converted = img * mask[:, :, None]
>>> converted.shape
(15L, 12L, 3L)

因此,您永远不需要创建(n, m, 3)掩码:通过操作掩码数组的步幅而不是创建一个更大的冗余数组来实现即时广播。 大多数numpy操作都支持这种广播方式:二元操作(如上所示),但也包括索引

>>> # Take the lower part of the image
>>> mask = np.tri(15, 12, dtype=bool)
>>> # Apply mask to first channel
>>> one_channel = img[:, :, 0][mask]
>>> one_channel.shape
(114L,)
>>> # Apply mask to all channels
>>> pixels = img[mask]
>>> pixels.shape
(114L, 3L)
>>> np.all(pixels[:, 0] == one_channel)
True

谢谢,那很有帮助。尤其是第二个片段。 :) - Abdul Fatir

7
可以沿着最后一个轴扩展维度,然后进行平铺,如下所示。
mask = np.random.randn(200, 150)
mask3d = np.tile(mask[:, :, None], [1, 1, 3])

[1, 1, 3]会在最后一个维度上铺设3次。


2
np.repeat(mask[..., np.newaxis], 3, axis=-1)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接