2011-05-25 14 views
26

Al mezclar pintura azul y amarilla, el resultado es una especie de verde.Algoritmo para encontrar el color entre otros dos: en el espacio de color de los colores pintados

Tengo dos colores RGB:

azul = (0, 0, 255)

y amarillo = (255, 255, 0)

Cuál es el algoritmo para encontrar el color RGB ¿ese es el resultado de mezclar los dos colores, como aparecerían al usar pintura? Los colores resultantes del algoritmo no tienen que ser terriblemente exactos. Para el ejemplo anterior, solo debería verse como una especie de verde.

Gracias de antemano.

Editar: Esta función, escrita en Go, funcionó para mí, en función de la respuesta de LaC.

func paintMix(c1, c2 image.RGBAColor) image.RGBAColor { 
    r := 255 - ((255 - c1.R) + (255 - c2.R)) 
    g := 255 - ((255 - c1.G) + (255 - c2.G)) 
    b := 255 - ((255 - c1.B) + (255 - c2.B)) 
    return image.RGBAColor{r, g, b, 255} 
} 

Edición # 2 Allthought este logra mezclar cian y amarillo, la mezcla entre el azul y el amarillo se vuelve negro, lo que no parece correcto. Todavía estoy buscando un algoritmo de trabajo.

Edit # 3 Aquí hay un ejemplo de trabajo completo en Go, usando el espacio de color HLS: http://go.pastie.org/1976031. Gracias Mark Ransom.

Edición # 4 parece que el camino a seguir para una mejor mezcla de colores sería el uso de la ecuación de Kubelka-Munk

+2

Esta es una buena. Si alguien se da cuenta de que podrían conseguir un trabajo en Wolfram. http://www.wolframalpha.com/input/?i=yellow+%2B+blue –

+1

Ya se ha respondido en su mayor parte aquí: http://stackoverflow.com/questions/4235072/math-behind-the-colour-wheel – colinross

+1

Otro duplicado: http://stackoverflow.com/questions/1351442/is-there-an-algorithm-for-color-mixing-that-works-like-mixing-real-colors – tylerl

Respuesta

12

La pintura trabaja por absorción. Empiezas con luz blanca (255,255,255) y lo multiplicas por los factores de absorción.

La pintura azul absorbe toda la luz roja y verde que llega a ella.

La pintura amarilla absorbe toda la luz azul que la golpea.

En un mundo perfecto, eso significa que la combinación de pintura amarilla y azul daría como resultado pintura negra o, en el mejor de los casos, un gris barroso.En la práctica, la pintura "azul" tiene un sesgo hacia el verde, por lo que se obtiene un verde fangoso. Nunca he visto un ejemplo de mezclar amarillo y azul que produzca un verde satisfactorio. Wikipedia entra en algunas de las complejidades de este proceso: http://en.wikipedia.org/wiki/Primary_color#Subtractive_primaries

Creo que lo que realmente está preguntando es cómo interpolar colores a lo largo de una rueda de colores. Esto debería ser independiente de si los colores son absorbentes como en la pintura o emisivos como en las pantallas RGB.

Editar: Al trabajar en el espacio de color HSL puede obtener el tipo de resultados que está buscando. Aquí hay un código en Python que implementa el algoritmo; promediar los tonos es engañoso y se basa en una respuesta anterior a la mía for averaging angles.

from colorsys import rgb_to_hls,hls_to_rgb 
from math import sin,cos,atan2,pi 

def average_colors(rgb1, rgb2): 
    h1, l1, s1 = rgb_to_hls(rgb1[0]/255., rgb1[1]/255., rgb1[2]/255.) 
    h2, l2, s2 = rgb_to_hls(rgb2[0]/255., rgb2[1]/255., rgb2[2]/255.) 
    s = 0.5 * (s1 + s2) 
    l = 0.5 * (l1 + l2) 
    x = cos(2*pi*h1) + cos(2*pi*h2) 
    y = sin(2*pi*h1) + sin(2*pi*h2) 
    if x != 0.0 or y != 0.0: 
     h = atan2(y, x)/(2*pi) 
    else: 
     h = 0.0 
     s = 0.0 
    r, g, b = hls_to_rgb(h, l, s) 
    return (int(r*255.), int(g*255.), int(b*255.)) 

