查找最近的RGB颜色

5

我被告知使用距离公式来确定颜色是否与其他颜色匹配,因此我有以下内容:

struct RGB_SPACE
{
    float R, G, B;
};

RGB_SPACE p = (255, 164, 32);  //pre-defined
RGB_SPACE u = (192, 35, 111);  //user defined

long distance = static_cast<long>(pow(u.R - p.R, 2) + pow(u.G - p.G, 2) + pow(u.B - p.B, 2));

这只是提供了一个距离,但我如何知道颜色是否与用户定义的颜色相匹配,至少达到25%?

我不确定,但我有一个想法,可以检查每个颜色值,看差异是否为25%。例如:

float R = u.R/p.R * 100;
float G = u.G/p.G * 100;
float B = u.B/p.B * 100;

if (R <= 25 && G <= 25 && B <= 25)
{
   //color matches with pre-defined color.
}
3个回答

7
我建议不要在RGB空间中进行检查。如果您有(0,0,0)和(100,0,0),根据cababunga的公式(以及考虑太多颜色相似的casablanca的公式),它们是相似的。然而,它们看起来非常不同。 HSL和HSV颜色模型基于人对颜色的解释,您可以轻松地为色调、饱和度和亮度分别指定距离(取决于您的情况下“相似”的含义是什么)。

实际上,Lab空间是基于人类解释的。 - zenpoy

4
"至少匹配25%"不是一个明确定义的问题。匹配至少25%的什么,根据什么度量?有大量可能的选择。如果你比较RGB颜色,那么显而易见的是从向量范数导出的距离度量。最重要的三个是:
  • 1-范数或“曼哈顿距离”:距离=|r1-r2| + |g1-g2| + |b1-b2|
  • 2-范数或欧几里得距离:距离=sqrt(pow(r1-r2, 2) + pow(g1-g2, 2) + pow(b1-b2, 2))(你可以计算其平方,这很好 - 如果你只是检查阈值,则可以通过平方阈值来避免sqrt)
  • 无穷范数:距离=max(|r1-r2|, |g1-g2|, |b1-b2|)
"
当然,还有很多其他可能性。您可以检查它们是否彼此之间距离在一定范围内:如果您希望在一个颜色通道的可能RGB值范围内允许高达25%的差异,则应分别使用三种方法的阈值为3/4 * 255,sqrt(3)/4 * 255和255/4。虽然这是一种非常粗略的指标。
衡量颜色之间距离的更好方法是将颜色转换为类似于CIELAB的感知均匀颜色空间,然后在那里进行比较;关于该主题,维基百科上有一篇相当不错的文章。根据您预期的应用程序,这可能过度了,但这些颜色空间是测量距离与人类视觉系统感知距离具有最佳相关性的地方。

我的意思是,用户定义的颜色至少匹配预定义颜色的25%。 - user963241

2
请注意,最大可能的距离是在(255, 255, 255)和(0, 0, 0)之间,它们之间的距离为3 * 255^2。显然,这两种颜色匹配度最低(0%匹配),它们相距100%。因此,至少25%的匹配意味着距离小于75%,即3 / 4 * 3 * 255^2 = 9 / 4 * 255 * 255。所以你可以检查是否:
distance <= 9 / 4 * 255 * 255

最大距离当然是sqrt(3 * 255^2)。我认为25%的匹配应该意味着差异不超过整个范围的1/4。因此,最终公式应为:distance <= sqrt(3)/4 * 255。 - cababunga
@cabanunga:你说的 sqrt 是对的,我之前没注意到是因为原帖中没有包含它。然而,“至少匹配25%”仍然意味着任何小于75%距离的内容都算匹配,因为距离越大,匹配度就越低。 - casablanca

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