在下面的代码中,我只看到一个图像被再次读取和写入。但是如何使图像像素值发生如此剧烈的变化呢?显然,将PIL图像对象转换为numpy数组会导致这种情况,但不知道原因。我已经阅读了PIL图像的文档,但没有看到任何合理的解释。
import numpy as np
from PIL import Image
def _remove_colormap(filename):
return np.array(Image.open(filename))
def _save_annotation(annotation, filename):
pil_image = Image.fromarray(annotation.astype(dtype=np.uint8))
pil_image.save(filename)
def main():
raw_annotation = _remove_colormap('2007_000032.png')
_save_annotation(raw_annotation, '2007_000032_output.png')
if __name__ == '__main__':
main()输入图像是,

这是输出,

注:输入图像中红色区域的值为128,0,在输出图像中为1,1,1。
代码的实际来源是这里。
编辑:正如@taras在他的评论中明确指出的那样,
基本上,调色板是一个3* 256值的列表,格式为256红色值、256绿色值和256蓝色值。您的pil_image是一个灰度像素数组,每个像素在0..255范围内取一个值。当使用'P‘模式时,像素值k被映射到颜色(pallettek,palette256 + k,palette2 2*256+ k)。使用“L”模式时,RGB中的颜色只是k或(k,k,k)。
分割图像注释对每种对象类型使用唯一的颜色。因此,我们不需要实际的调色板的可视化,我们摆脱不必要的调色板。
发布于 2018-08-06 08:26:18
快速检查打开的图像模式。
Image.open(filename).mode显示输入文件是以'P'模式打开的,它代表
8位像素,使用调色板映射到任何其他模式。
因此,当您使用Image.fromarray生成图像时,调色板就会丢失,您将在'L'模式下得到一个灰度图像。
您只需在创建输出数组时提供调色板信息。
可以使用Image.getpalette()提取调色板:
def _remove_colormap(filename):
img = Image.open(filename)
palette = img.getpalette()
return np.array(img), palette一旦创建了pil_image,就可以使用Image.putpalette(palette)将调色板设置回
def _save_annotation(annotation, palette, filename):
pil_image = Image.fromarray(annotation.astype(dtype=np.uint8))
pil_image.putpalette(palette)
pil_image.save(filename)您的main也相应地发生了变化:
def main():
raw_annotation, palette = _remove_colormap('SqSbn.png')
_save_annotation(raw_annotation, palette, '2007_000032_output.png')编辑:
palette是以下列形式列出的3*256个值的列表:
256个红色值,256个绿色值和256个蓝色值。
pil_image是一个灰度像素数组,每个像素在0..255范围内取一个值。使用'P'模式时,像素值k映射到RGB颜色(pallette[k], palette[256 + k], palette[2*256 + k])。当使用'L‘模式时,颜色只是RGB中的k或(k, k, k)。
发布于 2019-06-11 13:48:02
_remove_colormap(filename)中缺少模式转换。正如问题中定义的那样(以及@taras的答案),remove_colormap将PIL映像转换为numpy数组。_save_annotation()进一步将numpy数组转换为PIL映像。RGB图像就是这样保存的。应该使用convert('L')来转换为灰度。修改后的函数定义如下:
def _remove_colormap(filename):
img = Image.open(filename).convert('L')
palette = img.getpalette()
print("palette: ", type(palette))
return np.array(img), palettehttps://stackoverflow.com/questions/51702670
复制相似问题