OpenCV mask 到 PIL 图像的转换(与 P 模式混淆)

问题描述 投票:0回答:1

我正在尝试替换 OpenCV 最初用 PIL 编写的部分代码。 理想情况下,我想消除 PIL 或至少使输入(first_frame)是 OpenCV 数组。

原始(PIL)代码:

from PIL import Image
import numpy as np
import cv2

first_frame_path = "00000.png"
image2 = Image.open(first_frame_path)
print(image2.mode) # out: P <---

image2_p = image2.convert("P")
image2_pil = np.array(image2_p)
print(image2_pil.mean()) # out: 0.039107 <---

OpenCV代码:

from PIL import Image
import numpy as np
import cv2

first_frame_path = "00000.png"

image = cv2.imread(first_frame_path, cv2.IMREAD_COLOR)

image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
image_from_array = Image.fromarray(image)
print(image_from_array.mode) # out: RGB <---

image_p = image_from_array.convert("P")
image_pil = np.array(image_p)
print(image_pil.mean()) # out: 0.48973 <---

我应该如何调整我的 OpenCV 代码以使 image_pilimage2_pil 具有相同的值?

我计算 mean() 只是为了表明这两个数组是不同的,我的目标是获得相同的结果。

我正在使用简单的面具:

我知道差异来自于原始代码中掩码直接加载为 P,与 OpenCV 代码相矛盾,其中它是 RGB。不幸的是,我不知道如何解决它。我试图指定:

Image.fromarray(image, mode="P")

但是,然后我收到错误:

发生异常:ValueError 维度过多:3 > 2。

您能告诉我怎样才能获得与原始代码中相同的 NumPy 数组吗?

python opencv python-imaging-library
1个回答
0
投票

这就是你想要的。它依赖于允许 PIL 将图像转换为 RGB,然后返回到调色板模式,每次都以自己的(希望是确定性的)方式创建(或重新创建)调色板。

总的来说,你所做的事情真的很不明智......

#!/usr/bin/env python3

import cv2 as cv
import numpy as np
from PIL import Image

# Load original image
im = Image.open('26dQH.png')

# Convert to RGB, then back to palette so that **PIL decides the palette**
im = im.convert('RGB').convert('P', palette=Image.Palette.ADAPTIVE)

# Get its colours
print(f'im.getcolors(): {im.getcolors()}')
# prints im.getcolors(): [(5367, 0), (5297, 1), (399256, 2)]

# Print first 3 palette entries
print(np.array(im.getpalette()).reshape((-1,3))[:3])

# Prints:
# [[  0 128   0]
#  [128   0   0]
#  [  0   0   0]]

# Read same image using OpenCV and convert to palette-mode PIL Image
na = cv.imread('26dQH.png', cv.IMREAD_COLOR)
pi = Image.fromarray(na).convert('P', palette=Image.Palette.ADAPTIVE)

# Get its colours
print(f'pi.getcolors(): {pi.getcolors()}') 
# prints pi.getcolors(): [(5367, 0), (5297, 1), (399256, 2)]

# Print first 3 palette entries
print(np.array(im.getpalette()).reshape((-1,3))[:3])
# Prints:
# [[  0 128   0]
#  [128   0   0]
#  [  0   0   0]]
© www.soinside.com 2019 - 2024. All rights reserved.