В этом нет ошибки, но, возможно, неправильное понимание того, как работают различные режимы в Подушке.
Как вы выяснили, рассматриваемое изображение представляет собой изображение на поддоне. Но путем явного преобразования изображения в режим RGBA
вся информация из исходной палитры и прозрачности «обрабатывается», так что при преобразовании в некоторый массив NumPy вы увидите только цвета, взятые из палитры, и извлеченный альфа-канал.
Если вы откроете изображение без какого-либо преобразования, режим P
(или, возможно, PA
) будет выбран автоматически, а в некотором извлеченном массиве NumPy будет только один канал. Давайте рассмотрим следующий пример:
from matplotlib import pyplot as plt
import numpy as np
from PIL import Image
plt.figure(1, figsize=(10, 9))
# Read image with Pillow, explicit RGBA mode
image_pil = Image.open('grin-emoji-by-twitter.png').convert('RGBA')
plt.subplot(2, 2, 1), plt.imshow(image_pil), plt.title('Pillow image; explicit RGBA mode')
image_np = np.array(image_pil)
plt.subplot(2, 2, 2), plt.imshow(image_np), plt.title('NumPy array')
print("Image.open(...).convert('RGBA'):")
print(image_np.shape, image_np.dtype, '\n')
# Palette of Pillow image
print("Palette:")
print(image_pil.getpalette(), '\n')
# Image info of Pillow image
print("Information:")
print(image_pil.info, '\n')
# Read image with Pillow, no mode set, P mode is taken implicitly
image_pil = Image.open('grin-emoji-by-twitter.png')
plt.subplot(2, 2, 3), plt.imshow(image_pil), plt.title('Pillow image; implicit P mode')
image_np = np.array(image_pil)
plt.subplot(2, 2, 4), plt.imshow(image_np), plt.title('NumPy array')
print("Image.open(...):")
print(image_np.shape, image_np.dtype, '\n')
# Palette of Pillow image
print("Palette:")
print(image_pil.getpalette(), '\n')
# Image info of Pillow image
print("Information:")
print(image_pil.info)
plt.tight_layout()
plt.show()
Это вывод изображения:
Как видите, изображение подушки то же самое для обоих режимов, но извлеченные массивы NumPy отличаются (четыре канала RGBA по сравнению с одним каналом).
Давайте еще раз посмотрим на print
выходы:
Image.open(...).convert('RGBA'):
(512, 512, 4) uint8
Palette:
None
Information:
{}
Image.open(...):
(512, 512) uint8
Palette:
[71, 112, 76, 255, 202, 78, ... ]
Information:
{'transparency': b"\x00\x0e\x02\..."}
Мы снова видим разницу в NumPy массивах. Но вы также можете видеть, что информация о палитре и прозрачности больше не сохраняется как метаданные для явно RGBA
преобразованного изображения подушки, но кодируется в сами значения пикселей, в то время как они сохраняются при загрузке в режиме P
, Кроме того, вы видите, что [71, 112, 76]
(оливково-зеленый) используется для всех значений 0
пикселей, которые являются фоном. (Почему этот цвет был выбран, это другой вопрос.)
Так что, в зависимости от того, чего вы хотите добиться с извлеченным массивом NumPy, используйте режим P
при загрузке изображения с подушкой.
Надеюсь, это поможет!
----------------------------------------
System information
----------------------------------------
Platform: Windows-10-10.0.16299-SP0
Python: 3.8.1
Matplotlib: 3.2.0rc1
NumPy: 1.18.1
Pillow: 7.0.0
----------------------------------------