2010-01-20 2 views
22

Мы строим спортивное приложение и хотели бы включать цвета команды в различные части приложения.Цветовой логический алгоритм

Теперь каждая команда может быть представлена ​​несколькими цветами.

Что бы я хотел сделать, это выполнить проверку, чтобы проверить, находятся ли цвета двух команд в определенном диапазоне друг от друга, так что я не показываю два одинаковых цвета.

Итак, если основной цвет команды команды 1 имеет значение rgb (255,0,0) (или # FF0000), а основной цвет команды 2 аналогичен, скажем, rgb (250,0,0), то мы выбрал бы другой цвет для одной из команд.

Если возможно, какой подход я могу предпринять для проверки?

Благодаря

ответ

38

Вот theoretical explanation

И алго в 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)); 
} 
+1

+1 для отличной ссылки, код (хотя OP запрошен для Java) –

+0

- значения rgb, нормированные на интервал 0..1 или регулярные значения int he range 0..255? – Thariama

+0

Было бы здорово добавить примечание, как этот алгоритм сравнивается с методами, описанными в статье [color difference] (http://en.wikipedia.org/wiki/Color_difference) в Википедии, например. CIEDE2000. – bluenote10

5

Я хотел бы использовать 3d расстояние между двумя цветами, где х, у, г являются R, G, B значения.

Взгляните на эту библиотеку Perl:

http://metacpan.org/pod/Color::Similarity::RGB

Это легко реализовать себя.

Просто убедитесь, что (R1-R2)^2 + (G1-G2)^2 + (В1-В2)^2> = порог^2

+0

Я должен признать, что это работало достаточно хорошо для компьютерного зрения, но я на самом деле не принимая анатомию во внимание с этим ответом. –

+2

Да, я бы сказал, как похожие два цвета LOOK (а не как они похожи), я бы использовал алгоритм pgras. Человеческие глаза далеки от совершенства: мы более чувствительны к зеленому, чем красный или синий, наше восприятие яркости является логрифмическим и т. Д. –

2

С алгоритма точки зрения, это достаточно просто. Каждый цвет представляет собой точку в трехмерном пространстве, а разница между цветами - это расстояние между этими точками.

Предположительно, здесь необходимо убедиться, что цвета заметно отличаются. Если это так, решение о минимальном расстоянии, вероятно, будет довольно сложно. Проблема в том, что (по крайней мере для людей с нормальным зрением) некоторые различия легче увидеть, чем другие. Например, большинство людей более чувствительны к небольшим различиям в оттенках зеленого, чем одинаково небольшие изменения в оттенках красного или синего. Есть алгоритмы, чтобы принять это во внимание, но они основаны на среднем человеческом видении, поэтому ни один из них не гарантированно точно подходит для любого человека.

Просто для удовольствия, вы можете взглянуть на X-rite's online color vision test.

+2

Эта страница почти заставила меня puke –

+0

ну, точка в 3D-пространстве - простая точка зрения, и я не согласен, но я даю +1 для контрольная ссылка цветного зрения – Thariama

5

Большинство ответов по этому вопросу предложит рассчитать расстояние между двумя цветами при сопоставлении значений RGB в 3D-пространстве. Проблема с этим методом заключается в том, что два цвета с похожими оттенками, но разные уровни насыщенности или яркости могут отображаться дальше друг от друга в пространстве 3D RGB, чем два цвета с разными оттенками, но очень похожими уровня насыщенности и яркости. Другими словами, синий и зеленый могут быть ближе в пространстве 3D RGB, чем два оттенка красного. В этом приложении, чтобы цвета команды отличались друг от друга, различия оттенков должны весить гораздо больше, чем яркость и насыщенность.

Поэтому я бы преобразовал цветовое отображение из RGB в оттенки, насыщенность и уровни яркости, а затем проверял только значения оттенков на достаточном расстоянии.

Wikipedia has an explanation for converting RGB to HSV.LiteratePrograms has some sample code.

+1

Я пропустил тег Java в первом чтении. Класс java.awt.Color имеет метод RGBtoHSB для преобразования. –

+0

Этого достаточно, если ОП имеет только полдюжины команд; но если их 20 или 30+, то он ** ** учитывает насыщенность и яркость. Ссылка pgras дала утверждения, что их алгоритм дает лучшие результаты (что, конечно, субъективно), чем HSV-расстояние. –

+0

Как говорит OP, цель состоит в том, чтобы сравнить только два цвета во время. Я предположил, что этот метод является альтернативой попытке, если методы RGB дистанции дают недостаточные результаты. Как я уже говорил, сравнение только значений оттенков даст хорошие результаты при сравнении цветов с более высокими значениями насыщенности и яркости и не сработает при сравнении цветов с низкой яркостью или низкой насыщенностью. Улучшением этого метода будет проверка того, что по крайней мере один из цветов имеет достаточно высокие значения насыщенности и яркости перед проверкой различий оттенка. –

24

Вот алгоритм pgras' в Java:

public double ColourDistance(Color c1, Color c2) 
{ 
    double rmean = (c1.getRed() + c2.getRed())/2; 
    int r = c1.getRed() - c2.getRed(); 
    int g = c1.getGreen() - c2.getGreen(); 
    int b = c1.getBlue() - c2.getBlue(); 
    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); 
} 
+0

Вы не применили ">> 8"? –

+0

@sam_k: '>> 8' - это плохой способ записи'/256'. –

+0

Почему это плохо? Можете ли вы объяснить мне мою цель обучения. –

Смежные вопросы