Нахождение ближайшего цвета RGB - PullRequest
5 голосов
/ 13 ноября 2010

Мне сказали использовать формулу расстояния, чтобы найти, совпадает ли цвет с другим, поэтому у меня есть,

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 голосов
/ 13 ноября 2010

Я бы предложил не проверять в RGB-пространстве. Если у вас есть (0,0,0) и (100,0,0), они похожи в соответствии с формулой Cababungas (а также в соответствии с формулой Касабланки, которая считает слишком много цветов похожими). Тем не менее, они выглядят довольно по-другому.

Цветовые модели HSL и HSV основаны на человеческой интерпретации цветов, и вы можете легко указать расстояние для оттенка, насыщенности и яркости независимо друг от друга (в зависимости от того, что означает "похожий" случай).

4 голосов
/ 13 ноября 2010

«Соответствует не менее чем на 25%» не является четко определенной проблемой. Соответствует не менее чем на 25% и по какой метрике? Там множество возможных вариантов. Если вы сравните цвета RGB, очевидными будут метрики расстояния, полученные из векторных норм. Три наиболее важных из них:

  • 1-норма или «Манхэттенское расстояние»: расстояние = abs (r1-r2) + abs (g1-g2) + abs (b1-b2)
  • 2-нормальное или евклидово расстояние: расстояние = sqrt (pow (r1-r2, 2) + pow (g1-g2, 2) + pow (b1-b2, 2)) (вы вычисляете квадрат этого, который все в порядке - вы можете избежать sqrt, если вы просто проверяете пороговое значение, также возводя в квадрат пороговое значение)
  • Бесконечность: расстояние = max (абс (r1-r2), абс (g1-g2), абс (b1-b2))

Конечно, есть много других возможностей. Вы можете проверить, находятся ли они на некотором расстоянии друг от друга: если вы хотите разрешить разницу в 25% (в диапазоне возможных значений RGB) в одном цветовом канале, пороговые значения, которые нужно использовать для трех методов, равны 3/4 * 255, sqrt (3) / 4 * 255 и 255/4 соответственно. Это очень грубая метрика.

Лучший способ измерить расстояния между цветами - преобразовать ваши цвета в перцептуально однородное цветовое пространство, такое как CIELAB и провести сравнение там; на эту тему есть и неплохая статья в Википедии . Это может быть излишним в зависимости от вашего предполагаемого применения, но это те цветовые пространства, где измеренные расстояния имеют наилучшую корреляцию с расстояниями, воспринимаемыми зрительной системой человека.

2 голосов
/ 13 ноября 2010

Обратите внимание, что максимально возможное расстояние находится между (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
...