这里有一些演示代码可以将现有的 RGB 图像转换为indexed color image。请记住,Pillow 仅允许在某些调色板中存储 256 种不同的颜色,参见。 Image.putpalette。因此,请确保您的输入图像包含的不同颜色不超过 256 种。
另外,我假设调色板是已知的,并且现有 RGB 图像中的所有颜色都完全来自该调色板。否则,您需要添加代码以提取所有颜色,并事先设置适当的调色板。
import cv2
import numpy as np
from PIL import Image
# Existing palette as nested list
palette = [
[0, 128, 0],
[0, 64, 128],
[0, 128, 128],
[0, 64, 0],
]
# Existing RGB image, read with OpenCV (Attention: Correct color ordering)
img = cv2.imread('myimage.png')
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
h, w = img.shape[:2]
print(img)
# [[[ 0 128 0]
# [ 0 128 0]
# [ 0 128 0]
# ...
# [ 0 128 128]
# [ 0 128 128]
# [ 0 128 128]]
# Generate grayscale output image with replaced values
img_pal = np.zeros((h, w), np.uint8)
for i_p, p in enumerate(palette):
img_pal[np.all(img == p, axis=2)] = i_p
cv2.imwrite('output.png', img_pal)
# Read grayscale image with Pillow
img_pil = Image.open('output.png')
print(np.array(img_pil))
# [[0 0 0 ... 2 2 2]
# [0 0 0 ... 2 2 2]
# [0 0 0 ... 2 2 2]
# ...
# [1 1 1 ... 3 3 3]
# [1 1 1 ... 3 3 3]
# [1 1 1 ... 3 3 3]]
# Convert to mode 'P', and apply palette as flat list
img_pil = img_pil.convert('P')
palette = [value for color in palette for value in color]
img_pil.putpalette(palette)
# Save indexed image for comparison
img_pil.save('output_indexed.png')
这是现有的RGB图像myimage.png:
那是中间的output.png——你很可能不会看到不同的深灰色、近乎黑色的颜色:
为了比较,这是在转换为mode P 并应用调色板之后的索引彩色图像:
----------------------------------------
System information
----------------------------------------
Platform: Windows-10-10.0.19041-SP0
Python: 3.9.1
PyCharm: 2021.1.1
NumPy: 1.19.5
OpenCV: 4.5.2
Pillow: 8.2.0
----------------------------------------