寻找最近的RGB颜色

时间:2010-11-13 07:01:29

标签: c++ colors rgb

我被告知使用距离公式来查找颜色是否匹配另一个,所以我有,

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 个答案:

答案 0 :(得分:7)

我建议不要检查RGB空间。如果你有(0,0,0)和(100,0,0)它们是相似的cababungas公式(以及根据卡萨布兰卡考虑太多颜色相似)。然而,他们看起来很不一样。

HSL and HSV颜色模型基于人类对颜色的解释,然后您可以轻松地指定相互独立的色调,饱和度和亮度的距离(取决于您的情况中“相似”的含义)。 / p>

答案 1 :(得分:4)

“匹配至少25%”不是一个明确定义的问题。匹配至少25%的内容,并根据什么指标?有很多可能的选择。如果比较RGB颜色,那么显而易见的是从矢量规范派生的距离度量。最重要的三个是:

  • 1-norm或“Manhattan distance”:距离= abs(r1-r2)+ abs(g1-g2)+ abs(b1-b2)
  • 2范数或欧几里德距离:距离= sqrt(pow(r1-r2,2)+ pow(g1-g2,2)+ pow(b1-b2,2))(你计算它的平方,没问题 - 如果您只是通过平方阈值来检查阈值,则可以避开sqrt。
  • 无穷大范围:距离=最大值(abs(r1-r2),abs(g1-g2),abs(b1-b2))

当然还有很多其他的可能性。您可以检查它们是否在彼此的某个距离内:如果您希望在一个颜色通道中允许最多25%的差异(在可能的RGB值范围内),则用于3种方法的阈值为3/4 * 255,sqrt(3)/ 4 * 255和255/4。这是一个非常粗略的指标。

测量颜色之间距离的更好方法是将颜色转换为感知均匀的颜色空间,如CIELAB并在那里进行比较;关于这个问题也有一个相当不错的Wikipedia article。根据您的预期应用,这可能是过度的,但这些是测量距离与人类视觉系统感知距离最佳相关的色彩空间。

答案 2 :(得分: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