list comprehension for opencv bgr to hex binning for colour palette. TypeError: cannot unpack non-iterable numpy.uint8 object

list comprehension for opencv bgr to hex binning for colour palette. TypeError: cannot unpack non-iterable numpy.uint8 object

下面的代码采用 opencv 图像,将其转换为 rgb,然后使用列表推导逐步将像素转换为十六进制,然后计算每种颜色的像素数。

如何使用列表理解来减少这段代码,并解决底部的 TypeError?

import cv2
bgr_img = cv2.imread(img_input)
rgb_img = cv2.cvtColor(bgr_img, cv2.COLOR_BGR2RGB) # Hex starts with Red

文件的形状为 (300, 700, 3) 即 [[[ 90, 150, 140 ], [90 150 140], [90 150 140] ....

palette = dict()
for i in img:
    for j in i:
        colour_hex = [f"#{a:02x}{b:02x}{c:02}" for a,b,c in j]
        if colour_hex in palette:
            palette[colour_hex] +=1
        else:
            palette[colour_hex] = 1

因此字典包含十六进制颜色的值键对以及图像中每个像素有多少是该十六进制颜色。

错误消息显示为

类型错误:无法解压不可迭代的 numpy.uint8 对象

感谢下面的回复,更短的代码如下:-

import cv2
bgr_img = cv2.imread(img_input)
rgb_img = cv2.cvtColor(bgr_img, cv2.COLOR_BGR2RGB) # Hex starts with Red
palette = dict()
for i in img:
    for j in i:
        colour_hex = f"#{:02x}{:02x}{:02x}".format(*j)
        if colour_hex in palette:
            palette[colour_hex] +=1
        else:
            palette[colour_hex] = 1

可以再短一点吗? / 更多 Pythonic 使用列表理解 ?

您 运行 循环 j 以创建 colour_hex 的列表,但您实际上只想要 colour_hex 用于 j

替换为:

colour_hex = [f"#{a:02x}{b:02x}{c:02}" for a,b,c in j]

有了这个:

colour_hex = "#{:02x}{:02x}{:02}".format(*j)

如果您不需要 bgr_img 来做其他任何事情并且期望有许多不同的颜色,我更喜欢这个更短、也许更 Pythonic 的解决方案:

from cv2
from collections import defaultdict

rgb_img = cv2.cvtColor(cv2.imread(img_input), cv2.COLOR_BGR2RGB)
palette = defaultdict(int)
for i in rgb_img:
    for j in i:
        palette["#{:02x}{:02x}{:02x}".format(*j)] += 1

另一方面,如果您不需要 rgb_img,您也可以直接使用 bgr_img,从而避免调用 cvtColor:

from cv2
from collections import defaultdict

bgr_img = cv2.imread(img_input)
palette = defaultdict(int)
for i in bgr_img :
    for j in i:
        palette["#{2:02x}{1:02x}{0:02x}".format(*j)] += 1