Star

Created With

linkConversión a escala de grises.

linkProblem statement

Aplicar conversión a escala de grises en una imagen y un video usando el promediado RGB y Luma.

linkBackground

Para ahondar un poco en el tema se explicara antes conceptos fundamentales.

linkRGB

RGB (red, green, blue) es la composición del color en términos de la intensidad de los colores primarios de la luz, con el se realiza el tratamiento de la señal de vídeo que trata por separado las señales de los tres colores rojo, verde y azul. Al usarlo independientemente, proporciona mayor calidad y reproducción más fiel del color.

El modelo RGB está formado por los tres componentes de colores primarios aditivos y como mínimo un componente de sincronismo. Los componentes de color son las señales rojo, verde y azul; siendo transmitidos cada uno independiente y aislado del resto.

De esta forma no hay pérdidas en el tratamiento de la imagen puesto que los colores primarios siguen existiendo como tal en su transmisión. Por el contrario, mediante este sistema hay mucha información redundante, con el consiguiente aumento del ancho de banda necesario respecto a otros métodos de transmisión. Por ejemplo, cada color lleva el valor de brillo de toda la imagen, de forma que esta información está por triplicado.

linkEscala de Grises

En computación una escala de grises es la representación de una imagen en la que cada pixel se dibuja usando un valor numérico individual que representa su luminancia, en una escala que se extiende entre blanco y negro.

Algunas formas de transformar una imagen a escala de grises:

linkPromedio RGB

Es sin duda la solución trivial donde por medio del promedio de los 3 canales (rojo,verde y azul) para cada pixel de la imagen obtendremos un valor que sobreescribirá el valor de cada canal para este píxel, de esta manera la imagen que obtenemos tendrá un gris bastante razonable.

Dando una definición un poco más formal esta es simplemente la proyección de un punto sobre el eje neutral, la altura vertical de un punto en nuestro cubo inclinado. La ventaja es que, junto con los cálculos de tonalidad y crominancia de la distancia euclidiana, esta representación conserva las distancias y los ángulos de la geometría del cubo RGB.

Dicho esto se podría calcular con la siguiente fórmula:

I=avg(R,G,B)=13(R+G+B)I = avg(R,G,B) = \frac{1}{3} (R + G + B)1

linkLuma

En una transmisión de señal de vídeo, luma es el componente que codifica la información de luminosidad de la imagen. En términos generales, es algo muy similar a la versión en blanco y negro de la imagen original. Luma y crominancia combinadas proporcionan la señal denominada señal de vídeo compuesto, utilizada en multitud de aplicaciones; pueden enviarse conjuntamente o transmitirse independientemente. Forman parte de la codificación de vídeo en los estándares de TV NTSC y PAL, entre otros.

Es un término comúnmente utilizado en el procesamiento digital de imágenes para caracterizar a cada píxel.

En los formatos digitales que siguen el estándar CCIR_601 que sería equivalente a SDTV , la luma de un píxel se calcula con la fórmula

Y=0,299R+0,587G+0,114B.Y'=0,299 * R + 0,587 * G + 0,114 * B.1

Adicionalmente se incluyó la conversión usada por los sistemas UHDTV y HDR modernos que corresponde a:

Y=0,2627R+0,6780G+0,0593B.Y'=0,2627 * R + 0,6780 * G + 0,0593 * B.1

linkCode (solution) & results

linkEscala de grises en imágenes

Para lograr la conversión de las imágenes a escala de grises (promedio RGB, Luma) basta con acceder al componente RGB de cada pixel de la imagen, posteriormente realizar el cálculo ya sea del promedio o del coeficiente Luma (fórmulas expuestas anteriormente) para finalmente crear nuevas imágenes que contendrán el valor obtenido en cada uno de los canales del pixel. De esta manera se obtendrán los resultados mostrados continuos al código fuente de la solución.

linkCodigo

Se presenta el código fuente:

1link

