计算HSV空间中颜色之间的距离

use*_*846 8 metrics distance hsv

我打算在HSV空间中找到两种颜色之间的距离度量.

假设每个颜色元素有3个分量:色调,饱和度和值.色调范围在0到360之间,饱和度范围在0到1之间,值范围在0到255之间.

另外,色调具有圆形特性,例如,色调中的359在色调值中比在色调中的10更接近0.

任何人都可以提供一个很好的指标来计算HSV空间中2色元素之间的距离吗?

Mar*_*o13 14

首先是一个简短的警告:计算颜色的距离没有意义(在大多数情况下).如果不考虑比色法中50年研究的结果,比如CIECAM02色彩空间或距离测量的感知线性,这种距离测量的结果将是违反直觉的.根据您的距离测量"相似"的颜色对于观看者来说将"非常不同",并且具有大"距离"的其他颜色将被观看者无法区分.然而...


实际问题似乎主要针对"Hue"部分,它是0到360之间的值.实际上,0和360的值是相同的 - 它们都代表"红色",如下图所示:

色调

现在,计算其中两个值的差异可以归结为计算圆周为360的圆上两点的距离.您已经知道这些值严格在[0,360]范围内.如果您不知道,则必须使用浮点模运算将它们带入此范围.

然后,你可以计算出这些色调值之间的距离,h0并且h1,作为

hueDistance = min(abs(h1-h0), 360-abs(h1-h0));
Run Code Online (Sandbox Code Playgroud)

想象一下,这就是画圆圈上的两个点,并选择他们描述的较小的"蛋糕" - 也就是说,它们之间的距离是顺时针方向还是逆时针方向.


编辑扩展评论:

  • "Hue"元素在[0,360]范围内.使用上面的公式,您可以计算两种色调之间的距离.该距离在[0,180]范围内.将距离除以180.0将得到[0,1]中的值

  • "饱和度"元素在[0,1]范围内.两个饱和度之间的(绝对)差异也将在[0,1]范围内.

  • "值"元素在[0,255]范围内.因此,两个值之间的绝对差值也在[0,255]范围内.将此差值除以255.0将得到[0,1]中的值.

所以想象你有两个HSV元组.给他们打电话(h0,s0,v0)(h1,s1,v1).然后您可以按如下方式计算距离:

dh = min(abs(h1-h0), 360-abs(h1-h0)) / 180.0
ds = abs(s1-s0)
dv = abs(v1-v0) / 255.0
Run Code Online (Sandbox Code Playgroud)

这些值中的每一个都在[0,1]范围内.您可以计算此元组的长度:

distance = sqrt(dh*dh+ds*ds+dv*dv)
Run Code Online (Sandbox Code Playgroud)

并且该距离将是HSV空间的度量.


mvo*_*ker 8

如果您只想检查色调,Marco 的答案就可以了。然而,为了更准确地比较考虑到色调、饱和度和明度,肖恩的答案是正确的。你不能简单地同等地检查色调、饱和度和明度的距离,因为色调是一个圆,而不是一个法向量。它不像 RGB 那样,红、绿、蓝是向量


如果使用色度,它是一个圆锥体

色度锥体


如果使用饱和度,它是一个圆柱体

饱和气缸


PS:我知道我不会在这篇文章中给出任何新的解决方案,但肖恩的回答确实拯救了我,除了投票之外我还想承认它,因为它不是这里的最佳答案。


小智 5

给定hsv值,将其标准化为[0,2pi),[0,1],[0,1]范围,此公式会将颜色投影到HSV圆锥中,并为您提供该圆锥中的平方(笛卡尔)距离:

   ( sin(h1)*s1*v1 - sin(h2)*s2*v2 )^2
 + ( cos(h1)*s1*v1 - cos(h2)*s2*v2 )^2
 + ( v1 - v2 )^2
Run Code Online (Sandbox Code Playgroud)

  • 这个答案看起来比公认的更正确。因为 HSV 空间是**非线性**并且应用 L2 范数会导致不正确的距离。将 HSV 颜色转换为线性空间 (a,b,c) 会更好:a = sv cos(h), b = sv sin(h), and c = v (2认同)