我想设计一个程序,可以帮助我在5种预定义的颜色中评估哪一种更类似于可变颜色,以及与可变颜色的百分比。问题是我不知道如何手动一步一步地做到这一点。所以想一个程序就更难了。
更多细节:颜色来自不同颜色的管子和凝胶的照片。我有5个不同颜色的管子,每个代表5个等级中的1个。我想拍摄其他样本的照片,然后在电脑上通过比较颜色来评估样本属于哪个级别,我也想知道一个近似的百分比。我想要一个这样做的程序:http://www.colortools.net/color_matcher.html
如果你能告诉我该采取什么步骤,即使它们需要我手动思考和执行。那会很有帮助的。
我在我的android up中使用了这个,它似乎令人满意,尽管不建议使用RGB空间:
public double colourDistance(int red1,int green1, int blue1, int red2, int green2, int blue2)
{
double rmean = ( red1 + red2 )/2;
int r = red1 - red2;
int g = green1 - green2;
int b = blue1 - blue2;
double weightR = 2 + rmean/256;
double weightG = 4.0;
double weightB = 2 + (255-rmean)/256;
return Math.sqrt(weightR*r*r + weightG*g*g + weightB*b*b);
}
然后我用下面的方法得到相似度的百分比:
double maxColDist = 764.8339663572415;
double d1 = colourDistance(red1,green1,blue1,red2,green2,blue2);
String s1 = (int) Math.round(((maxColDist-d1)/maxColDist)*100) + "% match";
它工作得很好。
我猜你最后想分析一幅完整的图像,对吧?所以你可以检查单位颜色矩阵的最小/最大差值。
大多数处理图形的数学操作都使用矩阵,因为使用矩阵的可能算法通常比经典的逐点距离和比较计算更快。(例如,对于使用DirectX, OpenGL,…的操作)
所以我认为你应该从这里开始:
http://en.wikipedia.org/wiki/Identity_matrix
http://en.wikipedia.org/wiki/Matrix_difference_equation
…正如Beska在上面评论的那样:
这可能不会带来最好的“可见”差异……
这也意味着,如果你在处理图像,你的算法取决于你对“相似”的定义。
颜色值有不止一个维度,所以没有内在的方法来比较两种颜色。您必须为您的用例确定颜色的含义,从而确定如何最好地比较它们。
很可能你想比较颜色的色相、饱和度和/或明度属性,而不是红/绿/蓝组件。如果你不知道如何比较它们,那就拿几对样品颜色,在心里比较一下,然后试着向自己证明/解释为什么它们相似/不同。
一旦你知道了你想要比较的颜色的哪些属性/成分,那么你就需要弄清楚如何从颜色中提取这些信息。
最有可能的是,你只需要将颜色从常见的RedGreenBlue表示转换为HueSaturationLightness,然后计算类似的东西
avghue = (color1.hue + color2.hue)/2
distance = abs(color1.hue-avghue)
这个例子会给你一个简单的标量值,指示颜色的渐变/色相彼此之间的距离。
参见维基百科上的HSL和HSV。
请参阅维基百科关于色差的文章以获得正确的线索。
基本上,你想要在多维颜色空间中计算一个距离度量。
但是RGB并不是“感知上一致的”,所以Vadim建议的欧几里得RGB距离度量将与人类感知的颜色之间的距离不匹配。首先,L*a*b*是一个感知上均匀的颜色空间,delta度量是常用的。但有更精致的色彩空间和更精致的delta公式,更接近人类的感知。
你需要学习更多关于颜色空间和光源的知识来进行转换。但如果想要一个比欧几里得RGB度量更好的快速公式,只需这样做:
假设你的RGB值在sRGB颜色空间中
找到sRGB到L*a*b*的转换公式
将sRGB颜色转换为L*a*b*
计算两个L*a*b*值之间的delta
计算成本不高,只是一些非线性公式和一些乘法和加法。