Algoritmo para modificar uma cor para torná-la menos semelhante ao plano de fundo

23

Estou criando uma demonstração de 20 bolas quicando umas nas outras, com um fundo preenchido com uma cor sólida. A cor de cada bola é escolhida aleatoriamente com randint(0, 255)cada componente de tupla R, G, B.

O problema é que algumas bolas acabam com uma cor muito semelhante ao fundo, dificultando a visualização. Gostaria de evitar isso, rolando outra cor se a escolhida for muito semelhante (dentro de um determinado limite) ou afastando-a da cor de fundo.

Como calcular um índice de similaridade para usar como limite? Ou como transformar uma cor para torná-la, digamos, menos azulada ?

Isenção de responsabilidade óbvia: não sei nada sobre teoria das cores, portanto não sei se os conceitos acima existem!

Estou codificando em python, mas estou procurando conceitos e estratégias, então o pseudo-código é bom (ou apenas a teoria).

EDITAR:

Para esclarecer alguns pontos:

  • Cada bola tem sua própria cor aleatória. Gostaria que eles permanecessem o mais aleatórios possível e que explorassem o máximo possível do espaço de cores (seja RGB ou HSV, pygameaceita os dois formatos para definir cores)

  • Eu gostaria de evitar que cada cor fique "muito perto" do plano de fundo. O problema não é apenas a tonalidade: eu estou perfeitamente bem com uma bola azul claro contra um fundo azul escuro (ou um "azul completo" contra um azul "branco-ish", etc)

  • Por enquanto, não me importo se uma bola acaba com uma cor semelhante (ou mesmo idêntica) a outra bola. Evitar isso é um bônus, mas é uma questão menor.

  • A cor de fundo é uma constante, única cor RGB. Por enquanto estou usando o azul "básico" (0, 0, 255), mas não estou de acordo com isso. Portanto, considere o plano de fundo de uma cor arbitrária (com matiz arbitrário, brilho, saturação etc.).

EDIT2:

Versão TL, DR: Apenas crie uma forma aleatória de cores X para que nenhuma "desbote muito" em um fundo de cores arbitrárias (mas únicas e constantes)

MestreLion
fonte
1
Por que não colocar um contorno em torno de cada bola?
precisa saber é o seguinte
1
Então pode haver um problema com fazer uma cor de contorno distinto de ambos fundo e bolas de cor;)
Kromster diz apoio Monica
1
@AlexM .: difícil acreditar que não há nenhuma solução fácil para "gerar cores aleatórias evitando arbitrária"
MestreLion
1
O @MestreLion apenas usa preto para o contorno e gera cores com um valor mínimo de RGB de 128. É fácil assim.
precisa saber é o seguinte

Respostas:

33

Você pode usar o fato de que as cores compõem um espaço de cores (tridimensional) e calculam uma distância nesse espaço de cores. Você precisa definir uma métrica nesse espaço de cores para encontrar a distância entre duas cores.

Por exemplo, a distância em um espaço euclidiano entre dois pontos x = (x1, x2, x3) e y = (y1, y2, y3) é dada por d (x, y) = sqrt ((y1-x1) * (y1- x1) + (y2-x2) * (y2-x2) + (y3-x3) * (y3-x3)).

Agora você pode calcular a distância entre a cor de uma bola e a cor de fundo e, se ela for muito pequena, crie uma nova cor aleatória e teste novamente.

Você descobrirá que nem RGB nem HSV são bons espaços de cores para esta tarefa. O artigo da Wikipedia sobre diferença de cores emprega o espaço de cores L a b e fornece várias métricas possíveis.

Há também uma discussão sobre o stackoverflow no tópico.

