假设我们有一组先验已知的n种颜色C。我们得到了一个颜色l的列表。
目标是对每种颜色l,将其与C中的颜色匹配,使距离函数D最小化。
最直接的方法是使用欧氏距离,但这不是一个好主意,因为下面的例子:
假设输入颜色是(0.1,0,0(非常暗的红色。假设棕色(0.5,0.5,0(和纯红色(1.0,0(都是C.
欧氏距离给出:
-
到棕色的距离=(0.4^2+0.5^2(=0.41
-
到红色的距离=(0.9^2(=0.81
因此,暗红色被映射为棕色而不是红色,这在视觉上没有意义。
我们可以试试切比雪夫距离:
-
到棕色的距离=最大值(0.4,0.5,0(=0.5
-
到红色的距离=最大值(0.9,0,0(=0.9
或者曼哈顿距离:
至棕色的距离=最大值(0.4+0.5(=0.9
到红色的距离=最大值(0.9+0+0(=0.9
第一个仍然选择棕色而不是红色,第二个选择两者都是同样有效的选择。虽然有所改进,但并不理想。
然而,我不知道如何测量"视觉距离",即一种颜色在人类看来是否"看起来是绿色的",例如,如何将所述颜色映射为绿色。
我正在使用opencv,我已经搜索了文档,但我似乎没有发现这个问题是否已经解决。
欢迎来到色彩世界!如果使用RGB,上述距离度量不太可能起作用,因为RGB不是一个感知均匀的颜色空间(颜色空间中向量之间的距离与人类感知的变化不相似(。CIELAB颜色空间被认为是一个感知上均匀的颜色空间。
一种流行的颜色距离度量是CIELAB\deltaE*,它经过了一些修改
这些距离度量在colormath
包中可用。
来自文档:
from colormath.color_objects import LabColor
from colormath.color_diff import delta_e_cie1976
# Reference color.
color1 = LabColor(lab_l=0.9, lab_a=16.3, lab_b=-2.22)
# Color to be compared to the reference.
color2 = LabColor(lab_l=0.7, lab_a=14.2, lab_b=-1.80)
# This is your delta E value as a float.
delta_e = delta_e_cie1976(color1, color2)
在您的问题中,如果已知颜色集(C
(的大小很小(例如10(,则即使是delta_E
也可能无法按预期工作。一种更可靠的方法是收集一个新的集合S
,它在C
中的每种颜色都有很多阴影(你可以使用颜色词典(,并将l
中的每一种颜色映射到S
中的壁橱中,然后映射到C
。通过预先计算距离度量,您可以使用类似kd-tree的数据结构来加快搜索速度。