在rgb2gray转换中保持图像数据堆栈的维度

时间:2017-07-11 07:15:56

标签: python arrays numpy dimension

我有4D RGB image_data [图像,高度,宽度,通道],在我的情况下,尺寸是(x,32,32,3),我想将这些图像转换为灰度,这样我仍然有4D所以我的尺寸是(x,32,32,1)。

我发现了一个非常简单的rgb2gray转换:

def rgb2gray(rgb):
    return np.dot(rgb[...,:3], [0.299, 0.587, 0.114])

这个问题是它返回我(x,32,32),所以我失去了一个维度。

现在我想到的for循环中的解决方案正在关注并且它可以工作:

def rgb2gray(images):
    gray_images = []
    for image in images:
        gray_image = []
        for size in image:
            gray_size = []
            for channels in size:
                channel = [np.dot(channels, [0.299, 0.587, 0.114])]
                gray_size.append(channel)
            gray_image.append(gray_size)
        gray_images.append(gray_image)
    return np.array(gray_images)

现在,我想知道是否有更神奇的方法来实现相同的结果,并且是否存在可以显示它的向导。谢谢。

1 个答案:

答案 0 :(得分:0)

您可以使用np.dotnp.tensordotnp.matmulnp.einsum -

np.dot(images,[0.299, 0.587, 0.114])[...,None]
np.tensordot(images,[0.299, 0.587, 0.114],axes=((-1),(-1)))[...,None]
np.matmul(images, [0.299, 0.587, 0.114])[...,None]
np.einsum('ijkl,l->ijk',images, [0.299, 0.587, 0.114])[...,None]

运行样本以验证形状 -

In [41]: images = np.random.randint(0,255,(10,32,32,3))

In [42]: np.dot(images,[0.299, 0.587, 0.114])[...,None].shape
Out[42]: (10, 32, 32, 1)

In [43]: np.tensordot(images,[0.299, 0.587, 0.114],axes=((-1),(-1)))[...,None].shape
Out[43]: (10, 32, 32, 1)

In [44]: np.matmul(images, [0.299, 0.587, 0.114])[...,None].shape
Out[44]: (10, 32, 32, 1)

In [45]: np.einsum('ijkl,l->ijk',images, [0.299, 0.587, 0.114])[...,None].shape
Out[45]: (10, 32, 32, 1)

回顾你的问题,你有rgb2gray(rgb)返回(n,32,32)形状的数组。因此,您需要的唯一修改是在最后添加一个新的轴/单一维度np.newaxis/None。我们通过[...,np.newaxis][...,None]来实现此目标。

因此,获得所需输出的另一种方法是使用缩放数组的2D数组版本,从而避免显式追加新轴,如此 -

np.dot(images,np.array([[0.299], [0.587], [0.114]]))