Algoritmo para modificar un color para que sea menos similar que el fondo

23

Estoy creando una demostración de 20 bolas rebotando entre sí, con un fondo lleno de un color sólido. El color de cada bola se elige al azar con randint(0, 255)cada componente de tupla R, G, B.

El problema es que algunas bolas terminan con un color muy similar al del fondo, lo que las hace difíciles de ver. Me gustaría evitar eso, ya sea rodando otro color si el elegido es demasiado similar (dentro de un umbral dado) o alejándolo del color de fondo.

¿Cómo calcular un índice de similitud para usar como umbral? ¿O cómo transformar un color para hacerlo, digamos, menos azulado ?

Descargo de responsabilidad obvio: no sé nada sobre la teoría del color, ¡así que no sé si los conceptos anteriores existen!

Estoy codificando en Python, pero estoy buscando conceptos y estrategias, por lo que el pseudocódigo está bien (o solo la teoría).

EDITAR:

Para aclarar algunos puntos:

  • Cada bola tiene su propio color aleatorio. Me gustaría que permanecieran lo más aleatorios posible y que explorasen lo más posible el espacio de color (ya sea RGB o HSV, pygameacepta ambos formatos para definir el color)

  • Solo me gustaría evitar que cada color esté "demasiado cerca" del fondo. El problema no es solo el tono: estoy perfectamente bien con una bola azul claro sobre un fondo azul oscuro (o un "azul completo" contra un azul "blanco-ish", etc.)

  • Por ahora, no me importa si una bola termina con un color similar (o incluso idéntico) a otra bola. Evitar eso es una ventaja, pero es un problema menor.

  • El color de fondo es un color RGB único y constante. Por ahora estoy usando azul "básico" (0, 0, 255), pero no estoy decidido con eso. Por lo tanto, considere que el fondo es de un color arbitrario (con matices arbitrarios, brillo, saturación, etc.).

EDIT2:

TL, versión DR: simplemente dé una forma de crear X colores aleatorios para que ninguno "se desvanezca demasiado" en un contexto de color arbitrario (pero único y constante)

MestreLion
fuente
1
¿Por qué no simplemente poner un contorno alrededor de cada bola?
cenizas999
1
Entonces podría haber un problema al hacer un color de contorno distinto del color de fondo Y de las bolas;)
Kromster dice que apoya a Monica el
1
@AlexM .: difícil de creer que no haya una solución fácil para "generar colores aleatorios evitando uno arbitrario"
MestreLion
1
@MestreLion solo usa negro para el contorno y genera colores con un valor RGB mínimo de 128. Es así de fácil.
cenizas999

Respuestas:

33

Puede utilizar el hecho de que los colores forman un espacio de color (tridimensional) y calcular una distancia en este espacio de color. Luego debe definir una métrica en este espacio de color para encontrar la distancia entre dos colores.

Por ejemplo, la distancia en un espacio euclidiano entre dos puntos x = (x1, x2, x3) e y = (y1, y2, y3) viene dada por d (x, y) = sqrt ((y1-x1) * (y1- x1) + (y2-x2) * (y2-x2) + (y3-x3) * (y3-x3)).

Ahora puede calcular la distancia entre el color de las bolas y el color de fondo y, si es demasiado pequeño, cree un nuevo color aleatorio y pruebe nuevamente.

Encontrará que ni RGB ni HSV son buenos espacios de color para esta tarea. El artículo de Wikipedia sobre la diferencia de color emplea el espacio de color L a b y ofrece varias métricas posibles.

También hay un diskussion en stackoverflow sobre el tema.