>>> average_colors((255,255,0),(0,0,255)) 
(0, 255, 111) 
>>> average_colors((255,255,0),(0,255,255)) 
(0, 255, 0) 

Tenga en cuenta que esta respuesta no hace mezcla de pintura emular, por las razones expuestas anteriormente. Más bien da una mezcla intuitiva de colores que no se basa en ninguna realidad física del mundo.

+1

El uso de HSL me parece la buena respuesta. Utilizo HSL para algunos problemas (como producir conjuntos aleatorios de colores contrastados) y da resultados que son muy coherentes con la experiencia del ojo humano. –

+0

@Mark ¿Cómo ajustaría esto si tuviera cantidades desiguales de color, digamos 30% rojo + 70% azul? – glenstorey

+1

Intento emular el color del mundo real en mi categoría UIColor + Mixing. Se mezcla en RGB (estilo de computadora), RYB (mundo real, aditivo) y CMYK (mundo real, sustractivo). Los algoritmos son bastante simples y puede ajustar el divisor (según el número de colores) para obtener más de lo que desea. Sin limitaciones, diviértase con ello. Https://github.com/ddelruss/UIColor-Mixing Enjoy. –

9

En realidad, se obtiene verde de mezcla (sustractiva) amarillo y cian. El amarillo es rojo + verde (255, 255, 0), cian es verde + azul (0, 255, 255). Ahora haz los colores opuestos: azul (0, 0, 255) y rojo (255, 0, 0). Mézclalos de forma aditiva y obtienes morado (255, 0, 255). Haz lo opuesto y obtienes verde (0, 255, 0).

En otras palabras, puede obtener una mezcla sustractiva como opuesta a la mezcla aditiva de los opuestos de los dos colores.

4

El espacio de color RBG se basa en la luz emisión, el espacio de color de los tintes y pigmentos se basa en la luz absorción.

p. Ej. Las plantas no se ven verdes porque emiten luz verde, pero debido a que absorben todos los otros colores de la luz, que reflejan solo el verde.

En base a esto, debe poder acercarse bastante haciendo una conversión de RGB a un espacio de color absorbente, haciendo la "mezcla" y luego de vuelta.

+0

CMYK es el espacio de color estándar de absorción. – blueberryfields

+0

CMYK es * uno * de los espacios de color absortivos comúnmente utilizados, quizás el más común. Sin duda es suficiente para resolver el problema OP. – Bevan

2

¿Quieres utilizar CMY-colores sustractivos (cian, magenta, amarillo) (como Lac está haciendo, whithout el uso del término)

La conversión de ida y vuelta es simple: (C, M, Y) = (-R, -G, -B).
Entonces CMY (0,0,0) es blanco y CMY (FF, FF, FF) es negro.

Cuando agrega dos colores CMY, existen diferentes formas de calcular los valores nuevos. Puede tomar el promedio, máximo o algo intermedio para cada valor de color.
Por ejemplo. para filtros de luz, siempre usa el valor máximo. Para la pintura que desea utilizar, algo más cercano al valor promedio.

Como señala LaC, el verde no se mezcla con amarillo y azul, sino que se mezcla con amarillo y cian. Amarillo y azul realmente da negro, cuando se mezcla por valor máximo (por ejemplo, filtros de luz). Por esta razón, es posible que desee utilizar algo más cercano al valor promedio para la mezcla de pintura.

No desea utilizar CMYK, a menos que desee imprimir algo. El color negro "K" se usa principalmente en impresoras para ahorrar tinta, pero no es necesario para representar colores.

1

Uso Convert::Color para producir este tipo de salida:

mauve  is 0xE0B0FF sRGB=[224,176,255] HSV=[276, 31,100] 
vermilion is 0xE34234 sRGB=[227, 66, 52] HSV=[ 5, 77, 89] 
mix   is 0xE2799A sRGB=[226,121,154] HSV=[341, 46, 89] 

