Star

Created With

Escala de Grises RGB y LUMA

linkAntecedentes

El color no se considera como un atributo que tienen los objetos, sino como el resultado de un proceso visual entre la retina del ojo y el cerebro ya que el color se produce por la percepción de la luz. Debido a los tipos de conos fotoreceptores que poseen los animales, el humano en particular, se clasifican estos receptores en: los que responden a la luz roja del espectro visible, los que responden a la luz azul y los que responden a la luz verde.

Con base en esto se define el modelo de color RGB, el más conocido y utilizado. En este modelo cada color está representado por tres valores: el rojo (R), verde (G) y azul (B); de manera convencional se puede ubicar este modelo de color en un espacio cartesiano de 3 ejes, donde cada uno corresponde a uno de los tres valores del modelo en el rango [0,255] como se ve en la siguiente imagen:

RGB Space Image

De esta manera el negro se representa como (0,0,0) y el blanco como (255,255,255); para el caso particular de los colores en escala de grises, estos se obtienen con valores idénticos de R, G, y B.

Existen diversas técnicas de conversión a escala de grises a partir del modelo RGB. Desde el promedio, la tonalidad (basada en el modelo HSL), la luminosidad o Luma, entre otros; en el presente ejercicio se realizarán implementaciones de los algoritmos de Promedio RGB y Luma. El promedio RGB es el método más simple de lograr una conversión, ya que solo se necesita tomar los valores RGB de cada pixel y promediarlos, su formula es la siguiente:

GreyRGB(i,j)=R(i,j)+G(i,j)+B(i,j)3Grey_{RGB}(i,j) = \frac{R (i, j) + G (i, j) + B (i, j)}{3}1

Por su parte, el método de la Luminosidad (o Luma) consiste en una verión más sofisticada que la del promedio, ya que se realiza una suma de las ponderaciones de los valores de los componentes R, G y B con base en que el ojo humano es más sensible al color verde que a los otros colores (por esto su ponderación es mayor). Estos valores fueron establecidos a través de la recomendación Rec. 601 NTSC por la International Telecommunication Union - Radiocommunications.

LumaRGB(i,j)=0,299R(i,j)+0,587G(i,j)+0,114B(i,j)Luma_{RGB}(i,j) = 0,299 * R (i, j) + 0,587 * G (i, j) + 0,114 * B (i, j)1

A continuación en la pestaña Imagen RGB y Luma se podrá visualizar la implementación de los dos métodos mencionados anteriormente aplicados a una imagen por medio de shadders en WEBGL, lo cual permite que se ejecute el código directamente en la unidad de procesamiento gráfica GPU. Se crea una textura con la imagen y a esa textura se le calcula el promedio RGB y luma según el usuario especifique con las siguientes teclas:

TeclaResultado
0Imagen/Video Original
1Imagen/Video Promedio RGB
2Imagen/Video Luma

La representación de la imagen convertida se visualizará aplicada a una elipse y a un cubo que rota, con el ánimo de explorar una de las capacidades de WEBGL que es el manejo de elementos en 3D. De igual manera veremos como la luz puede afectar principalmente a el mencionado objeto 3D al pasar el cursor sobre el mismo y ver como la luz de distorsiona sobre el objeto (se observa mejor al dejar el cursor estático en un lugar cerca al cubo).

En la pestaña Video RGB y Luma se visualizan las mismas conversiones pero esta vez aplicadas a la captura de video por cámara en tiempo real. El video responde a los mismos comandos por teclas mencionados anteriormente, igualmente aplicando las texturas a un shader de WEBGL.

Por su parte, la pestaña Instrucciones describe un paso a paso del proceso de conversión de los elementos mencionados (imagen y video) ya que son pasos en su mayoría similares; Iniciando con la creación de los shaders respectivos a partir de los Fragment Shader y Vertex Shader correspondientes, una vez creado el canvas tipo WEBGL se pasan los datos de imagen o video al fragment shader para que identifique según la tecla presionada por el usuario que tipo de transformación desea. Por último el Fragment Shader calcula la escala de grises deseada y devuelve el renderizado de la imagen/video para ser mostrada.

Finalmente, las pestañas Código Imagen y Código Video muestra el código de implementación para los fragment shaders usados en la imagen y el video respectivamente, ambos tienen comentarios de su funcionamiento para mayor comprensión.

linkSolución y Resultados

No.Descripción
1Precargar Shader para imagen/ video con el vertex y fragment shader.
2Crear canvas de WEBGL.
3Crear el shader a partir del precargado.
4Pasar datos de imagen/video y tecla de control al Fragment Shader.
5El fragment shader carga la textura (ya sea video o imagen).
6Calcula el valor en escala de grises a representar según el comando recibido en la tecla de control.
7Renderizar el valor de color deseado y mostrar en pantalla.
8En el caso de Imagen, aplicar la textura renderizada en 2D(elipse) y 3D (cubo).
texture.frag
1link// Funcion para convertir un color a escala de grises