René
fonte
Essa é uma abordagem muito legal, eu poderia fazer isso :) Obrigado! Além disso, lembre-se de elaborar um pouco sobre como encontrar um limite adequado de "distância mínima"? Se o RGB não for adequado, como converter para L a b? Não estou me esforçando para obter métricas de percepção precisas, portanto qualquer padrão "bom o suficiente" será suficiente.
MestreLion 7/08/14
1
Adore esta resposta, bem pensada, uma boa explicação de como executar a tarefa, fornecendo as equações e referências necessárias. Boa primeira resposta.
Tom 'Blue' Piddock
1
Se você está procurando uma aproximação "boa o suficiente" da percepção humana, convém observar o espaço de cores YUV , que possui uma conversão direta de RGB.
TRM
5
Economize um pouco de tempo e não use a raiz quadrada (cara). Basta fazer o valor mínimo da distância da cor que você comparar com o quadrado.
22630 Chris Cudmore
1
@MestreLion O espaço de cor L a b * foi inventado para ser perceptualmente uniforme, o que significa que a distância percebida entre duas cores é a mesma que a distância real no espaço de cores. Como as cores RGB dependem do dispositivo, você não pode converter diretamente entre Lab e RGB. No entanto, se você usar um espaço de cores RGB absoluto específico, poderá convertê-los. Veja este artigo: en.wikipedia.org/wiki/SRGB_color_space e este artigo: en.wikipedia.org/wiki/Lab_color_space
jwir3
8

