【问题标题】:Tensorflow Deeplab image colormap removal confusionTensorflow Deeplab 图像颜色图去除混淆
【发布时间】:2019-01-13 02:53:45
【问题描述】:

在下面的代码中,我只看到,一个图像被再次读取和写入。但是图像像素值如何发生如此剧烈的变化?显然,将 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,0],输出图像为[1,1,1]。

代码的实际来源是here

编辑: 正如@taras 在他的评论中明确指出的那样,

基本上,调色板是 3 * 256 个值的列表,形式为 256 个红色值, 256 个绿色值和 256 个蓝色值。你的 pil_image 是一个数组 每个灰度像素在 0..255 范围内取单个值。什么时候 使用 'P' 模式,像素值 k 被映射到颜色(pallette[k], 调色板[256 + k],调色板[2 * 256 + k])。使用“L”模式时,颜色 只是 RGB 中的 k 或 (k, k, k)

分割图像注释为每个对象类型使用唯一的颜色。所以我们不需要实际的调色板来进行可视化,我们去掉了不必要的调色板。

【问题讨论】:

标签: python image-processing python-imaging-library


【解决方案1】:

快速检查打开的图像模式

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)

【讨论】:

  • 感谢您的回答。但是因为我不想更改代码。我只想知道这里的值是如何变化的。它是否遵循任何定义的规则来转换调色板?我的意思是 [128,0,0] 如何变成 [1,1,1]
  • 基本上,调色板是 3 * 256 个值的列表,形式为 256 个红色值、256 个绿色值和 256 个蓝色值。您的 pil_image 是一个灰度像素数组,每个像素在 0..255 范围内取一个值。当使用'P' 模式时,像素值k 被映射到颜色(pallette[k], palette[256 + k], palette[2*256 + k])。使用'L' 模式时,RGB 中的颜色只是k(k, k, k)
  • 我认为P模式下,像素值k映射到颜色(pallette[3*k], palette[3*k+1], palette[3*k+2])而不是(pallette[k], palette[256 + k], palette[2*256 + k])参考:pillow.readthedocs.io/en/5.1.x/handbook/…
【解决方案2】:

_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), palette

【讨论】:

    猜你喜欢
    • 2020-11-22
    • 1970-01-01
    • 2020-04-11
    • 2013-04-28
    • 2020-03-26
    • 2011-09-19
    • 1970-01-01
    • 2019-02-06
    • 1970-01-01
    相关资源
    最近更新 更多