将图像保存为文件中的 numpy 数组,并使用 Python 从文件中将其作为图像加载回来

Saving an image as a numpy array in a file and loading it back from the file as an image using Python

我正在尝试将图像转换为 numpy 数组并将其保存为 text/csv 文件。然后我试图将 text/csv 文件的内容加载回图像中。

在整个过程中,维度、数据类型像素值不得改变,以便准确重建原始图像(不失真)。

到目前为止我有什么-

testim = cv2.imread('img.jpg') #reading the input image

numpyimg = np.array(testim) # Saving as a numpy array

# Checking the shape and image
cv2_imshow(numpyimg)
print(numpyimg.shape)

# Trying to save in csv
for i in numpyimg:
  np.savetxt(fname="image_array.csv", delimiter=",", X=i)

# Check generated csv file after loading it

image_array = np.loadtxt(
    fname="image_array.csv", delimiter=","
)

print("NumPy array: \n", image_array)
print("Shape: ", image_array.shape)
print("Data Type: ", image_array.dtype.name)

当我打印保存文件的内容时,我看到了什么 -

NumPy array that I could saved in a file: 
 [[ 70. 176. 153.]
 [ 63. 170. 144.]
 [ 57. 167. 139.]
 ...
 [ 69. 118.  80.]
 [ 67. 117.  77.]
 [ 64. 114.  74.]]
Shape:  (1040, 3)

原图数组though-

array([[[ 78, 120, 165],
        [ 63, 105, 150],
        [ 48,  91, 134],
        ...,
        [ 22,  80,  51],
        [ 35,  91,  62],
        [ 49, 105,  76]],

       [[ 77, 122, 160],
        [ 62, 109, 147],
        [ 50,  95, 132],
        ...,
        [ 24,  84,  54],
        [ 29,  87,  58],
        [ 38,  96,  67]],

       [[ 73, 124, 150],
        [ 66, 120, 143],
        [ 63, 116, 137],
        ...,
        [ 28,  90,  60],
        [ 26,  86,  56],
        [ 27,  87,  57]],

       ...,

        [ 69, 118,  80],
        [ 67, 117,  77],
        [ 64, 114,  74]]], dtype=uint8)
shape: (780, 1040, 3)

这些看起来不一样,我不明白哪里出了问题。

有没有更简单、更准确的方法来解决这个问题?

我在这个问题上卡了很久。感谢您的帮助!

这些看起来不一样,我不明白哪里出了问题。

为了表示彩色图像OpenCV使用三维数组。要访问单个值,您必须提供 3:Y 坐标、X 坐标、颜色通道(0 代表 Blue1 代表 Green, 2 for Red 如果我没有记错 OpenCV 约定的话)。

text/csv 非常适合表示二维数据(想想电子表格),但如果您想要更多维度,则需要在写入之前和读取之后进行特殊处理。 RFC4180 不提供与列内容类型相关的任何功能。

您的 CSV 文件的大小 = (1040, 3)。

你的原图大小 = (780, 1040, 3).

你可以试试这个:

from PIL import Image
import numpy as np
  
#numpy array from image
img = np.array(Image.open('1.jpg')) # img to a numpy array shape = (50, 100, 3)

img_reshaped = img.reshape(img.shape[0], -1) # instead of looping and slicing through channels shape = (50, 300)
np.savetxt('img_2_numpy.csv', img_reshaped, delimiter=',') # save it as numpy array in csv file

numpydata = np.loadtxt('img_2_numpy.csv',dtype='uint8', delimiter=',') # load an array from csv file
array3D = numpydata.reshape(numpydata.shape[0], numpydata.shape[1] // img.shape[2], img.shape[2]) # reshape to (50, 100, 3)

# image from numpyarray
im = Image.fromarray(array3D)
im.show()

经过大量的反复试验,我找到了解决方案。这就是帮助我解决问题的原因-

from PIL import Image

# Create an empty text file before this step
with open('image_array.txt', 'w') as outfile:
    for slice_2d in numpyimg:
        np.savetxt(outfile, slice_2d)

new_data = np.loadtxt('image_array.txt')

new_data=new_data.reshape((780,1040,3))

img = Image.fromarray(new_data.astype(np.uint8),'RGB')
img.save('try.jpg')
img.show()