A página das normas de acessibilidade da Web das Nações Unidas ( http://www.un.org/webaccessibility/1_visual/13_colourcontrast.shtml ) indica um padrão para garantir a devida contraste de texto nos sites, lembrando que alguns usuários são daltônicos. Isso pode ser particularmente importante para você, já que alguns de seus usuários também podem ser daltônicos (seria difícil distinguir uma bola vermelha de fundo verde se tiverem a mesma luminância).

A página da ONU aponta para o analisador de taxa de contraste de cores de luminosidade do Juicy Studios em ( http://juicystudio.com/services/luminositycontrastratio.php#specify ), que afirma que o texto em segundo plano deve ter uma taxa de contraste de 4,5: 1, exceto pelo que acredite ser semelhante ao seu caso:

  • Texto grande: texto e imagens em grande escala têm uma taxa de contraste de pelo menos 3: 1

Agora, o que é uma taxa de contraste? Seguindo os hiperlinks (isso é divertido!), Chegamos a uma página W3 que define a taxa de contraste como:

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

Onde L1 e L2 são as luminências relativas das cores. L1 é a cor mais luminosa, L2 é a cor menos luminosa. Novamente, seguimos o link para a mesma 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 : O símbolo de sinal de intercalação ^ acima refere-se à exponenciação (x²)

E nós temos uma estrutura muito boa para um algoritmo de contraste (que é daltônico!)

  • Determinar valores R, G, B para cada cor
  • Determinar luminância para cada cor
  • Se a taxa de contraste entre a cor mais luminosa e a menos luminosa for menor que 3, rolar novamente!
John
fonte
2
Pode-se notar que ^ deve ser exponenciação. Para nós, usuários loucos do tipo C, significa xor (eu realmente pensei que você estava tentando fazer uma operação bit a bit em valores de ponto flutuante por um minuto).
Pharap
Essa é uma abordagem incrível , eu gosto! :)
MestreLion 8/08/14
E não se preocupe ^, eu nunca pensaria em um XOR pouco a pouco nesse contexto. . (ou em quaisquer phreaks realmente C'mon C, ^é o simbol de facto para exponenciação em pseudo-códigos (embora muito poucas línguas realmente usá-lo ... em python é **)
MestreLion
1
Apenas corrigindo erros de digitação. Além disso, se uma pessoa tiver problemas com o ^, é provável que outras pessoas no futuro também possam. Não faz mal ser específico.
John
1
@ John Não se preocupe,. Não sei de onde vem a confusão (ou seja, qual idioma usou ^ para qual finalidade primeiro). Eu só sei que ^ às vezes é usado para exponenciação por causa de minha experiência com VB (não conheço outros idiomas que o usem como exponenciação, mas provavelmente existem alguns). Assim como um alerta, é o símbolo de sinal de intercalação , não o símbolo da cenoura . Pode querer mudar isso antes que alguém faça uma piada horrível sobre a programação com vegetais (particularmente uma envolvendo raízes quadradas).
Pharap
2

O uso de valores RGB gerando um 0-255valor aleatório para cada componente pode não apenas criar cores semelhantes ao plano de fundo, mas também acabar com cores muito semelhantes para as bolas.

Eu provavelmente escolheria uma abordagem menos aleatória e criaria cores que, com certeza, serão diferentes. Você pode criar uma cor para cada ~ 32 graus na faixa de matiz e alternar o brilho ou a saturação (use o modelo de cores HSV em vez de RGB).

Então, algo como isto:

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 criará 20 cores, bem distribuídas. Isso pressupõe que você está usando matemática inteiro, por isso i = 0e i = 1vai criar o mesmo valor de tonalidade.

É claro que isso não é muito bom. Se você tiver 100 valores de cores para criar, o espaçamento de matiz poderá não ser suficiente e você terá cores semelhantes novamente. Nesse caso, você também pode variar o Vvalor (brilho).

Não sei como é a cor de fundo, mas o HSV também facilita a comparação de cores (basta comparar os 3 componentes e não se esqueça que o HUE é circular (0 == 360)).

ATUALIZAR:

Como eu realmente não respondi sua pergunta, mas forneci outra abordagem, eis como um algoritmo para um fundo arbitrário e bolas coloridas completamente aleatórias pode parecer (essa é uma abordagem de força bruta, mas deve funcionar bem para o seu 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
fonte
Sobre o seu algoritmo, como ele está levando em consideração a cor do plano de fundo?
MestreLion 7/08/14
No momento, ela não está levando em consideração a cor do plano de fundo ... você pode ajustá-la comparando as cores geradas (conforme descrito no último parágrafo) e depois criar uma cor com uma diferente V(porque o algoritmo atual não altera isso).
precisa saber é o seguinte
@MestreLion Adicionado uma atualização com um algoritmo alternativo
bummzack
Ótimo, isso parece uma boa estratégia. A força bruta está OK, as cores são geradas apenas uma vez na inicialização, não dentro do loop do jogo. Parece que você está usando a mesma abordagem que a de René, com distância euclidiana simples em HSV, correto? Alguma referência de um limite adequado para HSV? H, S e V pesam o mesmo em distância, como no RGB?
MestreLion
@MestreLion Sim, meu segundo algoritmo é basicamente o que René explicou em sua resposta. Infelizmente, não há valor definitivo para um bom limite, pois as alterações de cores não são percebidas uniformemente. Reconhecemos as alterações no verde muito mais rapidamente do que no azul ... portanto, para tons de verde, um limiar menor pode funcionar, mas não será suficiente para outras cores etc. pode ser mais adequado se você não obtiver resultados desejáveis ​​com o espaço de cores HSV.
bummzack
1

Como você mencionou que tem um fundo estacionário, a cor das bolas ainda pode ser aleatória, mas elas precisam cair em determinados intervalos que ainda complementam o fundo.

Noções básicas. Antes de fazermos isso, você precisa conhecer o básico. Considere as seguintes cores:

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)

Mistura de cores RGB [(0..255), (0..255), (0..255)] cria novas cores como acima.

Computação para cores negativas A computação para cores negativas é como transformar vermelho em ciano, verde em roxo, azul em amarelo.

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)

Cor Complementar

Conforme referência em Computação de cores complementares: http://serennu.com/colour/rgbtohsl.php

Sobre HSL

HSL expressa cores em termos de matiz, saturação e luminosidade, fornecendo um número para cada um desses três atributos da cor.

The Hue é a posição da cor na roda de cores, expressa em graus de 0 ° a 359 °, representando os 360 ° da roda; 0 ° sendo vermelho, 180 ° sendo o vermelho oposto à cor ciano e assim por diante.

A saturação é a intensidade da cor, quão opaca ou brilhante é. Quanto menor a saturação, mais opaca (mais cinza) a cor fica. Isso é expresso como uma porcentagem, sendo 100% de saturação total, o mais brilhante e 0% sem saturação, cinza.

Leveza é o quão clara é a cor. Um pouco diferente da saturação. Quanto mais branco na cor, maior o valor da luminosidade, mais preto, menor a luminosidade. Portanto, 100% de luminosidade torna a cor branca, 0% de luminosidade torna a cor preta e a cor "pura" seria 50% de luminosidade.

É mais fácil ver a diferença entre Saturação e Luminosidade do que explicá-la. Se você deseja esclarecer, tente visualizar as variações de Luminosidade e Saturação na página da calculadora de cores, escolhendo uma cor bastante brilhante como sua cor inicial.

Portanto, a notação HSL se parece com isso, fornecendo os valores Matiz, Saturação e Luminosidade nessa ordem: t

Vermelho: 0 ° 100% 50% Rosa pálido: 0 ° 100% 90% Ciano: 180 ° 100% 50% Aqui estão as etapas:

  1. Converta sua cor para HSL.

  2. Altere o valor da Matiz para o oposto da Matiz (por exemplo, se o seu Matiz for 50 °, o oposto estará em 230 ° na roda - 180 ° mais à frente).

  3. Deixe os valores de Saturação e Luminosidade como estavam.

  4. Converta esse novo valor HSL de volta à sua notação de cores original (RGB ou qualquer outra coisa).

Sites como EasyRGB.com podem fazer uma conversão genérica para você de RGB para HSL ou vice-versa.

Exemplo de programação feito em PHP conforme referência

Conversão RGB para HSL

O valor acima do azul # 0000FF rgb (0,0,255) pode ser apresentado como vermelho hexadecimal 00 + verde hexadecimal 00 + azul hexadecimal FF

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

Também pode ser apresentado como Vermelho Decimal 0 + Verde Decimal 0 + Azul Decimal 255

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

Agora, conecte esses valores à rotina rgb2hsl. Abaixo está minha versão PHP do código genérico do EasyRGB.com para essa conversão:

A entrada é $ var_r, $ var_g e $ var_b acima A saída é equivalente a HSL como $ h, $ se $ l - eles são novamente expressos como frações de 1, como os 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;
        };
};

