与二进制PNG图像在PIL/pillow中的处理方法

5
当将 PIL Image 对象中的二进制 PNG 文件转换为 numpy 数组时,无论原始图像是否被反转,其值都是相同的。
例如,这两个图像产生相同的 numpy 数组。

t image t inverted image

import numpy as np
from PIL import Image
t = Image.open('t.png')
t_inverted = Image.open('t_inverted.png')
np.asarray(t)
np.asarray(t_inverted)

np.asarray(t)np.asarray(t_inverted)的输出结果为:

array([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
       [1, 0, 0, 0, 0, 0, 0, 0, 0, 1],
       [1, 0, 1, 1, 0, 0, 1, 1, 0, 1],
       [1, 1, 1, 1, 0, 0, 1, 1, 1, 1],
       [1, 1, 1, 1, 0, 0, 1, 1, 1, 1],
       [1, 1, 1, 1, 0, 0, 1, 1, 1, 1],
       [1, 1, 1, 1, 0, 0, 1, 1, 1, 1],
       [1, 1, 1, 1, 0, 0, 1, 1, 1, 1],
       [1, 1, 1, 0, 0, 0, 0, 1, 1, 1],
       [1, 1, 1, 1, 1, 1, 1, 1, 1, 1]], dtype=uint8)

我原本期望0和1也会被翻转。为什么它们是相同的?


1
我可以确认Matlab显示了相同的行为。 - jmd_dk
1个回答

6

这两个PNG文件都是索引颜色的。它们包含相同的数据数组,只有值为0和1,但这些值不是像素颜色。它们应该是调色板的索引。在第一个文件中,调色板是

 Index     RGB Value
   0    [  0,   0,   0]
   1    [255, 255, 255]

在第二个文件中,调色板为:
 Index     RGB Value
   0    [255, 255, 255]
   1    [  0,   0,   0]

问题在于,当Image对象转换为numpy数组时,调色板并未使用,仅返回索引数组。
要解决此问题,请使用Image对象的convert()方法将格式从索引调色板转换为RGB颜色:
t = Image.open('t.png')
t_rgb = t.convert(mode='RGB')
arr = np.array(t_rgb)

3
为了获得更好的NumPy表示,使用二进制'1'模式:arr = np.array(t.convert('1')) - jmd_dk
然后要回到0和1,可以使用astype()方法:np.asarray(t.convert('1')).astype(np.uint8) - waspinator

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