viernes, marzo 26, 2010

Detección de fronteras

Casualmente he logrado hacer un detector de fronteras para imágenes en niveles de gris (extensible para imágenes en cualquier otro formato de color como RGB).

En principio estaba intentando hacer un simple filtro de suavizado (o desenfoque) gaussiano como primer paso para la realización de un filtro de Wiener de enfoque gaussiano dada una imagen de entrada desenfocada (debido a que el desenfoque producido por una cámara puede ser modelado mediante una función gaussiana).
No obstante, por error, he logrado realizar un detector de fronteras mediante un simple filtrado con el que se puede controlar tanto la resolución o densidad de bordes como la anchura de los mismos (mediante la parametrización de la varianza y tamaño del bloque espacial convolucionable).

Es una solución muy simple, rápida, eficiente y elegante basada, como digo, en un filtrado. La clave de que esto haya podido ser así, he observado que se asienta sobre la normalización del volumen que encierra el área gaussiana representada en la respuesta espacial del bloque convolucionable. Esta normalización se produce por desplazamiento en altitud de la respuesta espacial del filtro, lo que se traduce en un filtrado pasa-alta con coeficientes negativos y otro pasa-baja con coeficientes positivos. A partir de haber hecho esto (pensado como mero paso para un correcto promediado que no alterase los niveles de gris de la imagen original) pude observar sin más la detección de fronteras.

A continuación adjunto unos ejemplos y un par de respuestas espaciales de los filtros, así como el código de la función implementada en MatLab.


Imagen original 1.

Fronteras detectadas por filtrado de la imagen 1 (var = 2 dim = 10).

Imagen original 2.

 Fronteras detectadas por filtrado de la imagen 2 (var = 4 dim = 12).

 Respuesta espacial del filtro aplicado a la imagen 2.

 Imagen original 3.

 Fronteras detectadas por filtrado de la imagen 3 (var = 1 dim = 10).

Respuesta espacial del filtro aplicado a la imagen 3.


% Detector de fronteras
% Autor: Iván López Espejo
%
% Función para la detección de fronteras basada en filtrado gaussiano.
%
% Y = detBordes(x,var,dim)
%
% Donde en 'Y' se almacena la matriz imagen resultado, siendo 'x' la matriz
% imagen en niveles de gris de entrada sobre la que queremos aplicar el
% filtrado. Por otro lado, 'var' es la varianza de la función gaussiana 2-D
% (a mayor varianza, mayor consideración de figuras como borde (mayor
% densidad de bordes)) y 'dim' es el tamaño, en píxels, del área del filtro
% con el que convolucionaremos (promediaremos). A mayor 'dim',
% representación de las fronteras como líneas de mayor grosor.

function y = detBordes(x,var,dim)

% Generación de la respuesta espacial del filtro gaussiano.
H = zeros(dim,dim);
for j = 1:1:dim
    for k = 1:1:dim
        H(j,k) = exp(-(( ((j)^2) + ((k)^2) - 2*(round(dim/2))*(j) - 2*(round(dim/2))*(k) + (round(dim/2)^2) + (round(dim/2)^2) )/(2*var)));
    end
end
% Normalización del volumen del filtro en el dominio espacial.
k = (1-sum(sum(H)))/(dim^2);
H = H + k;
% Representación de la magnitud de la respuesta espacial del filtro.
surf(H)
% Filtrado mediante convolución en el dominio espacial y representación.
y = filter2(H,x);
figure
subplot(2,1,1), imshow(x), title('Imagen original');
subplot(2,1,2), imshow(y), title('Imagen filtrada');