Convertir RGB a escala de grises / intensidad

129

Al convertir de RGB a escala de grises, se dice que se deben aplicar pesos específicos a los canales R, G y B. Estos pesos son: 0.2989, 0.5870, 0.1140.

Se dice que la razón de esto es la diferente percepción / sensibilidad humana hacia estos tres colores. A veces también se dice que estos son los valores utilizados para calcular la señal NTSC.

Sin embargo, no encontré una buena referencia para esto en la web. ¿Cuál es la fuente de estos valores?

Vea también estas preguntas anteriores: aquí y aquí .

ypnos
fuente
26
Si lo hace Hago programación en valores RGB todo el tiempo. Aplicar valores del "mundo real" a estos cálculos es muy importante si desea que su aplicación valga la pena.
Neil N
1
Muchos programadores pueden no preocuparse y calcular imágenes de escala de grises "incorrectas", pero a mí sí.
ypnos
66
Estoy de acuerdo en que está relacionado con la codificación, definitivamente un problema interesante y relevante si está codificando gráficos. +1 como me gustaría saber la respuesta yo mismo
Cruachan
66
RGB está relacionado con la programación. Es tan relacionado con la programación como analizar cadenas de fechas. Como convertir el texto "verdadero" a un valor booleano.
Neil N

Respuestas:

87

Los números específicos en la pregunta son del CCIR 601 (vea el enlace de Wikipedia a continuación).

Si convierte RGB -> escala de grises con números ligeramente diferentes / métodos diferentes, no verá mucha diferencia en la pantalla de una computadora normal en condiciones de iluminación normales, pruébelo.

Aquí hay algunos enlaces más sobre el color en general:

Wikipedia Luma

El destacado sitio web de Bruce Lindbloom

capítulo 4 sobre Color en el libro de Colin Ware, "Visualización de información", isbn 1-55860-819-2; este largo enlace a Ware en books.google.com puede o no funcionar

cambridgeincolor : excelentes "tutoriales bien escritos sobre cómo adquirir, interpretar y procesar fotografías digitales utilizando un enfoque orientado visualmente que enfatiza el concepto sobre el procedimiento"

Si te topas con RGB "lineal" frente a "no lineal", aquí hay parte de una vieja nota para mí sobre esto. Repita, en la práctica no verá mucha diferencia.


RGB -> ^ gamma -> Y -> L *

En la ciencia del color, los valores RGB comunes, como en html rgb (10%, 20%, 30%), se denominan "no lineales" o Gamma corregidos . Los valores "lineales" se definen como

Rlin = R^gamma,  Glin = G^gamma,  Blin = B^gamma

donde gamma es 2.2 para muchas PC. Los RGB habituales a veces se escriben como R 'G' B '(R' = Rlin ^ (1 / gamma)) (purista clic de lengua) pero aquí soltaré el '.

El brillo en una pantalla CRT es proporcional a RGBlin = RGB ^ gamma, por lo que el 50% de gris en una CRT es bastante oscuro: .5 ^ 2.2 = 22% del brillo máximo. (Las pantallas LCD son más complejas; además, algunas tarjetas gráficas compensan la gamma).

Para obtener la medida de la luminosidad llamada L*desde RGB, primero divida RGB entre 255 y calcule

Y = .2126 * R^gamma + .7152 * G^gamma + .0722 * B^gamma

Esto está Yen el espacio de color XYZ; Es una medida de color "luminancia". (Las fórmulas reales no son exactamente x ^ gamma, sino cercanas; quédese con x ^ gamma para una primera pasada).

Finalmente,

L* = 116 * Y ^ 1/3 - 16

"... aspira a la uniformidad perceptiva [y] coincide estrechamente con la percepción humana de la ligereza". - Espacio de color de Wikipedia Lab

denis
fuente
8
Y = 0.2126 * R + 0.7152 * G + 0.0722 * B - Wikipedia ( en.wikipedia.org/wiki/Grayscale )
iamantony
14

Encontré que esta publicación hace referencia en una respuesta a una pregunta similar anterior. Es de mucha ayuda:

http://cadik.posvete.cz/color_to_gray_evaluation/

¡Muestra 'toneladas' de diferentes métodos para generar imágenes en escala de grises con diferentes resultados!

ypnos
fuente
9

Aquí hay un código en c para convertir rgb a escala de grises. La ponderación real utilizada para la conversión de rgb a escala de grises es 0.3R + 0.6G + 0.11B. estos pesos no son absolutamente críticos para que puedas jugar con ellos. Los he hecho 0.25R + 0.5G + 0.25B. Produce una imagen ligeramente más oscura.

NOTA: El siguiente código asume el formato de píxeles xRGB de 32 bits