2linkfloat grayscale(vec3 color) {

3link float lightness;

4link // Si la tecla de control es 1 se calcula el promedio RGB

5link if (u_key==1){

6link float I=(color.r + color.g + color.b) / 3.0; // Promedio de los tres componentes

7link lightness = I;

8link } else if (u_key==2){

9link // Si la tecla de control es 2 se calcula el valor luma

10link // Promedio ponderado de RGB con correccion gamma (Luma)

11link float Y= dot(color, vec3(0.299, 0.587, 0.114)); // SDTV

12link lightness = Y;

13link }

14link return lightness;

15link}

16link

17linkvoid main() {

18link vec2 uv = vTexCoord;

19link

20link //Invierte la posicion de la cordenada para que la imagen no quede al reves

21link uv.y = 1.0 - uv.y;

22link

23link vec4 tex = texture2D(u_img, uv);

24link // Calculo de escala de grises

25link float gray =grayscale(tex.rgb);

26link

27link float threshR = gray ;

28link float threshG = gray ;

29link float threshB = gray ;

30link

31link // Si la tecla de control es 0 se muestra la imagen original

32link if (u_key==0){

33link threshR = tex.r ;

34link threshG = tex.g ;

35link threshB = tex.b ;

36link }

37link vec3 thresh = vec3(threshR, threshG, threshB);

38link

39link // Se renderiza la salida

40link gl_FragColor = vec4(thresh, 1.0);

41link}

42link

webcam.frag
1link// Funcion para calculo de valor Luma de un color

2linkfloat luma(vec3 color) {

3link return dot(color, vec3(0.299, 0.587, 0.114));

4link}

5link

6link// Funcion para calculo del promedio RGB

7linkfloat grayRGB(vec3 color) {

8link float lightness=(color.r + color.g + color.b) / 3.0; // Promedio de los tres componentes

9link return lightness;

10link}

11linkvoid main() {

12link

13link vec2 uv = vTexCoord;

14link // voltear la textura para mostrarse al derecho

15link uv = 1.0 - uv;

16link

17link vec4 tex = texture2D(tex0, uv);

18link

19link float gray;

20link //Dejar valores de color originales desde el inicio

21link

22link float threshR = tex.r ;

23link float threshG = tex.g ;

24link float threshB = tex.b ;

25link

26link // Si la tecla de control es 1 se calcula la el promedio RGB

27link if (u_key==1){

28link

29link gray =grayRGB(tex.rgb);

30link

31link threshR = gray ;

32link threshG = gray ;

33link threshB = gray ;

34link }else if (u_key==2){

35link // Si la tecla de control es 2 se calcula el valor luma

36link gray = luma(tex.rgb);

37link

38link threshR = gray ;

39link threshG = gray ;

40link threshB = gray ;

41link }

42link

43link vec3 thresh = vec3(threshR, threshG, threshB);

44link

45link // Se renderiza la salida

46link gl_FragColor = vec4(thresh, 1.0);

47link}

48link

Se mostró exitosamente como es la implementación lógica y fundamentación teórica de la conversión a escala de grises por medio del promedio RGB y cálculo de Luma. A pesar de haber mostrado un acercamiento mínimo al renderizado 3D, se estima y se evidencia la alta capacidad para la representación de objetos con las texturas deseadas en un entorno espacial definido; las principales aplicaciones de lo mostrado son relacionadas con la creación de videojuegos e incluso de realidad virtual. Sin embargo cabe la posibilidad de la incursión en rubros como la medicina en el diagnóstico de imagenes, al pensar en una representación 3D del cuerpo humano y sus organos internos con texturas analizadas en laboratorio. De igual manera las simulaciones en cualquier ámbito pueden ser ejecutadas con ayuda de los shaders.

Por su parte la escala de grises ayuda a la comparación de la luminosidad de los colores, lo que permite la clasificación de los mismos y también a distinguir los grados de claridad en las atenuaciones y degradados de color. Todas estas son parte fundamental en el diseño gráfico y sus lineas de desempeño. Una de las aplicaciones más novedosa consiste en la recuperación de imagenes con sus colores originales a partir de su versión en escala de grises, sin embargo para esto hay que ajustar el brillo y el componenete gamma (Separación entre el color azul y el negro), entre otros. Tal como lo muestra el estudio realizado por Jesús Gustavo folres Eraña.

linkReferencias y Bibliografía

Metodos de Conversion a Escala de Grises

Image Grayscale Assets

Video Grayscale Assets

RGB Space Image

Sintesis Digital de Color Utilizando Tonos de Gris

AntecedentesSolución y ResultadosReferencias y Bibliografía

Home

Workshopschevron_right
Imaging & Videochevron_right
Softwarechevron_right
Hardwarechevron_right

Introducción RGB y Luma Mascaras de Convolución Ascii Art Foto-Mosaico

Desempeño Computacionalchevron_right

Conclusiones y Trabajo Futuro

Renderingchevron_right
Teamchevron_right