PIL.Image.fromarray在np.reshape之后产生扭曲的图像

时间:2017-07-09 11:54:09

标签: python numpy python-imaging-library

我有一个数组(numpy)的形状(10000,1296),我想保存为10,000张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 个答案:

答案 0 :(得分:2)

PIL&lt; <div id="all-the-coordinates"></div> 模式是表示亮度的数据的灰度模式 (亮度)。预计数据的整数为0到255.如果通过将NumPy数组传递给L Image.fromarray来创建PIL图像,则数组的dtype应为mode='L'。因此使用

uint8

确保传递给myarray = myarray.astype('uint8') 的数组具有dtype Image.fromarray

uint8是无符号的8位整数。 uint8是32位浮点数。它们是float32的4倍宽。 uint8将NumPy数组中的基础数据视为Image.fromarray,读取足够的字节以填充图像,并忽略其余数据。因此,每个32位浮点数变为四个8位整数,每个8位整数颜色都是不同的像素。

换句话说,以下uint8次传递:

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会产生乱码图像。

或者,您可以将uint8转换为myarray,而不是将其转换为uint8 读取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

有关所有可能的PIL模式的列表,请参阅this page