René
fuente
Ese es un enfoque muy agradable, podría hacerlo :) ¡Gracias! Además, ¿le gustaría elaborar un poco sobre cómo encontrar un umbral de "distancia mínima" adecuado? Si RGB no es adecuado, ¿cómo convertir a L a b? No me esfuerzo por obtener métricas de percepción precisas, por lo que cualquier valor predeterminado "suficientemente bueno" servirá.
MestreLion
1
Me encanta esta respuesta, bien pensada, buena explicación de cómo hacer la tarea al tiempo que proporciona las ecuaciones y referencias necesarias. Buena primera respuesta.
Tom 'Blue' Piddock
1
Si está buscando una aproximación "suficientemente buena" de la percepción humana, es posible que desee examinar el espacio de color YUV , que tiene una conversión directa de RGB.
Trm
55
Ahorre un poco de tiempo y no saque la raíz cuadrada (costosa). Simplemente haga su valor mínimo de distancia de color que compare con el cuadrado.
Chris Cudmore
1
@MestreLion El espacio de color L a b * se inventó para ser perceptualmente uniforme, lo que significa que la distancia percibida entre dos colores es la misma que la distancia real en el espacio de color. Dado que los colores RGB dependen del dispositivo, no puede convertir directamente entre Lab y RGB. Sin embargo, si usa un espacio de color RGB absoluto específico, puede convertirlos. Vea este artículo: en.wikipedia.org/wiki/SRGB_color_space y este artículo: en.wikipedia.org/wiki/Lab_color_space
jwir3
8

