我想设计一个程序,可以帮助我在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在上面评论的那样:
这可能不会带来最好的“可见”差异……
这也意味着,如果你在处理图像,你的算法取决于你对“相似”的定义。
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
}
Actually I walked the same path a couple of months ago. There is no perfect answer to the question (that was asked here a couple of times) but there is one, more sophisticated than the sqrt(r-r) etc. answer and more easy to implement directly with RGB without moving to all kinds of alternate color spaces. I found this formula here which is a low cost approximation of the quite complicated real formula (by the CIE which is the W3C of colors, since this is a not finished quest, you can find older and simpler color difference equations there).
Good Luck.
编辑:为了子孙后代,这里是相关的C代码:
typedef struct {
unsigned char r, g, b;
} RGB;
double ColourDistance(RGB e1, RGB e2)
{
long rmean = ( (long)e1.r + (long)e2.r ) / 2;
long r = (long)e1.r - (long)e2.r;
long g = (long)e1.g - (long)e2.g;
long b = (long)e1.b - (long)e2.b;
return sqrt((((512+rmean)*r*r)>>8) + 4*g*g + (((767-rmean)*b*b)>>8));
}
颜色值有不止一个维度,所以没有内在的方法来比较两种颜色。您必须为您的用例确定颜色的含义,从而确定如何最好地比较它们。
很可能你想比较颜色的色相、饱和度和/或明度属性,而不是红/绿/蓝组件。如果你不知道如何比较它们,那就拿几对样品颜色,在心里比较一下,然后试着向自己证明/解释为什么它们相似/不同。
一旦你知道了你想要比较的颜色的哪些属性/成分,那么你就需要弄清楚如何从颜色中提取这些信息。
最有可能的是,你只需要将颜色从常见的RedGreenBlue表示转换为HueSaturationLightness,然后计算类似的东西
avghue = (color1.hue + color2.hue)/2
distance = abs(color1.hue-avghue)
这个例子会给你一个简单的标量值,指示颜色的渐变/色相彼此之间的距离。
参见维基百科上的HSL和HSV。