Mostrando las entradas con la etiqueta Procesamiento de imágenes. Mostrar todas las entradas
Mostrando las entradas con la etiqueta Procesamiento de imágenes. Mostrar todas las entradas

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)

martes, 10 de mayo de 2016

Detección de bordes en imágenes con MATLAB


La detección de bordes en MATLAB es una de las operaciones de procesamiento de imágenes más común y básica, cuyo objetivo es determinar las regiones en una imagen que presentan cambios significativos de intensidad en los pixeles que la conforman.

Recuerde que una imagen en escala de grises puede expresarse como una función bivariable f(x, y), donde x e y son las coordenadas de ubicación (fila, columna). Así una forma sencilla de detectar los bordes en una imagen es utilizar el gradiente, mismo que determina la tasa de variación en ambas direcciones de una función bivariable, dado por:

$$ \nabla f = \begin{bmatrix} \frac{\partial f}{\partial x} \\ \frac{\partial f}{\partial y} \end{bmatrix} $$

Aunque claro, para nuestros propósitos lo que usaremos es la magnitud del gradiente:

$$ |\nabla f| = \sqrt{ \left(\frac{\partial f}{\partial x}\right)^2 + \left(\frac{\partial f}{\partial y}\right)^2} $$

Así, para determinar los bordes en una imagen, o lo que sería lo mismo: localizar las regiones en donde la magnitud del gradiente es mayor, podemos utilizar la función gradient, vea el siguiente ejemplo:

X = imread('Lenna.png');
XG = rgb2gray(X);
[dx,dy] = gradient(double(XG));
M = uint8(sqrt(dx.^2+dy.^2));
imshow(M);



MATLAB cuenta con una función especial para detectar bordes en una imagen: edge, la cual utiliza operadores matriciales especiales que transforman una imagen en escala de grises en una imagen binarizada con bordes resaltados.

X = imread('Lenna.png');
XG = rgb2gray(X);
XB = edge(XG,'sobel');
imshow(XB);


jueves, 24 de julio de 2014

Leer y mostrar imágenes con MATLAB


De forma habitual, se utilizan las funciones del Image Processing Toolbox de MATLAB para importar, procesar y visualizar imágenes, más concretamente las funciones imread e imshow para leer y mostrar imágenes respectivamente. Pero además de las anteriores, puede utilizarse algunas funciones que forman parte del núcleo de MATLAB para dichas tareas, tales como importdata e image / imagesc, evidentemente pueden presentar ciertos inconvenientes, pero representan una alternativa en el caso de no contar con el toolbox requerido.

Leer una imagen con imread

La sintaxis de la función imread es muy sencilla, a saber:

>> imread('nombre_img','formato');

Donde nombre_img es el nombre de la imagen o bien la ruta completa de la imagen en el caso que no se encuentre en el Current Folder, formato es justamente eso: el tipo de imagen que vamos a leer (PNG, JPG, GIF, TIFF, etc...), es común omitir el segundo argumento e incluir, claro, la extensión del archivo en el nombre del mismo. Para ejemplificar utilizaré una imagen cuyo nombre es "img", en formato jpg y que se encuentra almacenada en el directorio actual de trabajo, luego para leer la imagen se tendría que hacer lo que a continuación se muestra:

>> X=imread('img.jpg');

Al teclear la instrucción anterior MATLAB crea una matriz X en la cual se guarda  la información de cada uno de los píxeles que componen la imagen. Podemos verificarlo utilizando el comando whos como sigue:

>> whos X
  Name        Size                Bytes  Class    Attributes

  X         300x400x3            360000  uint8       

Revisando lo que MATLAB nos devuelve podemos identificar que la matriz creada está compuesta de 300 filas, 400 columnas y tres capas o planos correspondientes al modelo de color RGB (Red, Green, Blue), es decir, cada capa corresponde a la intensidad de cada uno de los colores. Además, la clase de datos utilizados son uint8 (entero sin signo de 8 bits) cuyo rango es de 0 a 255.


Mostrar una imagen con imshow

Una vez se ha leído y almacenado la imagen podemos utilizar la función imshow para visualizarla, la sintaxis de esta función es:

>> imshow(IMG);

Donde IMG es la matriz en la cual se ha guardado la información referente a la imagen. Para nuestro caso:

>> imshow(X);



Utilizando importdata e imagesc

Además de imread, es posible leer una imagen utilizando la función importdata, la sintaxis es:

>> X=importdata('nombre_img');

Para el ejemplo que hemos utilizado:

>> X=importdata('img.jpg');

Una vez almacenada la imagen podemos utilizar la función imagesc para mostrar la imagen:

>> imagesc(X);



Y como tal, el objetivo de esta entrada era simplemente adquirir y visualizar las imágenes. En posteriores entradas se hará referencia a algunas operaciones básicas que pueden aplicarse a una imagen, o mejor dicho, a la matriz que guarda la información de la misma.

sábado, 8 de marzo de 2014

Crear imágenes con degradado (Lineal y Radial)


Será ésta la primera entrada del blog orientada al procesamiento de imágenes, por lo cual es aún muy básica.

Vamos a crear cuatro tipo de degradados (lineal de derecha a izquierda, lineal de izquierda a derecha, radial de adentro hacia afuera y radial de afuera hacia adentro) en imágenes en escala de grises, utilizando ciclos for simples y anidados.

Lineal de derecha izquierda

Definimos primeramente las variables ancho y alto que determinarán el tamaño de la imagen. Con el ciclo for creamos la matriz A, agregando cada elemento de ella en una ejecución, como puede observarse la variación de valores se da sólo en una dirección. Recuerde que el tipo de dato comúnmente utilizado en imágenes es el uint8 (entero sin signo de 8 bits) y por ello debe hacerse la conversión explícita dado que MATLAB por defecto considera como tipo double cualquier valor numérico introducido. Se especifica que el valor tomado debe ser ancho-i para que mientras i aumenta el valor decrezca. Tome en cuenta que los valores próximos a 0 tienden a ser negros y que entre más próximos a 255 serán en un tono más claro o blanco. Finalmente, la instrucción imshow permite mostrar la imagen en una ventana.

ancho = 250;
alto = 250;
for i=1:ancho
    A(1:alto,i)=uint8(ancho-i);
end
imshow(A);



Lineal de izquierda a derecha


ancho = 250;
for i=1:ancho
    A(1:alto,i)=uint8(i);
end
imshow(A);




Radial de adentro hacia afuera

Como en el caso lineal se definen las variables ancho y alto, pero ahora se necesitarán dos ciclos for anidados dado que la variación será en ambas direcciones. El punto de referencia no será ninguno de los extremos, sino el punto medio dado por $ ancho/2 $ y $ alto/2 $. La variación del valor asignado depende de la variable "distr", que es la distancia desde el punto medio a cada uno de los puntos o pixeles que componen la imagen, o en términos más amables:

$$ \sqrt{(ancho/2\,-\,i)^2+(alto/2\,-\,j)^2} $$

ancho = 250;
alto = 250;
for i=1:ancho
    for j=1:alto
        distr = sqrt((ancho/2-i)^2+(alto/2-j)^2);
        A(j,i)=uint8(distr);
    end
end
imshow(A);



Radial de afuera hacia adentro


ancho = 250;
alto = 250;
for i=1:ancho
    for j=1:alto
        distr = sqrt((ancho/2-i)^2+(alto/2-j)^2);
        A(j,i)=uint8(0.5*ancho-distr);
    end
end
imshow(A);