La página de estándares de accesibilidad web de las Naciones Unidas ( http://www.un.org/webaccessibility/1_visual/13_colourcontrast.shtml ) indica un estándar para garantizar un contraste de texto adecuado en los sitios web, teniendo en cuenta que algunos usuarios son daltónicos. Esto puede ser particularmente importante para usted, ya que algunos de sus usuarios también pueden ser daltónicos (sería difícil distinguir una bola roja de un fondo verde si tienen la misma luminosidad).

La página de la ONU apunta al Analizador de relación de contraste de color de luminosidad de Juicy Studios en ( http://juicystudio.com/services/luminositycontrastratio.php#specify ) que establece que el texto en el fondo debe tener una relación de contraste de 4.5: 1, excepto por lo que I cree que es similar a su caso:

  • Texto grande: el texto a gran escala y las imágenes de texto a gran escala tienen una relación de contraste de al menos 3: 1

Ahora, ¿qué es una relación de contraste? Siguiendo los hipervínculos (¡esto es divertido!) Llegamos a una página W3 que define la relación de contraste como:

Contrast Ratio = (L1 + 0.05)/(L2 + 0.05)

Donde L1 y L2 son las luminosidades relativas de los colores. L1 es el color más luminoso, L2 es el color menos luminoso. Nuevamente, seguimos el enlace a la misma página W3 que especifica:

L = 0.2126 * R + 0.7152 * G + 0.0722 * B where R, G and B are defined as:

if RsRGB <= 0.03928 then R = RsRGB/12.92 else R = ((RsRGB+0.055)/1.055) ^ 2.4
if GsRGB <= 0.03928 then G = GsRGB/12.92 else G = ((GsRGB+0.055)/1.055) ^ 2.4
if BsRGB <= 0.03928 then B = BsRGB/12.92 else B = ((BsRGB+0.055)/1.055) ^ 2.4
and RsRGB, GsRGB, and BsRGB are defined as:

RsRGB = R8bit/255
GsRGB = G8bit/255
BsRGB = B8bit/255

NOTA : El símbolo de intercalación ^ anterior se refiere a exponenciación (x²)

Y tenemos un marco bastante bueno para un algoritmo de contraste (¡eso es compatible con daltonismo!)

  • Determine los valores R, G, B para cada color.
  • Determinar la luminancia para cada color.
  • Si la relación de contraste del color más luminosa al color menos luminosa es menor que 3, vuelva a girar.
John
fuente
2
Puede querer notar que ^ se supone que es exponenciación. Para nosotros, usuarios locos como C, significa xor (realmente pensé que estabas tratando de hacer una operación bit a bit en valores de coma flotante durante un minuto).
Pharap
Ese es un enfoque increíble , ¡me gusta! :)
MestreLion
Y no se preocupe ^, nunca pensaría en un XOR bit a bit en este contexto. (o en cualquier caso. Vamos C phreaks, ^es el símbolo de facto para la exponenciación en pseudocódigos (aunque muy pocos lenguajes realmente lo usan ... en Python **))
MestreLion
1
Solo arreglando errores tipográficos. Además, si una persona tiene problemas con el ^, es probable que otra persona en el futuro también pueda tenerlo. No hace daño ser específico.
John
1
@John No te preocupes,. No estoy seguro de dónde proviene la confusión (es decir, qué idioma usó ^ para qué propósito primero). Solo sé que ^ a veces se usa para exponenciación debido a mi experiencia con VB (no conozco ningún otro idioma que lo use como exponenciación, pero probablemente haya algunos). Sin embargo, solo como un aviso, es el símbolo de caret , no el símbolo de zanahoria . Es posible que desee cambiarlo antes de que alguien haga un chiste horrible sobre la programación con vegetales (particularmente uno que involucre raíces cuadradas).
Pharap
2

El uso de valores RGB generando un 0-255valor aleatorio para cada componente podría no solo crear colores similares al fondo, sino que también puede terminar con colores muy similares para las bolas.

Probablemente elegiría un enfoque menos aleatorio y crearía colores que están garantizados para ser diferentes. Puede crear un color para cada ~ 32 grados en el rango de tono y alternar el brillo o la saturación (use el modelo de color HSV en lugar de RGB).

Entonces algo como esto:

numColors = 20;
stepSize = 360 / (numColors / 2 + 1); // hue step size
for(i = 0; i < numColors; i++){
    color = HSV(i / 2 * stepSize, 0.5 + (i % 2) * 0.5, 1.0) 
}

que creará 20 colores, muy bien distribuidos. Esto supone que está utilizando álgebra de números enteros, por lo que i = 0y i = 1va a crear el mismo valor de tono.

Por supuesto, esto no escala demasiado bien ... si tiene 100 valores de color para crear, el espaciado de tono puede no ser suficiente y terminará con colores similares nuevamente. En ese caso, también puede variar el Vvalor (brillo).

No sé cómo es su color de fondo, pero HSV también facilita la comparación de colores (solo compare los 3 componentes y no olvide que HUE es circular (0 == 360)).

ACTUALIZAR:

Como realmente no respondí su pregunta, sino que proporcioné otro enfoque, así es como podría verse un algoritmo para un fondo arbitrario y bolas de colores completamente al azar (este es un enfoque de fuerza bruta, pero debería funcionar bien para su caso de uso):

// background color, currently equals RGB(0, 0, 255)
bg = HSV(240, 1.0, 1.0)

// number of colors to create is equal to the amount of balls
numColors = balls.length

// set threshold to compare colors. you can tweak this to your liking
threshold = 0.15

for(i = 0; i < numColors; i++){
    do {
        // assuming rnd returns a random float 0-1 inclusive
        color = HSV(rnd() * 360, rnd(), rnd())
        // calculate delta values, normalize hue to 0-1
        dH = (180 - abs(abs(bg.h - color.h) - 180)) / 360
        dS = bg.s - color.s
        dV = bg.v - color.v
        // "distance" between bg and color
        difference = sqrt(dH * dH + dS * dS + dV * dV)
    } while(difference < threshold)

    ball[i].color = color
}
bummzack
fuente
Sobre su algoritmo, ¿cómo está teniendo en cuenta el color de fondo?
MestreLion
Actualmente no está teniendo en cuenta el color de fondo ... podría ajustarlo comparando los colores generados (como se describe en el último párrafo) y luego crear un color diferente V(ya que el algoritmo actual no altera eso).
bummzack
@MestreLion agregó una actualización con un algoritmo alternativo
bummzack
Genial, esa parece una buena estrategia. La fuerza bruta está bien, los colores solo se generan una vez en la inicialización, no dentro del ciclo del juego. Parece que está utilizando el mismo enfoque que el de René, con una distancia euclidiana simple en HSV, ¿correcto? ¿Alguna referencia de un umbral adecuado para HSV? ¿H, S y V pesan lo mismo en distancia como en RGB?
MestreLion
@MestreLion Sí, mi segundo algoritmo es más o menos lo que René explicó en su respuesta. Lamentablemente, no hay un valor definitivo para un buen umbral ya que los cambios de color no se perciben de manera uniforme. Reconocemos los cambios en el verde mucho más rápido que en el azul ... por lo tanto, para los tonos verdes, un umbral más pequeño podría funcionar, pero no será suficiente para otros colores, etc. Hasta donde sé, el espacio de color Lab está cerca de la percepción del color humano y podría ser más adecuado si no obtiene resultados deseables con el espacio de color HSV.
bummzack
1

Dado que no mencionó que tiene un fondo estacionario, el color de las bolas aún puede ser aleatorio, pero tienen que caer en ciertos rangos que aún complementan el fondo.

Lo esencial. Antes de hacerlo, debe conocer los conceptos básicos. Considere los siguientes colores:

Black   #000000 rgb(0,0,0)
Red     #FF0000 rgb(255,0,0)
Green   #00FF00 rgb(0,255,0)
Blue    #0000FF rgb(0,0,255)
Yellow  #FFFF00 rgb(255,255,0)
Cyan    #00FFFF rgb(0,255,255)
Pink    #FF00FF rgb(255,0,255)
Gray    #C0C0C0 rgb(192,192,192)
White   #FFFFFF rgb(255,255,255)

Mezcla de colores RGB [(0..255), (0..255), (0..255)] crea nuevos colores como el anterior.

Calcular para colores negativos Calcular para colores negativos es como transformar rojo en cian, verde en morado, azul en amarillo.

Red     #FF0000 rgb(255,0,0) ->     Cyan    #00FFFF rgb(0,255,255)
Green   #00FF00 rgb(0,255,0) ->     Purple   #FF00FF    rgb(255,0,255)
Blue    #0000FF rgb(0,0,255) ->     Yellow  #FFFF00 rgb(255,255,0)

Color complementario

Según la referencia en Computación de colores complementarios: http://serennu.com/colour/rgbtohsl.php

Sobre HSL

HSL expresa los colores en términos de su tono, saturación y luminosidad, dando un número para cada uno de estos tres atributos del color.

El tono es la posición del color en la rueda de color, expresada en grados de 0 ° a 359 °, que representa los 360 ° de la rueda; 0 ° es rojo, 180 ° es el color opuesto al rojo cian, y así sucesivamente.

La saturación es la intensidad del color, lo opaco o brillante que es. Cuanto más baja es la saturación, más opaco (gris) se ve el color. Esto se expresa como un porcentaje, el 100% es saturación total, la más brillante, y el 0% es saturación, gris.

La ligereza es la luz del color. Ligeramente diferente a la saturación. Cuanto más blanco sea el color, mayor será su valor de Luminosidad, cuanto más negro, menor será su Luminosidad. Entonces, el 100% de luminosidad convierte el color en blanco, el 0% de luminosidad convierte el color en negro y el color "puro" sería el 50% de luminosidad.

Es más fácil ver la diferencia entre Saturación y Luminosidad que explicarla. Si desea aclarar, intente ver las variaciones de Luminosidad y Saturación en la página de la calculadora de color, eligiendo un color bastante brillante como color inicial.

Entonces la notación HSL se ve así, dando los valores de Tono, Saturación y Luminosidad en ese orden: t

Rojo: 0 ° 100% 50% Rosa pálido: 0 ° 100% 90% Cian: 180 ° 100% 50% Estos son los pasos:

  1. Convierte tu color a HSL.

  2. Cambie el valor de Hue al valor del Hue opuesto (por ejemplo, si su Hue es de 50 °, el opuesto estará a 230 ° en la rueda - 180 ° más alrededor).

  3. Deje los valores de Saturación y Luminosidad como estaban.

  4. Convierta este nuevo valor HSL nuevamente a su notación de color original (RGB o lo que sea).

Sitios como EasyRGB.com pueden realizar conversiones genéricas de RGB a HSL o viceversa.

Ejemplo de programación realizado en PHP según referencia

Conversión de RGB a HSL

El valor por encima de Azul # 0000FF rgb (0,0,255) se puede presentar como Rojo Hexadecimal 00 + Verde Hexadecimal 00 + Azul Hexadecimal FF

$redhex  = substr($hexcode,0,2);
$greenhex = substr($hexcode,2,2);
$bluehex = substr($hexcode,4,2);

También se puede presentar como Rojo Decimal 0 + Verde Decimal 0 + Azul Decimal 255

$var_r = (hexdec($redhex)) / 255;
$var_g = (hexdec($greenhex)) / 255;
$var_b = (hexdec($bluehex)) / 255;

Ahora conecte estos valores a la rutina rgb2hsl. A continuación se muestra mi versión PHP del código genérico de EasyRGB.com para esa conversión:

La entrada es $ var_r, $ var_g y $ var_b desde arriba La salida es equivalente a HSL como $ h, $ sy $ l - estos se expresan nuevamente como fracciones de 1, como los valores de entrada

$var_min = min($var_r,$var_g,$var_b);ttt
$var_max = max($var_r,$var_g,$var_b);
$del_max = $var_max - $var_min;

$l = ($var_max + $var_min) / 2;

if ($del_max == 0)
{
        $h = 0;
        $s = 0;
}
else
{
        if ($l < 0.5)
        {
                $s = $del_max / ($var_max + $var_min);
        }
        else
        {
                $s = $del_max / (2 - $var_max - $var_min);
        };

        $del_r = ((($var_max - $var_r) / 6) + ($del_max / 2)) / $del_max;
        $del_g = ((($var_max - $var_g) / 6) + ($del_max / 2)) / $del_max;
        $del_b = ((($var_max - $var_b) / 6) + ($del_max / 2)) / $del_max;

        if ($var_r == $var_max)
        {
                $h = $del_b - $del_g;
        }
        elseif ($var_g == $var_max)
        {
                $h = (1 / 3) + $del_r - $del_b;
        }
        elseif ($var_b == $var_max)
        {
                $h = (2 / 3) + $del_g - $del_r;
        };

        if ($h < 0)
        {
                $h += 1;
        };

        if ($h > 1)
        {
                $h -= 1;
        };
};

Entonces ahora tenemos el color como un valor HSL, en las variables $ h, $ sy $ l. Estas tres variables de salida se mantienen nuevamente como fracciones de 1 en esta etapa, en lugar de como grados y porcentajes. Entonces, por ejemplo, el cian (180 ° 100% 50%) saldría como $ h = 0.5, $ s = 1 y $ l = 0.5.

Luego, encuentre el valor del Hue opuesto, es decir, el que está a 180 °, o 0.5, de distancia (estoy seguro de que los matemáticos tienen una forma más elegante de adorar esto, pero):

Calcule el tono opuesto, $ h2

            $h2 = $h + 0.5;

            if ($h2 > 1)
                    {
                            $h2 -= 1;
                    };

El valor HSL del color complementario ahora está en $ h2, $ s, $ l. Así que estamos listos para convertir esto nuevamente a RGB (nuevamente, mi versión PHP de la fórmula EasyRGB.com). Tenga en cuenta que los formatos de entrada y salida son diferentes esta vez, vea mis comentarios en la parte superior del código:

La entrada es el valor HSL del color complementario, se mantiene en $ h2, $ s, $ l como fracciones de 1 La salida es RGB en formato normal 255 255 255, se mantiene en $ r, $ g, $ b El tono se convierte con la función hue_2_rgb, se muestra al final de este código

    if ($s == 0)
    {
            $r = $l * 255;
            $g = $l * 255;
            $b = $l * 255;
    }
    else
    {
            if ($l < 0.5)
            {
                    $var_2 = $l * (1 + $s);
            }
            elset
            {
                    $var_2 = ($l + $s) - ($s * $l);
            };

            $var_1 = 2 * $l - $var_2;
            $r = 255 * hue_2_rgb($var_1,$var_2,$h2 + (1 / 3));
            $g = 255 * hue_2_rgb($var_1,$var_2,$h2);
            $b = 255 * hue_2_rgb($var_1,$var_2,$h2 - (1 / 3));
    };

   // Function to convert hue to RGB, called from above

    function hue_2_rgb($v1,$v2,$vh)
    {
            if ($vh < 0)
            {
                    $vh += 1;
            };

            if ($vh > 1)
            {
                    $vh -= 1;
            };

            if ((6 * $vh) < 1)
            {
                    return ($v1 + ($v2 - $v1) * 6 * $vh);
            };

            if ((2 * $vh) < 1)
            {
                    return ($v2);
            };

            if ((3 * $vh) < 2)
            {
                    return ($v1 + ($v2 - $v1) * ((2 / 3 - $vh) * 6));
            };

            return ($v1);
    };

Y después de esa rutina, finalmente tenemos $ r, $ gy $ b en formato 255 255 255 (RGB), que podemos convertir a seis dígitos de hexadecimal:

    $rhex = sprintf("%02X",round($r));
    $ghex = sprintf("%02X",round($g));
    $bhex = sprintf("%02X",round($b));

    $rgbhex = $rhex.$ghex.$bhex;

$ rgbhex es nuestra respuesta: el color complementario en hexadecimal.

Como su fondo de color es azul o 0,0,255, el HSL es

Tono (H): 240 grados / Saturación (S): 100% / Luminosidad (L): 4.9%

el opuesto de 240 es 60 en un círculo, luego convertir de nuevo a RGB da un valor de # 181800

Ace Caserya
fuente
¡Gracias! Pero el enlace habla de generar un "color complementario" (lo que sea que sea) de sí mismo . Todavía no tengo idea de cómo usar eso para resolver mi problema: asegúrese de que cada color aleatorio no sea similar al color de fondo. El color de fondo es constante, de un solo color, y hay varias bolas.
MestreLion
Gracias Krom haciendo eso ahora. @MestreLion, dado que el fondo es constante, puede especificar un rango para sus bolas que aún complemente el fondo.
Ace Caserya
Actualmente exponiendo mi respuesta.
Ace Caserya
Hecho. No sé qué cambiar mucho en la explicación de los sitios porque se explica lo suficientemente bien. Créditos a los muchachos en EasyRGB.com
Ace Caserya
Continuemos esta discusión en el chat .
Ace Caserya
1

Me gustaría ampliar la idea de @ ashes999 de crear un esquema.

Mi código va a ser lo más parecido a Python que pueda en la parte superior de mi cabeza (nunca he escrito una línea de Python en mi vida, pero he echado un vistazo a un libro una o dos veces).

def lerp(a,b,value): # assuming your library was not kind enough to give you this for free
    return a + ((b - a) * value);

def drawRandomBall(bgColour,radius,point):
    var ballColour = Colour(random(0,255),random(0,255),random(0,255);
    var outlineColour = Colour(lerp(bgColour.R,255 - ballColour.R,0.5),lerp(bgColour.G,255 - ballColour.G,0.5),lerp(bgColour.B,255 - ballColour.B,0.5));
    fillCircle(point,radius+1,outlineColour);
    fillCircle(point,radius,ballColour);

Puede que no se vea particularmente bonito y no es realmente ideal para el código de producción, pero debería ser una solución rápida. No he probado el código, ya que no tengo exactamente un programa de "bolas rebotando alrededor de la pantalla" que pueda mutilar para probarlo.


Editar:

Al ver el código real en uso, la situación cambió de opinión, por lo que ofrezco esta solución.

Reemplace las líneas 276-284 con lo siguiente:

# Colour generator
def generateColourNonBG(leeway):
    color = (randint(0,255), randint(0,255), randint(0,255))
    while color[0] >= BG_COLOR[0]-leeway and color[0] =< BG_COLOR[0] + leeway and
    color[1] >= BG_COLOR[1]-leeway and color[1] =< BG_COLOR[1] + leeway and
    color[2] >= BG_COLOR[2]-leeway and color[2] =< BG_COLOR[2] + leeway:
        color = (randint(0,255), randint(0,255), randint(0,255))

# Ball generator
def generateBall():
    Ball(generateColourNonBG(5),
                   radius=randint(10, radius),
                   position=[randint(100, screen.get_size()[0]-radius),
                             randint(100, screen.get_size()[0]-radius)],
                   velocity=[randint(50, 50+vel[0]), randint(50, 50+vel[1])],
                   )                       

# Create the balls
balls = pygame.sprite.Group()
for _ in xrange(BALLS):
    balls.add(generateBall())

En esta nueva versión simplificada, un método de fábrica escupe las bolas y un método especializado genera los colores. El generador de color prueba el color generado aleatoriamente para ver si está dentro de un cierto rango de cercanía al color de fondo. Un color se considera demasiado cercano al color BG si sus tres canales de color están dentro de leewaycada lado de BG. Entonces, si el margen de maniobra es 0, solo se rechazarán los colores que coincidan exactamente con BG. Elegí 5 como predeterminado, que rechaza el color BG y los 5 colores a cada lado. Como el color BG es blanco, no estoy seguro de si rechazará el negro porque los dígitos se envuelven. Eso se puede evitar con el uso de las funciones min y max, pero las dejé por razones de brevedad.

Pharap
fuente
Estoy abierto a cualquier estrategia :) en cuanto a un programa para mutilar, puedo darte eso: github.com/MestreLion/rainballs las líneas relevantes serían 279-284
MestreLion
Estoy usando pygamecomo biblioteca. Sin Lerp, solo conversiones básicas RGB-HSV-CYMK: pygame.org/docs/ref/color.html
MestreLion
@MestreLion Oh, señor, ahora tengo que instalar pygame y python para probarlo. Me pegué un tiro en el pie con este XP. Lerping es fácil, la lerpfunción en mi respuesta es todo lo que hay que hacer. (Lerp significa 'interpolación lineal').
Pharap
@MestreLion Jugueteo un poco, resulta que mi versión de python no le gusta que se llame a print sin paréntesis. Solucioné eso, pero ahora tengo errores de pygame al no poder encontrar las bibliotecas correctas. Reescribiré mi código para que se ajuste a lo que tienes, pero no puedo probarlo hasta que arregle pygame. Recomendaría agregar ese archivo a la pregunta si aún no lo ha hecho (en caso de que alguien se sienta lo suficientemente amable como para escribir algo de Python para usted).
Pharap
Eres printdiferente porque estás usando Python 3, y todavía estoy en Python 2. Y aún no estoy seguro de si pygamefue portado a Py3. En pocas palabras: no te molestes :) La pregunta es sobre colores, no necesitas bolas reales rebotando :)
MestreLion
1

Para un formato RGB, esto parece funcionar lo suficientemente bien y es trivial:

diversity_score = (abs (r1 - r2) + abs (g1 - g2) + abs (b1 - b2)) / 765.0

Esto le dará un puntaje entre 0.0 y 1.0. Cuanto más bajo, más difícil es distinguir dos colores.

Debería ser obvio, pero en aras de la exhaustividad: los valores r, g, b deben convertirse primero en un número de coma flotante, y se supone que su valor máximo es 255.

AB
fuente