2linklet imagenOriginal, imagenPromedio, imagenLuma, imagenLuma2;

3link

4linkfunction preload() {

5link imagenOriginal = loadImage('/vc/docs/sketches/assets/exampleImage.jpg');

6link imagenPromedio = createImage(402, 322);

7link imagenLuma = createImage(402, 322);

8link imagenLuma2 = createImage(402, 322);

9link}

10link

11linkfunction setup() {

12link createCanvas(804, 644);

13link imagenOriginal.resize(402, 322);

14link}

15link

16linkfunction draw() {

17link

18link imagenOriginal.loadPixels();

19link imagenPromedio.loadPixels();

20link imagenLuma.loadPixels();

21link imagenLuma2.loadPixels();

22link

23link for (let y = 0; y < imagenOriginal.height; y++) {

24link for (let x = 0; x < imagenOriginal.width; x++) {

25link

26link let index = (x + y * imagenOriginal.width) * 4;

27link

28link let r = imagenOriginal.pixels[index + 0];

29link let g = imagenOriginal.pixels[index + 1];

30link let b = imagenOriginal.pixels[index + 2];

31link

32link let bw = (r + g + b) / 3; // Promedio

33link

34link imagenPromedio.pixels[index + 0] = bw;

35link imagenPromedio.pixels[index + 1] = bw;

36link imagenPromedio.pixels[index + 2] = bw;

37link imagenPromedio.pixels[index + 3] = 255;

38link

39link

40link let luma = r * .299 + g * .587 + b * .114; //SDTV

41link

42link imagenLuma.pixels[index + 0] = luma;

43link imagenLuma.pixels[index + 1] = luma;

44link imagenLuma.pixels[index + 2] = luma;

45link imagenLuma.pixels[index + 3] = 255;

46link

47link

48link let luma2 = r * .263 + g * .678 + b * .059; //UHDTV HDR

49link

50link imagenLuma2.pixels[index + 0] = luma2;

51link imagenLuma2.pixels[index + 1] = luma2;

52link imagenLuma2.pixels[index + 2] = luma2;

53link imagenLuma2.pixels[index + 3] = 255;

54link

55link }

56link }

57link imagenPromedio.updatePixels();

58link imagenLuma.updatePixels();

59link imagenLuma2.updatePixels();

60link

61link textSize(10);

62link stroke(0);

63link fill(30, 178, 166)

64link textStyle(BOLDITALIC);

65link

66link

67link image(imagenOriginal, 0, 0);

68link text('IMAGEN ORIGINAL', 20, 20);

69link image(imagenPromedio, imagenOriginal.width, 0);

70link text('PROMEDIO RGB', imagenOriginal.width + 20, 20);

71link image(imagenLuma, 0, imagenOriginal.height);

72link text('LUMA (SDTV)', 20, imagenOriginal.height + 20);

73link image(imagenLuma2, imagenOriginal.width, imagenOriginal.height);

74link text('LUMA (UHDTV)', imagenOriginal.width + 20, imagenOriginal.height + 20);

75link}

76link

linkResultados

Se presentan los resultados obtenidos:

linkEscala de grises en Videos

Para el caso de conversión a escala de grises en videos podemos pensar que será bastante similar al procedimiento con imágenes y es totalmente acertado, el tratamiento sobre los píxeles del video es exactamente el mismo que el empleado al procesar imágenes, solo debemos tener la consideración de obtener la información del video con los métodos correspondientes de P5, como lo veremos a continuación.

linkCodigo

Se presenta el código fuente:

1linkvar widthI= 429; // Anchura del lienzo

2linkvar heightI = 322; // Altura del lienzo

3link

4linklet videoOriginal, videoPromedio, videoLuma, videoLuma2;

5link

