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

Keeping the dimensionality of image data stack in rgb2gray transformation

我有 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])

这个问题是 returns 我 (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)

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

你可以使用np.dot or np.tensordot or np.matmul or np.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) return (n,32,32) 形数组。因此,您需要做的唯一修改是在末尾添加一个新的轴/单例维度 np.newaxis/None。我们在这里用 [...,np.newaxis][...,None].

来实现它

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

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