Então agora temos a cor como um valor HSL, nas variáveis ​​$ h, $ se $ l. Essas três variáveis ​​de saída são novamente mantidas como frações de 1 neste estágio, e não como graus e porcentagens. Assim, por exemplo, ciano (180 ° 100% 50%) sairia como $ h = 0,5, $ s = 1 e $ l = 0,5.

Em seguida, encontre o valor do matiz oposto, ou seja, aquele que está a 180 ° ou 0,5, de distância (tenho certeza que os matemáticos têm uma maneira mais elegante de mostrar isso, mas):

Calcular a matiz oposta, $ h2

            $h2 = $h + 0.5;

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

O valor HSL da cor complementar está agora em $ h2, $ s, $ l. Então, estamos prontos para convertê-lo novamente em RGB (novamente, minha versão PHP da fórmula EasyRGB.com). Observe que os formatos de entrada e saída são diferentes desta vez, veja meus comentários na parte superior do código:

A entrada é o valor HSL da cor complementar, mantida em $ h2, $ s, $ l como frações de 1 A saída é RGB no formato normal 255 255 255, mantida em $ r, $ g, $ b A matiz é convertida usando a função hue_2_rgb, mostrada no final deste 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);
    };

E depois dessa rotina, finalmente temos $ r, $ ge $ b no formato 255 255 255 (RGB), que podemos converter em seis dígitos hexadecimais:

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

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

$ rgbhex é a nossa resposta - a cor complementar em hexadecimal.

Como o fundo colorido é azul ou 0,0.255, o HSL é

Matiz (H): 240 graus / Saturação (S): 100% / Luminosidade (L): 4,9%

oposto de 240 é 60 em um círculo, em seguida, converter de volta para RGB dá um valor de # 181800

