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

标签 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')

我想用 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 太天真了,弄乱了数据,但我无法解决这个问题。欢迎任何想法。

最佳答案

PIL 的 L 模式是一种灰度模式,用于表示亮度的数据 (亮度)。数据应为 0 到 255 之间的整数。如果您通过使用 mode='L' 将 NumPy 数组传递给 Image.fromarray 创建 PIL 图像,dtype数组的长度应该是 uint8。因此使用

myarray = myarray.astype('uint8')

确保传递给 Image.fromarray 的数组具有 dtype uint8


uint8 是无符号的 8 位整数。 float32 是 32 位 float 。它们的宽度是 uint8 的 4 倍。 Image.fromarray 将 NumPy 数组中的基础数据视为 uint8,读取足够的字节来填充图像,并忽略其余部分。所以每个 32 位 float 变成四个 8 位整数,每个 8 位整数为不同的像素着色。

换句话说,以下断言通过:

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()

这就是为什么在不转换为 uint8 的情况下使用 myarray 会产生乱码图像的原因。


或者,您可以不将 myarray 转换为 uint8 读取 mode='F' 中的数据( float 模式):

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获取所有可能的 PIL 模式的列表。

关于python - PIL.Image.fromarray 在 np.reshape 之后产生扭曲的图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44996127/

相关文章:

python - Mac 上缺少(?)Python 2.7 框架

python - 如何存储 bash 命令的输出?

python - 检查单个元素是否包含在 Numpy 数组中

python - win32com python 异常行为

Python Image Shuffle Failure - 我哪里出错了?

python - 如何在lxml解析中获得准确的日期?

python - 将 2D numpy 数组转换为表示灰度图像的 3d numpy 数组

python - 如何在Python中找到多列中重复行的最大绝对值并显示其行和列索引

python - 类方法返回列表/数组

python - 如何使用 Pillow 隐藏重叠像素?