代码之家  ›  专栏  ›  技术社区  ›  Ofer Sadan

PIL.Image。fromarray在np.Reformate后产生失真图像

  •  3
  • Ofer Sadan  · 技术社区  · 7 年前

    我有一个形状为(10000196)的数组(numpy),我想将其保存为10000张36x36大小的图像。数组中的所有值都在范围内 (0,255) 。因此,我使用此代码来实现这一点(效果很好):

    for i, line in enumerate(myarray):
        img = Image.new('L',(36,36))
        img.putdata(line)
        img.save(str(i)+'.png')
    

    Image.fromarray 方法,但与原始方法相比,生成的图像失真得无法识别。首先我试了一下:

    myarray = myarray.reshape(10000,36,36)
    for i, line in enumerate(myarray):
        img = Image.fromarray(line, 'L')
        img.save(str(i)+'.png')
    

    Image.fromarray(myarray[0].reshape(36,36), 'L').save('test.png')
    

    再一次——扭曲的图像。

    fromarray reshape 太天真了,把数据搞砸了,但我没法解决这个问题。欢迎提出任何想法。

    1 回复  |  直到 7 年前
        1
  •  6
  •   unutbu    7 年前

    PIL的 L (亮度)。数据应为0到255之间的整数。如果通过将NumPy数组传递给 Image.fromarray 具有 mode='L' uint8 .因此使用

    myarray = myarray.astype('uint8')
    

    确保将数组传递给 Image.fromarray 具有数据类型 uint8 .


    uint8 float32 s是32位浮点。它们的宽度是 uint8 Image.fromarray 将NumPy数组中的底层数据视为 uint8 s、 读取足够的字节来填充图像,忽略其余的。因此,每个32位浮点变成四个8位整数,每个8位整数为不同的像素着色。

    assert 通行证:

    import numpy as np
    from PIL import Image
    
    line = np.arange(256).reshape(16, 16).astype('float32')
    img = Image.fromarray(line, 'L')
    line2 = np.asarray(img)
    assert (line.view('uint8').ravel()[:256].reshape(16, 16) == line2).all()
    

    myarray 不转换为 s创建了一个乱码图像。


    myarray s你可以 mode='F' (浮动模式):

    import numpy as np
    from PIL import Image
    
    line = np.arange(256).reshape(16, 16).astype('float32')
    img = Image.fromarray(line, 'F').convert('L')
    img.save('/tmp/out.png')
    

    enter image description here

    看见 this page