martes, 29 de marzo de 2011

Procesamiento digital de imágenes

El procesamiento digital de imágenes es el conjunto de técnicas que se aplican a las imágenes digitales con el objetivo de mejorar la calidad o facilitar la búsqueda de información.


TÉCNICAS DE FILTRADO

Se trata de métodos para resaltar o suprimir, de forma selectiva, información contenida en una imagen a diferentes escalas espaciales, para destacar algunos elementos de la imagen, o también para ocultar valores anómalos. Otra técnica para aislar información correspondiente a diferentes escalas espaciales es la transformada de Fourier que, por su complejidad, no se verá en este curso.

El proceso de filtrado consiste en la aplicación a cada uno de los pixels de la imagen de una matriz de filtrado de tamaño NxN (generalmente de 3x3 aunque puede ser mayor) compuesta por números enteros y que genera un nuevo valor mediante una función del valor original y los de los pixels circundantes. El resultado final se divide entre un escalar, generalmente la suma de los coeficientes de ponderación. Los filtros se pueden expresar mediante una ecuación.



 Filtros de paso bajo
Su objetivo es suavizar la imagen, son útiles cuando se supone que la imagen tiene gran cantidad de ruido y se quiere eliminar. También pueden utilizarse para resaltar la información correspondiente a una determinada escala (tamaño de la matriz de filtrado); por ejemplo en el caso de que se quiera eliminarla variabilidad asociada a los  tipos de cubierta presentes en la imagen uniformizando de esta manera su respuesta. Existen varias posibilidades:

Filtro de la media; asigna al pixel central la media de todos los pixeles incluidos en la ventana. La matriz de filtrado estaría compuesta por unos y el divisor sería el número total de elementos en la matriz.

Código en MatLab:




[nombre_archivo,path]=uigetfile({'*.jpg';'*.gif';'*.jpeg'},'Seleccione un archivo');
imagen=imread([path,nombre_archivo]);
imagen_gris=double(rgb2gray(imagen));

imagen_media=imagen_gris;
[f,c] = size(imagen_gris);
for i=2:f-1
        for j=2:c-1
          imagen_media(i,j)=(imagen_media(i-1,j-1)+imagen_media(i-1,j+1)+
          imagen_media(i-1,j)+imagen_media(i+1,j-1)+imagen_media(i+1,j+1)+
          imagen_media(i+1,j)+imagen_media(i,j-1)+imagen_media(i,j)+imagen_media(i,j+1)) / 9;
        end
end
imshow(uint8(imagen_media));




Filtro de la mediana: Tiene la ventaja de que el valor final del pixel es un valor real presente en la imagen y no un promedio, de este modo se reduce el efecto borroso que tienen las imágenes que han sufrido un filtro de media. Además el filtro de la mediana es menos sensible a valores.


Código en MatLab:

[nombre_archivo,path]=uigetfile({'*.jpg';'*.gif';'*.jpeg'},'Seleccione un archivo');
imagen=imread([path,nombre_archivo]);
imagen_gris=double(rgb2gray(imagen));
imagen_mediana=imagen_gris;
[f,c] = size(imagen_gris);
for i=2:f-1
        for j=2:c-1
           v(1)=imagen_mediana(i-1,j-1);
           v(2)=imagen_mediana(i-1,j+1);
           v(3)=imagen_mediana(i-1,j);
           v(4)=imagen_mediana(i+1,j-1);
           v(5)=imagen_mediana(i+1,j+1) ;      
           v(6)=imagen_mediana(i+1,j);
           v(7)=imagen_mediana(i,j-1);
           v(8)=imagen_mediana(i,j);
           v(9)=imagen_mediana(i,j+1);
           
           y=0;
           for h=1:9
             a=9999999;
            for r=h:9
             if v(r)<a
                 a=v(r);
                 y=r;
             end
            end
            v(y)=v(h);
           v(h)=a;
           end
           imagen_mediana(i,j)=v(5);           
        end
end
imshow(uint8(imagen_mediana));


Filtros de paso alto
 Filtros para la detección de bordes
Los bordes de una imagen digital se pueden definir como transiciones entre dos regiones de niveles de gris significativamente distintos. Suministran una valiosa información sobre las  fronteras de los objetos y puede ser utilizada para segmentar la imagen, reconocer objetos, etc. La mayoría de las técnicas para detectar bordes emplean operadores locales basados en distintas  aproximaciones discretas de la primera y segunda derivada de los niveles de grises de la imagen.

Filtro de Sobel: Técnicamente es un operador diferencial discreto que calcula una aproximación al gradiente de la función de intensidad de una imagen.                                                                                                                                                                                  Formula                                                                                                     Matemáticamente, el operador utiliza dos kernels de 3×3 elementos para aplicar convolución a la imagen original para calcular aproximaciones a las derivadas, un kernel para los cambios horizontales y otro para las verticales. Si definimos \mathbf{A} como la imagen original y \mathbf{G_x} y \mathbf{G_y} son los dos kernels que representan para cada punto las aproximaciones horizontal y vertical de las derivadas de intensidad, el resultado es calculado como:




\mathbf{G_x} = \begin{bmatrix} 
+1 & 0 & -1 \\
+2 & 0 & -2 \\
+1 & 0 & -1 
\end{bmatrix} * \mathbf{A}
\quad \mbox{and} \quad 
\mathbf{G_y} = \begin{bmatrix} 
+1 & +2 & +1 \\
0 & 0 & 0 \\
-1 & -2 & -1 
\end{bmatrix} * \mathbf{A}
En cada punto de la imagen, los resultados de las aproximaciones de los gradientes horizontal y vertical pueden ser combinados para obtener la magnitud del gradiente, mediante:
\mathbf{G} = \sqrt{ \mathbf{G_x}^2 + \mathbf{G_y}^2 }
Con esta información, podemos calcular también la dirección del gradiente:
\mathbf{\Theta} = \operatorname{arctan}\left({ \mathbf{G_y} \over \mathbf{G_x} }\right)
donde, por ejemplo, Θ es 0 para bordes verticales con puntos más oscuros al lado izquierdo.

Código en MatLab:

[nombre_archivo,path]=uigetfile({'*.jpg';'*.gif';'*.jpeg'},'Seleccione un archivo');
imagen=imread([path,nombre_archivo]);
imagen_gris=double(rgb2gray(imagen));
imagen_sobel=imagen_gris;
[f,c] = size(imagen_gris);
for i=2:f-1
        for j=2:c-1
        gx=imagen_gris(i-1,j-1)+2*imagen_gris(i-1,j)+imagen_gris(i-1,j+1)-imagen_gris(i+1,j-1)-2*imagen_gris(i+1,j)-imagen_gris(i+1,j+1);
        gy=imagen_gris(i-1,j-1)-imagen_gris(i-1,j+1)+2*imagen_gris(i,j-1)-2*imagen_gris(i,j+1)+imagen_gris(i+1,j-1)-imagen_gris(i+1,j+1);
        imagen_sobel(i,j)=sqrt((gx)^2+(gy)^2);
        end
end
imshow(uint8(imagen_sobel));