我有以下Python代码,其中将形状为326x490x3
的某些图像另存为numpy
数组,以便在以后的阶段进行预处理。我想将图像保存在4D numpy数组中,以便以后可以批量处理它们。该代码可以正常工作,但是我发现,当我将4D数组的每个3D元素转换回RGB图像时,我只会得到一个静态图像。
代码:
data = np.zeros((129, 326, 490, 3))
image_path = '0.jpg'
img = Image.open(image_path)
data[0,:,:,:] = np.asarray(img)
im = Image.fromarray(data[0], 'RGB')
im.show()
输出:
但是当我尝试将4D数组中的3D numpy数组切片显示为灰度图像时,效果很好。
代码:
data = np.zeros((129, 326, 490, 3))
image_path = '0.jpg'
img = Image.open(image_path)
data[0,:,:,:] = np.asarray(img)
im = Image.fromarray(np.dot(data[0], [0.299, 0.587, 0.114]))
im.show()
输出:
将图像保存到3D numpy数组并切换回PIL图像时,给定here的解决方案可以按预期工作。
代码:
data = np.zeros((129, 326, 490, 3))
image_path = '0.jpg'
img = Image.open(image_path)
im = Image.fromarray(np.asarray(img), 'RGB')
im.show()
输出:
有人可以解释这种行为吗? 我不了解代码对于3D numpy数组的预期工作方式,但对于4D numpy数组的3D数组切片的工作方式却有所不同。
答案 0 :(得分:2)
由numpy.zeros
创建的数组的默认数据类型为numpy.float64
(即浮点数)。因此data
是一个浮点数组。在im = Image.fromarray(data[0], 'RGB')
行中,您已将模式明确指定为'RGB'
,这意味着8位整数(请参见Modes文档),因此fromarray
解释了参数{{ 1}}作为8位整数的数组。显然,它不会尝试转换输入数组。它仅假设数组中的基础数据存储为8位整数。由于data[0]
实际上包含浮点值,因此结果不正确。
在使用data[0]
的情况下,您没有明确指定模式,因此im = Image.fromarray(np.dot(data[0], [0.299, 0.587, 0.114]))
使用其自己的代码来确定模式,在这种情况下为fromarray
(32位浮点数)。因此,它可以正确转换您的数据。例如,如果您将模式指定为'F'
(表示8位黑白)
(即'L'
),调用将成功,但是图像数据将再次不正确,因为im = Image.fromarray(np.dot(data[0], [0.299, 0.587, 0.114]), 'L')
会将包含浮点值的内存解释为好像包含8位整数像素一样。
最简单的解决方法可能是将fromarray
创建为8位无符号整数的数组:
data