unsigned int *pntrBWImage=(unsigned int*)..data pointer..;  //assumes 4*width*height bytes with 32 bits i.e. 4 bytes per pixel
unsigned int fourBytes;
        unsigned char r,g,b;
        for (int index=0;index<width*height;index++)
        {
            fourBytes=pntrBWImage[index];//caches 4 bytes at a time
            r=(fourBytes>>16);
            g=(fourBytes>>8);
            b=fourBytes;

            I_Out[index] = (r >>2)+ (g>>1) + (b>>2); //This runs in 0.00065s on my pc and produces slightly darker results
            //I_Out[index]=((unsigned int)(r+g+b))/3;     //This runs in 0.0011s on my pc and produces a pure average
        }
twerdster
fuente
2
0.3 0.6 0.11 no agrega a 1. Wikipedia parece sugerir 0.30 0.59 0.11.
damix911
Es cierto, pero el único resultado de que no se sumen a 1 será un cambio muy leve en la intensidad. El método propuesto de 0.25,0.5,0.25 suma a 1 pero no importaría si no lo hiciera. Es una optimización, por lo que renunciar a un poco de precisión es una compensación razonable.
twerdster
2
@twerdster Ninguno de los conjuntos de coeficientes es correcto. .3, .6, .11 es el antiguo estándar NTSC, no sRGB / Rec709 (que es lo que usan la web y la mayoría de las computadoras). Y su 0.25,0.5,0.25 no es una compensación razonable: B es solo el 7% de luminancia, se equivoca en un 347%. Los coeficientes para sRGB / r709 (después de la linealización): Rlin * 0.2126 + Glin * 0.7152 + Blin * 0.0722 = Y Estas ponderaciones espectrales se derivan de la percepción espectral humana. No puede simplemente atascar los números que desee por conveniencia y esperar ser precisos. Necesita linealizar sRGB y luego aplicar los coeficientes correctos.
Myndex
Si se encuentra en una situación en la brecha es demasiado caro, una aproximación que utiliza un solo multiplican con los cambios y añade es: 0.11111111 * ((G + (G<<1) + R) <<1) + B). Esto es equivalente a (2*R+6*G+B) / 9)o 0.222 R + 0.666 G + 0.111 B. Antes de pasar a producción, compare con una fórmula precisa para varios casos de prueba.
ToolmakerSteve
6

Consulte las Preguntas frecuentes sobre el color para obtener información al respecto. Estos valores provienen de la estandarización de los valores RGB que usamos en nuestras pantallas. En realidad, de acuerdo con las Preguntas frecuentes sobre el color, los valores que está utilizando no están actualizados, ya que son los valores utilizados para el estándar NTSC original y no para los monitores modernos.

Brian Campbell
fuente
3

¿Cuál es la fuente de estos valores?

La "fuente" de los coeficientes publicados son las especificaciones NTSC que se pueden ver en Rec601 y Características de la televisión .

La "fuente fundamental" son los experimentos de CIE de 1931 sobre la percepción del color humano. La respuesta espectral de la visión humana no es uniforme. Los experimentos condujeron a la ponderación de los valores de triestímulo basados ​​en la percepción. Nuestros conos L, M y S 1 son sensibles a las longitudes de onda de luz que identificamos como "Rojo", "Verde" y "Azul" (respectivamente), que es donde se derivan los colores primarios del triestímulo. 2

Las ponderaciones espectrales de luz lineal 3 para sRGB (y Rec709) son:

R lin * 0.2126 + G lin * 0.7152 + B lin * 0.0722 = Y

Estos son específicos de los espacios de color sRGB y Rec709, que están destinados a representar monitores de computadora (sRGB) o monitores HDTV (Rec709), y se detallan en los documentos de la UIT para Rec709 y también BT.2380-2 (10/2018)

NOTAS AL PIE (1) Los conos son las células que detectan el color de la retina del ojo.
(2) Sin embargo, las longitudes de onda de triestímulo elegidas NO están en el "pico" de cada tipo de cono; en cambio, los valores de triestímulo se eligen de manera que estimulen un tipo de cono en particular sustancialmente más que otro, es decir, la separación del estímulo.
(3) Debe linealizar sus valores sRGB antes de aplicar los coeficientes. Discuto esto en otra respuesta aquí.

Myndex
fuente
-2

Estos valores varían de persona a persona, especialmente para las personas daltónicas.

Bob Pickle
fuente
-4

es todo esto realmente necesario, la percepción humana y la CRT vs LCD variarán, pero la intensidad RGB no, ¿por qué no L = (R + G + B)/3y establecer el nuevo RGB en L, L, L?

usuario1668969
fuente
3
Simplemente promediando las tres primarias R, G, B las trata como perceptivamente iguales, lo cual no es el caso para el sistema de visión humana.
Bill Feth