Qual é a melhor maneira de média duas cores que definem um gradiente linear?

StackOverflow https://stackoverflow.com/questions/649454

  •  19-08-2019
  •  | 
  •  

Pergunta

Se eu tiver duas cores definidas por seus valores RGB, pode I média os valores vermelho, verde e azul e, em seguida, combinam-se para definir uma terceira cor que se parece com uma média visuais dos dois?

ou seja NewColor = (R1 + R2) / 2, (G1 + G2) / 2, (B1 + B2) / 2

EDIT1: Obrigado por todas as respostas. Para as minhas necessidades atuais, eu só estou lidando com pares de cores que são tons da mesma cor, então eu acho que em média eles vão trabalhar. No entanto, vou tentar converter para o Laboratório espacial para se certificar de que suposição é verdadeira ea técnica será útil no futuro.

EDIT2: Aqui estão os meus resultados fwiw. Color1 e Color2 são minhas duas cores e as duas colunas do meio são os resultados da média em L a b espaço e média RGB respectivamente. Neste caso não há muita diferença entre os dois cor e assim as diferenças na saída a partir das técnicas de média é sutil.

comparação visual das técnicas de média cor

Foi útil?

Solução

Dê uma olhada nas respostas a esta questão .

Basicamente, você deseja converter as cores em algo chamado Lab espaço , e encontrar o seu média nesse espaço.

espaço Lab é uma maneira de representar as cores onde os pontos que estão perto um do outro são aqueles que parecem semelhantes entre si para os seres humanos.

Outras dicas

Várias respostas sugerem a conversão para Lab espaço de cor -. O que provavelmente é uma boa abordagem para a manipulação de cores mais complexa

Mas se você simplesmente precisa de uma maneira rápida de tomar a média de duas cores, isso pode ser feito no espaço RGB. Você apenas tem que importar uma ressalva: Você deve conciliar os valores RGB antes de média entre elas, e depois tome a raiz do resultado. (Se você simplesmente tomar a média, o resultado tende a ser muito escuro.)

Como esta:

NewColor = sqrt((R1^2+R2^2)/2),sqrt((G1^2+G2^2)/2),sqrt((B1^2+B2^2)/2)

Aqui está uma grande vid que explica por que este método é eficiente: https://www.youtube.com/watch?v = LKnqECcg6Gw

Média em espaço de cor HSL pode produzir melhores resultados.

Eu não sei se tomar uma média simples dos componentes é o "melhor" de um ponto de vista perceptual (que soa como uma pergunta para um psicólogo), mas aqui estão alguns exemplos usando a média simples componente.

text alt

O one-vermelho-de mostarda verde é feio, mas a interpolação parece bastante razoável.

Sim. Você pode calcular a média duas cores juntas assim. É a abordagem usada pelo OpenGL para misturar cores em conjunto (por exemplo, na criação de mapas MIP para renderizar objetos distantes, ou tornando a 50% textura transparente). É rápido, simples e "bom o suficiente" para muitas situações. Não é completamente realista, no entanto, e provavelmente não seria usado em imagens de fotografia de qualidade.

Isso é difícil. Em primeiro lugar, um conjunto de valores RGB não definir uma cor. Eles precisam ser interpretadas à luz das cores primárias a que se referem (o espaço de cores), como sRGB, Rec.709, Rec.2020, Adobe RGB (1998), etc.

Além disso, valores RGB como normalmente se deparam-los não são proporcionais à luz linear: eles são "codificada" utilizando uma função não linear (gama). E às vezes (em aplicações de vídeo principalmente) o valor de "negro" não é zero, mas é compensado a partir de zero, normalmente 16 para valores de 8 bits. E "branco" não é 255, mas 235. sRGB e Rec.709 primárias share RGB, mas as suas funções de gama são diferentes.

A conversão espaço começa a cores com a remoção de qualquer preto compensado assim que o preto é zero. Se a função gama tem um ponto de interrupção no-lo (como sRGB e Rec.709 fazer), você terá que escalar cuidadosamente os valores RGB para que "branco" é 1.0.

Em seguida, "decodificar" o gamma fazendo o inverso da função gama originais. (Uma resposta sugerida em quadratura com os valores, o que é uma aproximação da decodificação gama.) Agora você tem valores RGB linear de luz em algum espaço de cor. Neste ponto, você pode converter de que o espaço de cor para o espaço Lab. A maioria das conversões de RGB para Lab passar por um espaço de cor intermediário chamado XYZ.

Os passos como chamadas de função aninhada:

Lab = XYZ2Lab (RGB2XYZ (gamma_decode (offset_and_scale (RGB), gammaFunction ), espaço de cor RGB ))

(espaço Lab foi desenvolvido em 1976 como uma tentativa de criar uma deformação perceptualmente uniforme do espaço padrão CIE XYZ. (Luv foi outra tentativa.) A idéia é que o euclidiano (em linha reta) distância entre duas cores que foram apenas-visivelmente diferente (um "JND") seria a mesma distância para quaisquer duas cores. a distância entre as duas cores no laboratório é conhecido como 'Delta-E'. a simples delta fórmula distância euclidiana é agora chamado dE76. Veja https://en.wikipedia.org/wiki/Color_difference )

No seu caso, você poderia calcular a média das duas cores Lab para obter um novo cor Lab, em seguida, reverter todas as conversões para voltar para RGB no seu espaço de cor escolhida.

Isto fará você perto, mas não é garantido, simplesmente porque "cor" é uma percepção humana, não uma quantidade física, e tem sido notoriamente difícil de caracterizar de forma confiável. Lab realmente não funcionam tão bem em ser perceptivelmente uniforme. Então ao invés de correção Lab, eles propuseram uma mais-complexa função nova, delta-E com outro warp built-in: DE94. Que foi melhor, mas não é perfeito, então outra proposta surgiu em 2000: DE2000. Também melhor, mas não perfeito. Veja a página Wiki acima para mais informações.

Se DE2000 não é bom o suficiente (ou complexa demais!) Que você pode ter um olhar para uma alternativa ao Lab chamado ICtCp que é reivindicada a ser mais perceptualmente uniforme do que Lab.

Eu acho que, a resposta de arntjw vai na direção certa, e reconhece o underlay logarítmica, como mencionado por Dan W. No entanto, a média geométrica adequada não é sqrt ((C1 ^ 2 + C2 ^ 2) / 2) , mas sqrt (C1-C2 *). Assim, a cor média seria:

NewColor = sqrt(R1*R2),sqrt(G1*G2),sqrt(B1*B2)

As cores resultantes são mais perto do que esperamos. Você pode generalizar para mais cores utilizando raízes de ordem superior, e peso cada cor pela adição de um expoente de seus componentes.

Na verdade, há uma maneira muito mais simples.

  • dimensionar a imagem para baixo para 1 x 1 pixel.

    Cor do 1px é a cor média de tudo o que você escalado

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top