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

时间:2016-01-31 12:45:15

标签: distance metrics hsv

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

假设每个颜色元素有3个组件:色调,饱和度和值。 Hue的范围介于0到360之间,饱和度介于0到1之间,值介于0到255之间。

同样色调具有圆形属性,例如,色调中的359在色调值中比在色调中的10更接近0。

有人能提供一个好的指标来计算HSV空间中2色素之间的距离吗?

4 个答案:

答案 0 :(得分:14)

首先是一个简短的警告:计算颜色的距离没有意义(在大多数情况下)。如果不考虑Colorimetry中50年研究的结果,例如CIECAM02 Color Space或距离测量的感知线性,这种距离测量的结果将是违反直觉的。类似的颜色"根据你的距离测量会出现"非常不同"对于观众和其他颜色,它们具有很大的距离"观众无法区分。然而...

实际问题似乎主要针对的是" Hue" part,这是0到360之间的值。事实上,0和360的值是相同的 - 它们都代表" red",如图所示:

Hue

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

然后,您可以计算这些色调值h0h1之间的距离,如

hueDistance = min(abs(h1-h0), 360-abs(h1-h0));

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

  

EDIT扩展评论:

  • " 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

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

distance = sqrt(dh*dh+ds*ds+dv*dv)

此HSV空间的距离为metric

答案 1 :(得分:4)

给定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

答案 2 :(得分:1)

如果您只想检查色相,Marco的答案就可以了。但是,对于考虑色相,饱和度和值的更准确的比较,肖恩的答案是正确的。 您不能简单地平均检查与色相,饱和度和值的距离,因为色相是一个圆,而不是法线向量。不同于RGB是红色,绿色和蓝色的向量

enter image description here

PS:我知道我在这篇文章中没有提供任何新的解决方案,但是Sean的回答确实救了我,除了要顶一下,我想承认这一点,因为它不是此处的最佳答案。

答案 3 :(得分:0)

让我们开始:

c0 = HSV( h0, s0, v0 )
c1 = HSV( h1, s1, v1 )

这里还有两个解决方案:

  1. (Helix Length)求欧氏空间中曲线的长度:

    x = ( s0+t*(s1-s0) ) * cos( h0+t*( h1-h0 ) )
    y = ( s0+t*(s1-s0) ) * sin( h0+t*( h1-h0 ) )
    z = ( v0+t*(v1-v0) )

t 从 0 到 1。

注意:h1-h0 不仅仅是减法,它是模数减法。 这可以通过旋转优化然后使用:h0=0, and h1 = min(abs(h1-h0), 360-abs(h1-h0))

  1. (RGB 上的螺旋长度)与上面相同,但将上面的曲线转换为 RGB 而不是欧几里得空间,然后计算弧长。 再次通过HSV颜色坐标进行凸组合,HSV线上的每个点都转换为RGB。
    用欧几里德范数计算 RGB 空间中那条线的长度。

    helix_rgb( t ) = RGB( HSV( h0+t*( h1-h0 ), s0+t*(s1-s0), v0+t*(v1-v0) ) )

t 从 0 到 1。

注意:h1-h0 不仅仅是减法,它是(大于)模数减法,例如

D(HSV(300,50,50),HSV(10,50,50)) = D(HSV(300,50,50),HSV( 0,50,50)) + D(HSV( 0,50,50), HSV(10,50,50))

指标对比:
Metrisc comparison
RGB(0,1,0) 是参照点,计算右下角图像颜色的距离。
彩色图像由规则 HSL([0-360], 100, [1-100] ) 生成。

EMEuclid with Modulo 的缩写,因为 Marco13 提出了 Sean Gerrish 的尺度。 HSI、HSL和HSV的解比较,RGB和CIE76(LAB)也有距离。

EM 与 Helix len、RGB2RGB、CIE76 等其他解决方案相比,EM 可以以非常低的成本提供可接受的结果。

https://github.com/dmilos/color.git 中,它实现了具有任意缩放的 EM
示例:

typedef ::color::hsv<double> color_t; // or HSI, HSL
color_t A = ::color::constant::orange_t{};  \
color_t B = ::color::constant::lime_t{};  \
auto distance = ::color::operation::distance<::color::constant::distance::hue_euclid_entity>( A, B, 3.1415926/* pi is default */ );