有没有一种简单的方法来比较两种颜色之间的相似程度?

26

有没有一种方法可以比较两个颜色彼此之间的相似度? 如果说它们两个都是蓝色的话。
目前我们比较它们的方式是手动将每个可能的颜色分配到一个颜色家族(红色,绿色,蓝色...)。 然后只需比较字符串 :)
但肯定可以将这个手动任务分配给一个整洁小巧的算法。


2
我们这些色盲者可能会对哪些颜色相近或不同有不同的看法... - Per Alexandersson
4个回答

22

你可能希望将颜色转换为HSL模型(色相、饱和度、亮度),然后按照HSL顺序在阈值内比较值。如果色相在被认为“接近”的容差范围内,则检查饱和度和亮度的“接近程度”。


1
我认为这个答案比David的更好,因为如果没有其他信息,我猜OP会发现基于HSL的比基于RGB的更有用。 - Adam Bellaire
1
@matt:请看我的对David回答的评论。基本上,我认为人们在比较颜色时自然会认为色调比饱和度或亮度更重要。 RGB将这些属性混合在表示中,使数值比较困难。 HSL将它们分开,使比较更容易。 - Adam Bellaire
不错的想法;但是有一些边角情况需要处理,例如,如果饱和度非常低,则色调并不重要。如果亮度非常低,则饱和度可能并不那么重要。 - Dickon Reed
@Dickon:说得好。我认为对于这种算法,总会有那些不太符合模型的特殊情况。 - Jeff Yates
使用这个HLS颜色选择器工具来比较多种颜色。 - Beau Smith
显示剩余2条评论

10

Delta-E(差异度)是一个代表两种颜色之间视觉“距离”的单一数字,数字越低,颜色对于人眼来说越相似。

有几种不同的计算方法…其中最流行的是CIE76(又称CIE 1976或dE76)。

每个方法使用不同的方式计算,但大多数都要求您将颜色转换为比RGB更好的(用于比较的)颜色模型。

对于CIE76,您基本上只需要将您的颜色转换为LAB颜色空间,然后计算它们之间的三维距离即可。

Wikipedia中有所有的公式:http://en.wikipedia.org/wiki/Color_difference

您可以使用在线颜色计算器检查您的工作:


9

我不确定有哪些算法,你可以考虑将RGB(红色、绿色、蓝色)值转换为HSB(色调、饱和度、亮度)。

色调本质上是“颜色”,因此您可以简单地比较色调值的接近程度。

请参见http://en.wikipedia.org/wiki/HSV_color_space


其他维度呢?从人类的角度来看,两种颜色在H值相同的情况下可能完全不同(例如红色和粉色)。 - Tibor Takács
我最初也是这么想的,但那样行不通。如果饱和度非常低,它实际上变成了灰度图像,其中色调分量的值开始变得不那么重要。因此,所有分量都根据其值发挥作用。 - AppleGrew

3
我知道这个问题已经有10年历史了,但是我想扩展Joe Zack的答案:
以下是我的Kotlin代码。
//Entry point here
//Color must be hexa for example "#829381"
fun calculateColorDistance(colorA: String, colorB: String): Double {
    val aColorRGBArray = getColorRGBArray(colorA)
    val bColorRGBArray = getColorRGBArray(colorB)
    val aColorLAB = getColorLab(aColorRGBArray)
    val bColorLAB = getColorLab(bColorRGBArray)
    return calculateColorDistance(aColorLAB, bColorLAB)
}

private fun calculateColorDistance(aColorLAB: DoubleArray, bColorLAB: DoubleArray): Double {
    val lab = aColorLAB[0] - bColorLAB[0]
    val aab = aColorLAB[1] - bColorLAB[1]
    val bab = aColorLAB[2] - bColorLAB[2]
    val sqrtlab = lab.pow(2)
    val sqrtaab = aab.pow(2)
    val sqrtbab = bab.pow(2)

    val sum = sqrtlab + sqrtaab + sqrtbab
    return sqrt(sum)
}

private fun getColorRGBArray(color: String): IntArray {
    val cleanColor = color.replace("#", "")
    val colorInt = Integer.parseInt(cleanColor, 16)
    val r = Color.red(colorInt)
    val g = Color.green(colorInt)
    val b = Color.blue(colorInt)
    return intArrayOf(r, g, b)
}

private fun getColorLab(colorRGB: IntArray): DoubleArray {
    val outLab = doubleArrayOf(0.0,0.0,0.0)
    ColorUtils.RGBToLAB(colorRGB[0], colorRGB[1], colorRGB[2], outLab)
    return outLab
}

calculateColorDistance会返回一个Double类型的值。这个值越低,颜色就越相似。

希望这能帮到有需要的人。


1
不错!我也喜欢 Kotlin - 你已经有了一个不错的库的开端 :) - Joe Zack

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接