正确将 png 转换为 npy numpy 数组(图像到数组)

Posted

技术标签:

【中文标题】正确将 png 转换为 npy numpy 数组(图像到数组)【英文标题】:Properly convert png to npy numpy array (Image to Array) 【发布时间】:2018-05-31 05:41:27 【问题描述】:

当我生成一个图像然后从中生成一个 numpy 数组时,原始的 .npy 文件与新文件不同。我认为new-array.npyoriginal-array.npy 完全相同,因为它们来自同一张图片。

例如,我使用了这个 4*4 像素的小图像:original-image.png

这是一个更大的版本(不是我正在使用的版本):

代码的最后一部分是将.png 转换为.npy 的部分。我认为问题出在某个地方。

import numpy as np
from PIL import Image
from matplotlib import pyplot as plt

filename = 'image-test'

img = Image.open( filename + '.png' )
data = np.array( img, dtype='uint8' )

np.save( filename + '.npy', data)

# visually testing our output
img_array = np.load(filename + '.npy')
plt.imshow(img_array) 

我的简单算法:

    生成随机rgb数组并保存为.npy 从该 numpy 数组中保存一个 .png 文件。 加载.png 文件并将其保存回.npy
import numpy as np
from matplotlib import pyplot as plt
import matplotlib

from PIL import Image                                                                                


####create a matrix of random colors
filename = "original-array"

matrix=np.random.random((4,4,3))
nx,ny,nz=np.shape(matrix)
CXY=np.zeros([ny, nx])
for i in range(ny):
    for j in range(nx):
        CXY[i,j]=np.max(matrix[j,i,:])

#Save binary data
np.save(filename + '.npy', CXY)
print(filename + " was saved")

#Load npy
img_array = np.load(filename + '.npy')
plt.imshow(img_array)


####Save npy as png
filename = "original-image"

img_name = filename +".png"
matplotlib.image.imsave(img_name, img_array)
print(filename + " was saved")


#### Convert that png back to numpy array

img = Image.open( filename + '.png' )
data = np.array( img, dtype='uint8' )

#Convert the new npy file to png
filename = "new-array"

np.save( filename + '.npy', data)
print(filename + " was saved")


#Load npy
img_array = np.load(filename + '.npy')

filename = "new-image"
#Save as png
img_name = filename +".png"
matplotlib.image.imsave(img_name, img_array)
print(filename + " was saved")

结果如下:

当我从new-array.npy 重新生成图像时,我得到的图像与original-image.png 完全相同:

【问题讨论】:

您知道,PNG 文件中的像素数据是经过压缩的。数据的微小变化以及不同的压缩算法可能会改变文件大小。要比较实际数据,请对解压缩的像素进行比较。 感谢您的回答,但问题是我的想法是能够将该数组用于机器学习算法,并且在转换后它必须相同。我该怎么办? 我的意思是因为这个微小的变化我得到了错误:IndexError: index 2323 is out of bounds for axis 0 with size 1400 当我将 2400*1400 png 转换为 numpy 数组和尝试使用它。这并不奇怪,因为文件似乎有不同的界限.. PNG 文件格式将像素存储为整数。您不能将浮点数组(例如您的 CXYimg_array)中的数据保存到 PNG 文件中并期望读回相同的值。 您的数组 CXY 包含 0..1 范围内的浮点数。 PNG 文件只能存储整数,因此不能存储浮点值。 【参考方案1】:

文件不同,因为数组具有不同的数据类型。

第一次保存数据是在保存数组 CXY 时。该数组的类型为np.float64,因为这是np.zeros 返回的默认数据类型。

第二个数组是通过加载原始图像而不是保存的 npy 文件创建的。这是引入不一致的地方,因为 PNG 数据的类型为 np.uint8(并且在下一行中再次转换为 np.uint8)。这是一种较小的数据类型,因此整体文件大小较小。

【讨论】:

以上是关于正确将 png 转换为 npy numpy 数组(图像到数组)的主要内容,如果未能解决你的问题,请参考以下文章

C中的numpy数组类型转换

如何使用 numpy.savez 将带有子数组的数组保存到单独的 .npy 文件中

numpy的文件存储,读取 .npy .npz 文件

可以将 Fortran 数组保存为 .npy 格式吗?

Numpy | 23 IO

如何将numpy数组图像转换为字节?