Python RGB2灰度变换中保持图像数据栈的维数

Python RGB2灰度变换中保持图像数据栈的维数,python,arrays,numpy,dimension,Python,Arrays,Numpy,Dimension,我有4D RGB图像_数据[image,height,width,channel],在我的例子中,尺寸是(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循环的解

我有4D RGB图像_数据[image,height,width,channel],在我的例子中,尺寸是(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)
现在,我想知道是否有更神奇的方法来达到同样的效果,是否有一个巫师可以展示它。谢谢。

您可以使用或-

验证形状的示例运行-

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)
形状数组。因此,您只需要在末尾添加一个新的axis/singleton维度,使用
np.newaxis/None
。我们在这里是通过
[…,np.newaxis]
[…,None]
实现的

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

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

非常感谢Divakar,这解决了我的问题,使我的解决方案运行速度更快:)使用einsum的解决方案非常好。
np.dot(images,np.array([[0.299], [0.587], [0.114]]))