Ofe*_*dan 2 python numpy python-imaging-library
我有一个形状为 (10000,1296) 的数组 (numpy),我想将其保存为 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')
Run Code Online (Sandbox Code Playgroud)
我想使用该Image.fromarray方法替换此代码,但是与原始方法相比,生成的图片失真得无法识别。首先我试过这个:
myarray = myarray.reshape(10000,36,36)
for i, line in enumerate(myarray):
img = Image.fromarray(line, 'L')
img.save(str(i)+'.png')
Run Code Online (Sandbox Code Playgroud)
这没有用。所以为了调试,我想我只会尝试一个项目并这样做:
Image.fromarray(myarray[0].reshape(36,36), 'L').save('test.png')
Run Code Online (Sandbox Code Playgroud)
再次 - 乱码扭曲的图像。
所以我想要么fromarray没有像我想象的那样工作,要么我reshape太天真并且弄乱了数据,但我无法解决这个问题。欢迎任何想法。
PIL 的L模式是用于表示亮度(亮度)的数据的灰度模式。数据应为 0 到 255 之间的整数。如果您通过将 NumPy 数组传递给Image.fromarraywith创建 PIL Image,则数组mode='L'的 dtype 应为uint8。因此使用
myarray = myarray.astype('uint8')
Run Code Online (Sandbox Code Playgroud)
确保传递给的数组Image.fromarray具有 dtype uint8。
uint8s 是无符号的 8 位整数。float32s 是 32 位浮点数。它们的宽度是uint8. Image.fromarray将 NumPy 数组中的底层数据视为uint8s,读取足够的字节来填充图像,并忽略其余部分。因此,每个 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()
Run Code Online (Sandbox Code Playgroud)
这就是为什么在myarray不转换为uint8s 的情况下使用会创建一个乱码的图像。
或者,您可以在(浮点模式)中读取数据,而不是转换myarray为uint8s 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')
Run Code Online (Sandbox Code Playgroud)
这产生
有关所有可能的 PIL 模式的列表,请参阅此页面。
| 归档时间: |
|
| 查看次数: |
2376 次 |
| 最近记录: |