PIL图像从I模式转换为P模式

4

我有这张深度图像:

enter image description here

我用PIL这样加载它:

depth_image = Image.open('stereo.png')

如果我打印图像的模式,它会显示模式I,根据文档,这是(32位有符号整数像素)

这是正确的,因为图像值的范围从0到255。我想对这个深度图进行着色以获得更好的可视化效果,所以我尝试使用调色板将其转换为P模式,例如:

depth_image = depth_image.convert('P', palette=custom_palette)
depth_image.save("colorized.png")

但结果是这样的黑白图像:

在此输入图片描述

我相信调色板没问题,因为有256个颜色以int格式存储在一个数组中。

我已经尝试在保存前将其转换为RGB格式,例如:

depth_image = depth_image.convert('RGB')

我也尝试在之后添加调色板,例如:

depth_image = depth_image.putpalette(custom_palette)

如果我尝试保存它而不将其转换为RGB,会收到以下提示:

    depth_image.save("here.png")
AttributeError: 'NoneType' object has no attribute 'save'

目前我将尝试将图像转换为numpy数组,然后从那里映射颜色,但我想知道关于PIL方面的遗漏。我查看了文档,但没有找到有关I到P转换的信息。


请展示您的 custom_palette - Mark Setchell
由于太长了,我无法将其作为评论添加,但它在这里的pastebin上https://pastebin.com/JqVbF87a我以Google的turbo color_palette为基础,位于此处https://gist.github.com/mikhailov-work/ee72ba4191942acecc03fe6da94fc73f,并将其格式化为PIL可以管理的格式。我还尝试了类似以下的内容: .convert("P", palette=Image.ADAPTIVE, colors=256) 但仍然没有任何效果。 - bpinaya
1个回答

1
我认为问题在于您的值被缩放到了0..65535而不是0..255的范围内。
如果这样做,您会发现值比您预期的要大:
i = Image.open('depth.png') 
n = np.array(i) 

print(n.max(),n.mean())
# prints 32257, 6437.173

所以,我很快地尝试了:
n = (n/256).astype(np.uint8)
r = Image.fromarray(n)
r=r.convert('P') 
r.putpalette(custom_palette)     # I grabbed this from your pastebin

enter image description here


1
非常感谢!我原以为问题出在转换上,而不是图像本身,奇怪的是,当我用Geeqie打开它时,所有像素值都没有超过255。 - bpinaya

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接