Ace Caserya
fonte
Obrigado! Mas o link fala sobre gerar uma "cor complementar" (seja lá o que for) de si mesma . Ainda não sei como usar isso para resolver meu problema: verifique se cada cor aleatória não é semelhante à cor de fundo. A cor do plano de fundo é constante, de cor única e há várias bolas.
MestreLion 7/08/14
Obrigado Krom por fazer isso agora. @MestreLion, como o plano de fundo é constante, você pode especificar um intervalo para suas bolas que ainda complementa o plano de fundo.
Ace Caserya
Atualmente expondo minha resposta.
Ace Caserya
Feito. Não sei o que mudar muito na explicação dos sites, porque ela é explicada suficientemente bem. Créditos para os caras do EasyRGB.com
Ace Caserya
Vamos continuar esta discussão no chat .
Ace Caserya
1

Gostaria de expandir a idéia de @ ashes999 de criar um esboço.

Meu código será o mais parecido com um python do que eu consigo (nunca escrevi uma linha de python na minha vida, mas olhei sobre um livro uma ou duas vezes).

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);

Pode não parecer particularmente bonito e não é realmente ideal para código de produção, mas deve ser suficiente como uma solução rápida. Não testei o código, pois não tenho exatamente o programa "bolas saltando pela tela" que posso mutilar para testá-lo.


Editar:

Ao ver o código real em uso, a situação virou de cabeça para baixo, então, em vez disso, ofereço esta solução.

Substitua as linhas 276-284 pelo seguinte:

# 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())

Nesta nova versão simplificada, um método de fábrica cospe as bolas e um método especializado gera as cores. O gerador de cores testa a cor gerada aleatoriamente para verificar se ela está dentro de um certo intervalo de proximidade da cor de fundo. Uma cor é considerada muito próxima da cor BG se todos os três canais de cores estiverem dentro de leewaycada lado da BG. Portanto, se a margem de manobra for 0, apenas as cores que correspondem exatamente ao BG serão recusadas. Eu escolhi 5 como padrão, que recusa a cor BG e as 5 cores em ambos os lados. Como a cor BG é branca, não tenho certeza se recusará o preto porque os dígitos são redondos. Isso pode ser evitado com o uso das funções min e max, mas eu as deixei de fora por uma questão de brevidade.

Pharap
fonte
Estou aberto a qualquer estratégia :) como para um programa de mutilar, posso dar-lhe que: github.com/MestreLion/rainballs linhas relevantes seria 279-284
MestreLion
Estou usando pygamecomo uma biblioteca. Não Lerp, apenas conversões básicas de RGB-HSV-CYMK: pygame.org/docs/ref/color.html
MestreLion
@MestreLion Oh senhor, agora eu tenho que instalar pygame e python para testá-lo. Eu me atirei no pé com este XP. Lerping é fácil, a lerpfunção na minha resposta é tudo o que existe. (Lerp significa 'interpolação linear').
Pharap
@MestreLion Brincando um pouco, acontece que minha versão do python não gosta de impressão sendo chamada sem parênteses. Corrigido isso, mas agora eu tenho erros do pygame que não conseguem encontrar as bibliotecas corretas. Vou reescrever meu código para se encaixar no que você tem, mas não posso testá-lo até corrigir o pygame. Eu recomendo anexar esse arquivo à pergunta se você ainda não o fez (caso alguém esteja se sentindo bem o suficiente para escrever algum python para você).
precisa saber é o seguinte
Você printé diferente porque está usando o Python 3 e eu ainda estou no Python 2. E ainda não tenho certeza se pygamefoi portado para o Py3. Bottomline: não se preocupe :) A pergunta é sobre cores, você não precisa de bolas reais pulando :)
MestreLion
1

Para um formato RGB, isso parece funcionar bem o suficiente e é trivial:

diversity_score = (abs (r1 - r2) + abs (g1 - g2) + abs (b1 - b2)) / 765,0

Isso lhe dará uma pontuação entre 0,0 e 1,0. Quanto menor, mais difícil é distinguir duas cores.

Deve ser óbvio, mas por uma questão de completude: os valores de r, g, b devem ser convertidos primeiro em um número de ponto flutuante e supõe-se que seu valor máximo seja 255.

AB
fonte