【问题标题】:Broadcast one channel in Numpy array into three channels将 Numpy 数组中的一个频道广播成三个频道
【发布时间】:2016-06-09 10:54:50
【问题描述】:

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

我这样做如下。

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

有没有更快的方法使用numpy

【问题讨论】:

    标签: python arrays numpy


    【解决方案1】:
    np.repeat(mask.reshape(2560L, 1920L, 1L), 3, axis=2)
    

    【讨论】:

    • 更简单:np.repeat(mask[..., np.newaxis], 3, axis=2).
    【解决方案2】:

    如果您绝对希望掩码为(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
    

    【讨论】:

    • 谢谢你,这有帮助。尤其是第二个 sn-p。 :)
    【解决方案3】:

    尺寸可以沿最后一个轴展开,然后平铺如下。

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

    [1, 1, 3] 在最后一维将掩码平铺 3 次。

    【讨论】:

      【解决方案4】:
      np.repeat(mask[..., np.newaxis], 3, axis=-1)
      

      【讨论】:

        猜你喜欢
        • 2019-05-16
        • 2019-08-28
        • 1970-01-01
        • 2018-02-06
        • 2013-07-17
        • 2017-10-20
        • 2016-11-27
        • 1970-01-01
        相关资源
        最近更新 更多