jueves, 4 de agosto de 2016

Convertir una imagen a escala de grises


La manera rápida


Si cuenta con el Image Processing Toolbox MATLAB dispone de una función llamada rgb2gray que permite convertir una imagen RGB a una en escala de grises, ej:

X = imread('lenna.png');
XG = rgb2gray(X);
imshow(XG);

Imagen original

Imagen en escala de grises

Como puede notar es muy simple, sólo necesita pasar como argumento la matriz que contiene la información de la imagen RGB.

La otra, un poco de algoritmos...


Si no dispone del toolbox de procesamiento de imagen, entonces puede implementar su propio algoritmo para realizar dicha tarea.

El algoritmo más simple es el del promedio (average method), que consiste en calcular el promedio de los canales RGB y asignarlos al pixel correspondiente en la imagen de grises. Por ejemplo dada una matriz de MxNx3 correspondiente a una imagen, el pixel de la matriz de grises en la posición (i, j) se calcula como sigue:

$$ XG_{i,j} = \frac{X_{i,j,1} + X_{i,j,2} + X_{i,j,3}}{3} $$

Donde XG es la matriz de grises, de dimensiones MxN. Y Xi, j, 1Xi, j, 2 y Xi, j, 3 las componentes correspondientes a los canales R, G y B, respectivamente.

Implementando esto en MATLAB:

X = imread('lenna.png');
XG = uint8(mean(X,3));
imshow(XG);

¿Bastante simple verdad?, lo que hacemos es hacer el promedio en la dimensión 3, es decir, para cada pixel. La conversión a entero de 8-bits (uint8) es necesaria para que se muestre correctamente cuando utilizamos imshow, dado que la función mean devuelve una matriz de tipo double.

Otro método para convertir a escala de grises es el de la luminosidad (luminosity method) que consiste en asignar una proporción específica (ponderada) a cada uno de los canales, dependiendo la aportación de estos. De hecho MATLAB utiliza este tipo de transformación en la función rgb2gray. Con este método, la expresión para calcular el valor de un pixel de grises viene dado por:

XGi, j = 0.2889 Xi, j, 1 + 0.5870 Xi, j, 2 + 0.1140 Xi, j, 3

LLevando esto a un código MATLAB:

X = imread('img/lenna.png');
k = [0.2989 0.5870 0.1140];
XG = X(:,:,1)*k(1) + X(:,:,2)*k(2) + X(:,:,3)*k(3);
imshow(XG)

4 comentarios:

  1. hola una pregunta de donde sales estos valores

    k = [0.2989 0.5870 0.1140];

    ResponderBorrar
    Respuestas
    1. El ojo percibe distintas intesidades de luz en función del color que se observe, esto es debido a la respuesta del ojo al espectro visible , por esa razón el cálculo del equivalente blanco y negro (escala de grises o luminancia) de la imagen debe realizarse como una media ponderada de las distintas componentes de color de cada pixel. Esas medidas corresponden a esos números, 0,2989 para el Rojo, 0,5870 para el verde y 0,1140 para el azul

      Borrar
    2. ¿Podrías citar la fuente de la cuál obtuviste esos valores por favor?

      Borrar
  2. El ojo percibe distintas intesidades de luz en función del color que se observe, esto es debido a la respuesta del ojo al espectro visible , por esa razón el cálculo del equivalente blanco y negro (escala de grises o luminancia) de la imagen debe realizarse como una media ponderada de las distintas componentes de color de cada pixel. Esas medidas corresponden a esos números, 0,2989 para el Rojo, 0,5870 para el verde y 0,1140 para el azul

    ResponderBorrar