将Numpy阵列中的一个通道广播为三个通道

时间:2016-06-09 10:54:50

标签: python arrays numpy

我有一个形状为img的RGB图像(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 个答案:

答案 0 :(得分:6)

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

答案 1 :(得分:5)

如果你绝对想让面具为(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)

但是,通常,您可以直接使用这些broadcasts。例如,如果你想用你的面具乘以你的图像:

>>> 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操作都支持这种广播:二元操作(如上所述),还有indexing

>>> # 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

答案 2 :(得分:1)

可以沿最后一个轴扩展尺寸,然后按如下方式平铺。

mask = np.random.randn(200, 150)
mask3d = np.tile(mask[:, :, None], [1, 1, 3])

[1, 1, 3]在最后一维中将面具拼贴3次。

答案 3 :(得分:0)

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