2010-01-20 12 views
22

Estamos creando una aplicación deportiva y desearíamos incorporar colores de equipo en varias partes de la aplicación.Algoritmo de lógica de color

Ahora cada equipo se puede representar usando varios colores diferentes.

Lo que me gustaría hacer es realizar una comprobación para verificar si los dos colores del equipo están dentro de un rango determinado el uno del otro, de modo que no se muestran dos colores similares.

Entonces, si el color del equipo primario del equipo 1 tiene un valor de rgb (255,0,0) (o # FF0000), y el color primario del equipo 2 es similar, digamos rgb (250,0,0), entonces elegiría un color diferente para uno de los equipos.

De ser posible, ¿qué enfoque podría tomar para realizar el control?

Gracias

Respuesta

38

Aquí es una theoretical explanation

Y el algo en 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 para un gran enlace, código (aunque OP solicite Java) –

+0

son los valores de rgb normalizados para el intervalo 0..1 o valores regulares en el rango 0..255? – Thariama

+0

Sería genial agregar una nota de cómo este algoritmo se compara con las técnicas descritas en el artículo [diferencia de color] (http://en.wikipedia.org/wiki/Color_difference) de Wikipedia, por ejemplo. CIEDE2000. – bluenote10

5

yo usaría distancia 3D entre dos colores, donde x, y, z son R, G, los valores de b.

Tome un vistazo a esta Biblioteca Perl:

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

Esto es fácil de aplicar a sí mismo.

Sólo asegúrese de que (R1-R2)^2 + (G1-G2)^2 + (B1-B2)^2> = umbral^2

+0

Tengo que admitir que esto funcionó bastante bien para la visión por ordenador, pero no estoy realmente tomando la anatomía en cuenta con esta respuesta. –

+2

Sí, yo diría que por el parecido entre dos colores (en lugar de lo similares que son) utilizaría el algoritmo de pgras. Los ojos humanos están lejos de ser perfectos: somos más sensibles al verde que al rojo o al azul, nuestra percepción del brillo es logrítmica, etc. –

2

Desde un punto de vista algoritmo, esto es bastante simple. Cada color representa un punto en un espacio 3D, y la diferencia entre los colores es la distancia entre esos puntos.

Presumiblemente, el punto aquí es garantizar que los colores sean visiblemente diferentes. Si ese es el caso, decidir la distancia mínima probablemente sea bastante difícil. El problema es que (al menos para las personas con visión normal) algunas diferencias son más fáciles de ver que otras. Por ejemplo, la mayoría de las personas son más sensibles a las pequeñas diferencias en tonos de verde que los cambios igualmente pequeños en tonos de rojo o azul. Existen algoritmos para tener esto en cuenta, pero se basan en la visión humana promedio, por lo que ninguno de ellos garantiza que sea exactamente correcto para una persona en particular.

Solo por diversión, es posible que desee echar un vistazo a X-rite's online color vision test.

+2

Esa página casi me hizo vomitar –

+0

, un punto en el espacio 3D es un punto de vista simple y no estoy de acuerdo, pero doy +1 para el enlace de prueba de visión de color – Thariama

5

La mayoría de las respuestas a esta pregunta sugerirán el cálculo de la distancia entre dos colores al mapear los valores RGB en un espacio 3D. El problema con esta técnica es que dos colores con matices similares, pero con diferentes niveles de saturación o brillo pueden alejarse unos de otros en el espacio RGB 3D que en dos colores con diferentes matices, pero con niveles de saturación y brillo muy similares. En otras palabras, un azul y un verde pueden estar más cerca en el espacio 3D RGB que dos tonos de rojo. En esta aplicación, al garantizar que los colores del equipo difieran, las diferencias de matiz deberían pesar mucho más que el brillo y la saturación.

Así que convertiría la asignación de color de RGB a los niveles de tono, saturación y brillo, y luego verificaría solo los valores de tono para una distancia suficiente.

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

+1

Me olvidé de la etiqueta Java en la primera lectura. La clase java.awt.Color tiene un método RGBtoHSB para la conversión. –

+0

Eso es suficiente si el OP tiene solo media docena de equipos; pero si hay 20 o más de 30, entonces ** tiene ** para tener en cuenta la saturación y el brillo. El enlace pgras dio a entender que su algoritmo arroja mejores resultados (que por supuesto son subjetivos) que la distancia HSV. –

+0

Como dice el OP, el objetivo es comparar solo dos colores a la vez. Sugerí que este método es una alternativa para probar si los métodos de distancia RGB dan resultados insuficientes. Como pienso más sobre esto, la comparación de los valores de matiz dará buenos resultados al comparar colores con valores de saturación y brillo más altos, y fallará al comparar colores con bajo brillo o baja saturación. Una mejora de este método sería verificar que al menos uno de los colores tenga valores de saturación y brillo suficientemente altos antes de verificar las diferencias de matiz. –

24

Aquí es algoritmo pgras' en 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

¿No ha aplicado ">> 8"? –

+0

@sam_k: '>> 8' es una mala forma de escribir'/256'. –

+0

¿Por qué es malo? ¿Puedes explicarme por mi propósito de aprendizaje? –

Cuestiones relacionadas