6linkfunction setup() {

7link videoOriginal = createVideo(['/vc/docs/sketches/assets/sample.mp4']);

8link videoOriginal.hide();

9link createCanvas(804, 644);

10link

11link videoPromedio = createImage(429, 322);

12link videoLuma = createImage(429, 322);

13link videoLuma2 = createImage(429, 322);

14link videoOriginal.volume(0);

15link}

16link

17linkfunction draw() {

18link

19link background(0);

20link videoOriginal.loadPixels();

21link videoPromedio.loadPixels();

22link videoLuma.loadPixels();

23link videoLuma2.loadPixels();

24link

25link for (let x = 0; x < videoOriginal.width; x++) {

26link for (let y = 0; y < videoOriginal.height; y++) {

27link

28link let index = (x + y * videoOriginal.width) * 4;

29link

30link let r = videoOriginal.pixels[index + 0];

31link let g = videoOriginal.pixels[index + 1];

32link let b = videoOriginal.pixels[index + 2];

33link

34link let bw = (r + g + b) / 3; // Promedio

35link

36link videoPromedio.pixels[index + 0] = bw;

37link videoPromedio.pixels[index + 1] = bw;

38link videoPromedio.pixels[index + 2] = bw;

39link videoPromedio.pixels[index + 3] = 255;

40link

41link let luma = r * .299 + g * .587 + b * .114; //SDTV

42link

43link videoLuma.pixels[index + 0] = luma;

44link videoLuma.pixels[index + 1] = luma;

45link videoLuma.pixels[index + 2] = luma;

46link videoLuma.pixels[index + 3] = 255;

47link

48link let luma2 = r * .263 + g * .678 + b * .059; //UHDTV HDR

49link

50link videoLuma2.pixels[index + 0] = luma2;

51link videoLuma2.pixels[index + 1] = luma2;

52link videoLuma2.pixels[index + 2] = luma2;

53link videoLuma2.pixels[index + 3] = 255;

54link }

55link }

56link videoPromedio.updatePixels();

57link videoLuma.updatePixels();

58link videoLuma2.updatePixels();

59link

60link

61link textSize(10);

62link stroke(0);

63link fill(30, 178, 166)

64link textStyle(BOLDITALIC);

65link

66link image(videoOriginal, 0, 0);

67link text('IMAGEN ORIGINAL', 20, 20);

68link image(videoPromedio, widthI, 0);

69link text('PROMEDIO RGB', widthI + 20, 20);

70link image(videoLuma, 0, heightI);

71link text('LUMA (SDTV)', 20, heightI + 20);

72link image(videoLuma2, widthI, heightI);

73link text('LUMA (UHDTV)', widthI + 20, heightI + 20);

74link

75link}

76link

77linkfunction mousePressed() {

78link videoOriginal.loop();

79link}

linkResultados

Se presentan los resultados obtenidos, para visualizarlos por favor dar click en el canvas:

linkConclusions & future work

Se espera continuar con la investigación aplicando distintos algoritmos y evaluando los resultados obtenidos.

Bibliografia

  • Wikipedia. (23 de Marzo de 2021). Wikipedia. Obtenido de HSL and HSV: https://en.wikipedia.org/wiki/HSL_and_HSV#Disadvantages
  • Wikipedia. (16 de Septiembre de 2020). Wikipedia. Obtenido de Luma (video): https://en.wikipedia.org/wiki/Luma_(video)
  • Developer Mozilla. (11 de Marzo de 2021). MDN Web Docs. Obtenido de Digital video concepts: https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Video_concepts
Conversión a escala de grises.Problem statementBackgroundRGBEscala de GrisesPromedio RGBLumaCode (solution) & resultsEscala de grises en imágenesCodigoResultadosEscala de grises en VideosCodigoResultadosConclusions & future work

Home

Workshopschevron_right
Imaging & Videochevron_right
Softwarechevron_right
Hardwarechevron_right
Renderingchevron_right
Algovischevron_right
Computer Graphicschevron_right
HCIchevron_right
P5 Code Snippetschevron_right
Memberschevron_right