numpy.array()读取图片不准确问题

需求:将信息按像素存储在图片里,再完整地读出来(矩阵、图片互转)

代码:

    # 随机生成一个3*3的矩阵,保存到图片里
    data = np.random.randint(1, 255, (3, 3, 3), dtype='uint8')
    print("image1: ",data)
    im = Image.fromarray(data)
    im.save("picture1.jpg")

    # 再读出来
    im = Image.open("picture1.jpg")
    data = np.array(im)
    print("image2: ",data)

    # 为了直观对比,再写入新图片
    im = Image.fromarray(data)
    im.save("picture2.jpg")

结果:

img


两次print的矩阵天差地别!

img


img


两次的图片仔细看能发现差别

其他尝试:

  1. 将上述第一行代码换成:

     data = np.full((3,3,3),255,dtype='uint8')
     data2 = np.zeros((3,3,3),dtype='uint8')
     data = np.concatenate((data,data2),axis = 1)
    

    结果如下:

    img


    读取的值不准确

  2. 将上述读取图片代码换成:

     im = Image.open("picture1.jpg").convert('RGB')
     for i in range (0,3):
         for j in range (0,3):
             print(im.getpixel((i, j)))
    

    同样不行

  3. 将上述读取图片代码换成:

    im = cv2.cvtColor(np.array(im),cv2.COLOR_RGB2BGR)
    

    同样不行,结果跟直接np.array()一样,说明可能问题就出在np.array()上

将图片保存为png格式就可以了,jpg使用的一种失真压缩标准方法,多次上传下载jpg图片会逐渐失真,这也是为什么两次数据矩阵不一样的缘故,而png则是无损的压缩方式,不会出现上述情况

可能是函数问题,用此方法读取试试


img1=cv2.imread(imagePath)
print("img1:",img1.shape)
print("img1:",type(img1))

save 可以接受 format 参数,当没有传递时,使用的格式由文件扩展绝对。因此本例中使用jpg格式, 而JPEG的压缩方式通常是破坏性资料压缩(lossy compression),即在压缩过程中图像的品质会遭受到可见的破坏,这会导致你每次调用都会不一样。

保存为jpg的过程中,PIL.Image.save()方法内部使用压缩算法对图片进行的压缩处理,使得图片会损耗,建议保存为png格式。

import numpy as np
from PIL import Image

# 随机生成一个3*3的矩阵,保存到图片里
data = np.random.randint(1, 255, (3, 3, 3), dtype='uint8')
print("image1: ",data)
im = Image.fromarray(data)
im.save("picture1.png")

# 再读出来
im = Image.open("picture1.png")
data = np.asarray(im)
print("image2: ",data)

# 为了直观对比,再写入新图片
im = Image.fromarray(data)
im.save("picture2.png")

"""
image1:  [[[171 130  19]
  [ 66 163 220]
  [ 32  43  24]]

 [[ 23 201   7]
  [229  82 121]
  [ 19  15 122]]

 [[ 45 126 204]
  [123   4 112]
  [121  30  49]]]
image2:  [[[171 130  19]
  [ 66 163 220]
  [ 32  43  24]]

 [[ 23 201   7]
  [229  82 121]
  [ 19  15 122]]

 [[ 45 126 204]
  [123   4 112]
  [121  30  49]]]
"""

修改试试

data = np.random.randint(1, 255, (3, 3, 3), dtype='uint8')
    print("image1: ",data)
    im = Image.fromarray(numpy.uint8( data ))
    im.save("picture1.jpg")
 
    # 再读出来
    im = Image.open("picture1.jpg")
    data = np.array(im)
    print("image2: ",data)
 
    # 为了直观对比,再写入新图片
    im = Image.fromarray(numpy.uint8( data ))
    im.save("picture2.jpg")

或者用Pillow,Pillow是首选的图像处理工具。
安装pip install Pillow
转换代码:

from PIL import Image
import numpy as np
imageBin = Image.open('picture1.jpg')
imgarray = np.array(imageBin ) 
arr2im = Image.fromarray(imgarray)
arr2im.save("picture2.jpg")

调整参数