Convertir una imagen a color a escala de grises usando el promedio RGB y Luma.
Antiguamente las imágenes estaban solamente presentadas en escalas de grises, en estas imágenes las formas se podían distinguir por su luminosidad. En algunos casos se podía distinguir si los objetos eran de diferentes colores cuando estos tenían “grises” diferentes. Ahora con la aparición y uso del RGB (Red, Green & Blue) o en español RVA (Rojo, Verde & Azul), se hace uso del modelo aditivo de la luz para simular la mayoría de los colores visibles. Aunque pasar de un modelo RGB a una escala de grises es poco común, esto es posible hacerlo gracias a distintos métodos de conversión, entre ellos están el promedio de RGB y Luma.
El promedio RGB, como lo indica su nombre, solo hace uso del promedio de los valores en la escala RGB para calcular la luminosidad del píxel y de esta manera transformarlo a escala de grises.
1link> let img;
2link> let imgOriginal;
3link>
4link> function preload() {
5link> img = loadImage('/vc/docs/sketches/Taller1/ImagingAndVideo/WolvCar.png');
6link> imgOriginal = loadImage('/vc/docs/sketches/Taller1/ImagingAndVideo/WolvCar.png');
7link> }
8link>
9link> function setup() {
10link> createCanvas(780, 500);
11link> pixelDensity(1);
12link> imgOriginal.resize(390,500);
13link> image(imgOriginal, 0, 0);
14link> }
15link>
16link> function draw() {
17link> img.resize(390,500);
18link> image(img, 390, 0);
19link> img.loadPixels();
20link> for (var y = 0; y < img.height; y++) {
21link> for (var x = 0; x < img.width; x++) {
22link> var index = (x + y * img.width) * 4;
23link> var r = img.pixels[index + 0];
24link> var g = img.pixels[index + 1];
25link> var b = img.pixels[index + 2];
26link> var bw = (r + g + b) / 3;
27link> img.pixels[index + 0] = bw;
28link> img.pixels[index + 1] = bw;
29link> img.pixels[index + 2] = bw;
30link> }
31link> }
32link> img.updatePixels();
33link> }
Luma, por otro lado, es definida como la corrección de gamma en una señal de video. Los más usados actualmente son UIT-R BT 601 (TVSD) y UIT-R BT 709 (TVHD) que están definidos como:
El resultado es el siguiente:
1link> let img;
2link> let imgOriginal;
3link>
4link> function preload() {
5link> img = loadImage('/vc/docs/sketches/Taller1/ImagingAndVideo/WolvCar.png');
6link> imgOriginal = loadImage('/vc/docs/sketches/Taller1/ImagingAndVideo/WolvCar.png');
7link> }
8link>
9link> function setup() {
10link> createCanvas(780, 500);
11link> pixelDensity(1);
12link> imgOriginal.resize(390,500);
13link> image(imgOriginal, 0, 0);
14link> img.resize(390,500);
15link> img.loadPixels();
16link> for (var y = 0; y < img.height; y++) {
17link> for (var x = 0; x < img.width; x++) {
18link> var index = (x + y * img.width) * 4;
19link> var r = img.pixels[index + 0];
20link> var g = img.pixels[index + 1];
21link> var b = img.pixels[index + 2];
22link> var luma = r * .299 + g * .587 + b * .0114;
23link> img.pixels[index + 0] = luma;
24link> img.pixels[index + 1] = luma;
25link> img.pixels[index + 2] = luma;
26link> }
27link> }
28link> img.updatePixels();
29link> image(img, 390, 0);
30link> }
Si realizamos la comparacion entre el metodo de promedio RGB y Luma, podemos notar que el segundo tiene su escala mas oscura que el primero.
1link> let img;
2link> let imgOriginal;
3link>
4link> function preload() {
5link> img = loadImage('/vc/docs/sketches/Taller1/ImagingAndVideo/WolvCar.png');
6link> imgOriginal = loadImage('/vc/docs/sketches/Taller1/ImagingAndVideo/WolvCar.png');
7link> }
8link>
9link> function setup() {
10link> createCanvas(780, 500);
11link> pixelDensity(1);
12link> img.resize(390,500);
13link> img.loadPixels();
14link> for (var y = 0; y < img.height; y++) {
15link> for (var x = 0; x < img.width; x++) {
16link> var index = (x + y * img.width) * 4;
17link> var r = img.pixels[index + 0];
18link> var g = img.pixels[index + 1];
19link> var b = img.pixels[index + 2];
20link> var luma = r * .299 + g * .587 + b * .0114;
21link> img.pixels[index + 0] = luma;
22link> img.pixels[index + 1] = luma;
23link> img.pixels[index + 2] = luma;
24link> }
25link> }
26link> img.updatePixels();
27link> image(img, 390, 0);
28link> }
29link>
30link> function draw() {
31link> imgOriginal.resize(390,500);
32link> image(imgOriginal, 0, 0);
33link> imgOriginal.loadPixels();
34link> for (var y = 0; y < imgOriginal.height; y++) {
35link> for (var x = 0; x < imgOriginal.width; x++) {
36link> var index = (x + y * imgOriginal.width) * 4;
37link> var r = imgOriginal.pixels[index + 0];
38link> var g = imgOriginal.pixels[index + 1];
39link> var b = imgOriginal.pixels[index + 2];
40link> var bw = (r + g + b) / 3;
41link> imgOriginal.pixels[index + 0] = bw;
42link> imgOriginal.pixels[index + 1] = bw;
43link> imgOriginal.pixels[index + 2] = bw;
44link> }
45link> }
46link> imgOriginal.updatePixels();
47link> }
Luego realizamos la conversion de un video a escala de grises y obtenemos el siguiente resultado:
Hacer click para correr el video.
1link> let fingers;
2link>
3link> function setup() {
4link> createCanvas(780, 240);
5link> fingers = createVideo(['/vc/docs/sketches/fingers.mov',
6link> '/vc/docs/sketches/fingers.webm']);
7link> fingers.hide();
8link> }
9link>
10link> function draw() {
11link> image(fingers, 460, 0);
12link> filter(GRAY);
13link> image(fingers, 0, 0);
14link> }
15link>
16link> function mousePressed() {
17link> fingers.loop();
18link> background(255);
19link> }