在PIL /枕头中使用二进制PNG图像

was*_*tor 5 python numpy python-imaging-library

将二进制PNG文件从PIL图像对象转换为numpy数组时,无论原始图像是否反转,其值都相同。

例如,这两个图像都产生相同的numpy数组。

图像 t倒像

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)
Run Code Online (Sandbox Code Playgroud)

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)
Run Code Online (Sandbox Code Playgroud)

我期望0和1也将反转。他们为什么一样?

War*_*ser 5

这两个PNG文件都被索引了。它们包含相同的数据数组,仅包含您看到的值0和1,但这些值并非旨在作为像素的颜色。它们应该是调色板中的索引。在第一个文件中,调色板是

 Index     RGB Value
   0    [  0,   0,   0]
   1    [255, 255, 255]
Run Code Online (Sandbox Code Playgroud)

在第二个文件中,调色板是

 Index     RGB Value
   0    [255, 255, 255]
   1    [  0,   0,   0]
Run Code Online (Sandbox Code Playgroud)

问题在于,将Image对象转换为numpy数组时,不使用调色板,而仅返回索引数组。

要解决此问题,请使用对象的convert()方法Image将格式从索引调色板转换为RGB颜色:

t = Image.open('t.png')
t_rgb = t.convert(mode='RGB')
arr = np.array(t_rgb)
Run Code Online (Sandbox Code Playgroud)

  • 为了获得更好的 NumPy 表示,请使用二进制“1”“模式”:“arr = np.array(t.convert('1'))” (3认同)