red   is 0xFF0000 sRGB=[255, 0, 0] HSV=[ 0,100,100] 
blue   is 0x0000FF sRGB=[ 0, 0,255] HSV=[240,100,100] 
red+blue  is 0x800080 sRGB=[128, 0,128] HSV=[300,100, 50] 

black  is 0xFFFFFF sRGB=[255,255,255] HSV=[ 0, 0,100] 
white  is 0x000000 sRGB=[ 0, 0, 0] HSV=[ 0, 0, 0] 
grey   is 0x808080 sRGB=[128,128,128] HSV=[ 0, 0, 50] 

dark red  is 0xFF8080 sRGB=[255,128,128] HSV=[ 0, 50,100] 
light red is 0x800000 sRGB=[128, 0, 0] HSV=[ 0,100, 50] 

pink   is 0x800080 sRGB=[128, 0,128] HSV=[300,100, 50] 
deep purple is 0xBF80FF sRGB=[191,128,255] HSV=[270, 50,100] 

Cuando se ejecuta este tipo de código:

#!/usr/bin/env perl 
use strict; 
use warnings; 

use Convert::Color; 

main(); 
exit; 

sub rgb($$$) { 
    my($r, $g, $b) = @_; 
    return new Convert::Color:: "rgb8:$r,$g,$b"; 
} 

sub show($$) { 
    my ($name, $color) = @_; 
    printf "%-12s is 0x%6s", $name, uc $color->hex; 
    printf " sRGB=[%3d,%3d,%3d] ",  $color->rgb8; 

    my ($h,$s,$v) = $color->as_hsv->hsv; 
    for ($s, $v) { $_ *= 100 } 
    printf " HSV=[%3.0f,%3.0f,%3.0f] ", $h, $s, $v; 
    print "\n"; 
} 

sub main { 
    my $vermilion = rgb 227, 66, 52; 
    my $mauve  = rgb 224, 176, 255; 
    show mauve  => $mauve; 
    show vermilion => $vermilion; 

    my $mix = alpha_blend $mauve $vermilion; 
    show mix => $mix; 
    print "\n"; 

    my $red = rgb 255, 0, 0; 
    my $blue = rgb 0, 0, 255; 
    show red => $red; 
    show blue => $blue; 

    $mix = alpha_blend $red $blue; 
    show "red+blue" => $mix; 
    print "\n"; 

    my $black = rgb 255, 255, 255; 
    my $white = rgb 0,  0, 0; 
    show black => $black; 
    show white => $white; 

    my $grey = alpha_blend $black $white; 
    show grey => $grey; 
    print "\n"; 

    my $dark_red = alpha_blend $red $black; 
    my $light_red = alpha_blend $red $white; 

    show "dark red" => $dark_red; 
    show "light red" => $light_red; 
    print "\n"; 

    my $magenta = rgb 255, 0, 255; 
    my $violet = rgb 127, 0, 255; 

    my $pink  = alpha_blend $magenta $white; 
    my $deep_purple = alpha_blend $violet $black; 

    show pink   => $pink; 
    show "deep purple" => $deep_purple;; 
} 
+0

Después de instalar Convert :: Color desde http://search.cpan.org/src/PEVANS/List-UtilsBy-0.07/lib/List/UtilsBy.pm ​​y List :: UtilsBy desde http://search.cpan.org /src/PEVANS/List-UtilsBy-0.07/lib/List/UtilsBy.pm, Esto es lo que obtengo cuando ejecuto el script de Perl anterior (agregué el "}" que faltaba al final): Espacio de color no reconocido nombre 'rgb8' en ./color.pl línea 12 – Alexander

+0

Bueno, ese es el programa que ejecuté. Oh, ya veo, estoy ejecutando la versión 0.08 de Convert :: Color. Verifique su número de versión. – tchrist

+0

Una respuesta que te obliga a lidiar con Perl en lugar de lidiar con el problema en cuestión no es lo que estaba buscando ... – Alexander

Cuestiones relacionadas