我想设计一个程序,可以帮助我在5种预定义的颜色中评估哪一种更类似于可变颜色,以及与可变颜色的百分比。问题是我不知道如何手动一步一步地做到这一点。所以想一个程序就更难了。

更多细节:颜色来自不同颜色的管子和凝胶的照片。我有5个不同颜色的管子,每个代表5个等级中的1个。我想拍摄其他样本的照片,然后在电脑上通过比较颜色来评估样本属于哪个级别,我也想知道一个近似的百分比。我想要一个这样做的程序:http://www.colortools.net/color_matcher.html

如果你能告诉我该采取什么步骤,即使它们需要我手动思考和执行。那会很有帮助的。


当前回答

只是另一个答案,尽管它与Supr的答案相似-只是不同的颜色空间。

问题是:人类感知颜色的差异并不均匀,而RGB颜色空间忽略了这一点。因此,如果你使用RGB颜色空间,只是计算两种颜色之间的欧几里得距离,你可能会得到一个在数学上绝对正确的差异,但与人类告诉你的不一致。

This may not be a problem - the difference is not that large I think, but if you want to solve this "better" you should convert your RGB colors into a color space that was specifically designed to avoid the above problem. There are several ones, improvements from earlier models (since this is based on human perception we need to measure the "correct" values based on experimental data). There's the Lab colorspace which I think would be the best although a bit complicated to convert it to. Simpler would be the CIE XYZ one.

这里有一个网站列出了在不同颜色空间之间转换的公式,所以你可以尝试一下。

其他回答

这只是我第一次想到的一个想法(如果愚蠢的话,对不起)。 颜色的三个分量可以假定为点的三维坐标,然后可以计算点之间的距离。

外汇期货

Point1 has R1 G1 B1
Point2 has R2 G2 B2

颜色之间的距离为

d=sqrt((r2-r1)^2+(g2-g1)^2+(b2-b1)^2)

比例是

p=d/sqrt((255)^2+(255)^2+(255)^2)

只是另一个答案,尽管它与Supr的答案相似-只是不同的颜色空间。

问题是:人类感知颜色的差异并不均匀,而RGB颜色空间忽略了这一点。因此,如果你使用RGB颜色空间,只是计算两种颜色之间的欧几里得距离,你可能会得到一个在数学上绝对正确的差异,但与人类告诉你的不一致。

This may not be a problem - the difference is not that large I think, but if you want to solve this "better" you should convert your RGB colors into a color space that was specifically designed to avoid the above problem. There are several ones, improvements from earlier models (since this is based on human perception we need to measure the "correct" values based on experimental data). There's the Lab colorspace which I think would be the best although a bit complicated to convert it to. Simpler would be the CIE XYZ one.

这里有一个网站列出了在不同颜色空间之间转换的公式,所以你可以尝试一下。

Kotlin版本与你想匹配的百分比有多少。

方法调用,参数为percent

isMatchingColor(intColor1, intColor2, 95) // should match color if 95% similar

方法体

private fun isMatchingColor(intColor1: Int, intColor2: Int, percent: Int = 90): Boolean {
    val threadSold = 255 - (255 / 100f * percent)

    val diffAlpha = abs(Color.alpha(intColor1) - Color.alpha(intColor2))
    val diffRed = abs(Color.red(intColor1) - Color.red(intColor2))
    val diffGreen = abs(Color.green(intColor1) - Color.green(intColor2))
    val diffBlue = abs(Color.blue(intColor1) - Color.blue(intColor2))

    if (diffAlpha > threadSold) {
        return false
    }

    if (diffRed > threadSold) {
        return false
    }

    if (diffGreen > threadSold) {
        return false
    }

    if (diffBlue > threadSold) {
        return false
    }

    return true
}

颜色值有不止一个维度,所以没有内在的方法来比较两种颜色。您必须为您的用例确定颜色的含义,从而确定如何最好地比较它们。

很可能你想比较颜色的色相、饱和度和/或明度属性,而不是红/绿/蓝组件。如果你不知道如何比较它们,那就拿几对样品颜色,在心里比较一下,然后试着向自己证明/解释为什么它们相似/不同。

一旦你知道了你想要比较的颜色的哪些属性/成分,那么你就需要弄清楚如何从颜色中提取这些信息。

最有可能的是,你只需要将颜色从常见的RedGreenBlue表示转换为HueSaturationLightness,然后计算类似的东西

avghue = (color1.hue + color2.hue)/2
distance = abs(color1.hue-avghue)

这个例子会给你一个简单的标量值,指示颜色的渐变/色相彼此之间的距离。

参见维基百科上的HSL和HSV。

我尝试了各种方法,如LAB颜色空间,HSV比较,我发现光度在这个目的上非常有效。

这是Python版本

def lum(c):
    def factor(component):
        component = component / 255;
        if (component <= 0.03928):
            component = component / 12.92;
        else:
            component = math.pow(((component + 0.055) / 1.055), 2.4);

        return component
    components = [factor(ci) for ci in c]

    return (components[0] * 0.2126 + components[1] * 0.7152 + components[2] * 0.0722) + 0.05;

def color_distance(c1, c2):

    l1 = lum(c1)
    l2 = lum(c2)
    higher = max(l1, l2)
    lower = min(l1, l2)

    return (higher - lower) / higher


c1 = ImageColor.getrgb('white')
c2 = ImageColor.getrgb('yellow')
print(color_distance(c1, c2))

会给你

0.0687619047619048