La detección de discontinuidades % Se lee la imagen: I=imread('cuadrad.jpg'); % La cual presentará puntos que se desean discriminar, producto a la presencia de ruido >> II=imnoise(I,'salt & pepper',0.01); % Se define la máscara para detectar los puntos blancos: >> w=[-1, -1, -1; -1, 8, -1; -1, -1, -1] w = -1 -1 -1 -1 8 -1 -1 -1 -1 % Se aplica el filtro >> III=imfilter(II, w,'symmetric'); Como se puede apreciar los puntos blancos sobre negro están bien definidos (ver figura a continuación), pero los negros sobre blanco se presentan como cuadrados, lo cual significa que lo que se ha hecho es detectar los bordes de los puntos negros. Para comprobar ello se complementa la imagen II y se aplica el mismo filtro. >> IV=imcomplement(II); % Complemento de la imagen >> V=imfilter(IV, w,'symmetric');
Los puntos negros (antes blancos) siguen mostrándose como cuadrados. Nótese como también se han detectado los bordes, porque en esta figura están bien definidos (alto contraste). Se detectan los puntos más significativos aplicando la condición umbral, por lo que los detalles en gris ya no se representan >> VI=abs(imfilter(II, w,'symmetric'))>=255; % Umbral = 255 Se aplica una máscara donde no se consideren los píxeles diagonales >> ww=[0, -1, 0; -1, 4, -1; 0, -1, 0] % Los píxeles diagonales son cero ww = 0 -1 0 -1 4 -1 0 -1 0
Y se aplica el filtro con la nueva máscara y el umbral. La figura resultante muestra que se ha logrado una selección más precisa de los puntos de la imagen. >>VII=abs(imfilter(II, ww,'symmetric'))>=255;
Si se desean detectar los puntos negros se invierte la máscara: >> www=-ww www = 0 1 0 1 -4 1 0 1 0 Y se aplica el filtro >> VIII=abs(imfilter(II, www,'symmetric'))>=255; Para aplicar una selección más precisa de los puntos se deben eliminar los cuadrados o cualquier píxel que tenga alguna conexión con otro de su entorno. El siguiente programa determina los valores medios de intensidad después de aplicar filtros de detección de líneas en diferentes direcciones % Se definen las máscaras w(:,:,1)=[-1, -1, -1; 2, 2, 2; -1, -1, -1]; % 0o w(:,:,3)=rot90(w(:,:,1)); % 90o w(:,:,2)=[-1, -1, 2; -1, 2, -1; 2, -1, -1]; % 45o w(:,:,4)=rot90(w(:,:,2)); % -45o
% Se calcula la media for i=1:4 II(:,:,i) = imfilter(I,w(:,:,i),'symmetric','same'); maxima_intensidad(1,i)=mean2(II(:,:,i)) figure;imshow(II(:,:,i)); end |
lo cual puede ser un indicador de la dirección preferente que tienen las líneas en la imagen. En las figuras que se muestran a continuación se presenta el resultado de aplicar el programa  máxima_intensidad(0o)=11.36 | 
máxima_intensidad(45o)=7.17 | 
máxima_intensidad(90o)=8.47 |  máxima_intensidad(-45o)=7.22 |
Como se puede apreciar,las líneas predominantes son las horizontales (0o). Método de Roberts: Es uno de los más antiguos, simples y menos utilizado de los métodos de detección de bordes en la actualidad, a pesar de que su sencillez en la implementación es atrayente para las aplicaciones hardware de alta velocidad.
A continuación se muestra un programa que aplica cuatro posibles combinaciones (45, 135, -45, -135) de máscaras para la aplicación de la detección de bordes basado en el método de Roberts.
>> II45 = imfilter(I,[1 0; 0 -1],'symmetric'); >> II45p = imfilter(I,[-1 0; 0 1],'symmetric'); >> II135 = imfilter(I,[0 1;-1 0],'symmetric'); >> II135p = imfilter(I,[0 -1;1 0],'symmetric');
Se puede obtener la combinación de los aportes de los bordes en las cuatro direcciones a través de la suma, ello es >> sum1=imadd(II45, II45p); >> sum2=imadd(II135, II135p); >> III=imadd(sum1, sum2); 
III |
Un método alternativo para realizar las operaciones anteriores es a través del uso de las funciones edge e imlincomb. No necesariamente se combinan el resultado de aplicar todas las máscaras, puede seleccionarse el mayor valor devuelto entre ellas, sustituyendo por este el píxel objeto de estudio. Adicionalmente, se puede aplicar determinado umbral a la imagen resultante. Método de Prewitt: Enfatiza los bordes horizontales y verticales como resultado de aplicar el gradiente para obtener las matrices que constituirán las máscaras. Estas se define por % Detección de bordes horizontales >> w=fspecial('prewitt') w = 1 1 1 0 0 0 -1 -1 -1 % Detección de bordes verticales >> w=w' w = 1 0 -1 1 0 -1 1 0 -1 >> II=imfilter(I, w, 'symmetric', 'same'); % Se aplica filtro para la detección de los bordes verticales Una alternativa es la utilización de la función edge (ver la relación entre la función edge e imfilter para obtener los bordes). Por ejemplo, si se desean detectar los bordes horizontales se puede utilizar >> III=edge(I,'prewitt', [],'horizontal'); La diferencia fundamental entre imfilter y edge es que a este último se le puede definir un umbral para representar los bordes ( a imfilter se le puede incorporar este umbral a través de un condicionante, como se muestra a continuación en el ejemplo del método de Sobel) y aplicar el método de Prewitt en ambas direcciones de forma simultánea. Método de Sobel: Es similar al método de Prewitt, sólo que en este caso las máscaras se definen por: >> w=fspecial('sobel') w = % Máscara horizontal 1 2 1 0 0 0 -1 -2 -1 >> w=w' % Máscara vertical w = 1 0 -1 2 0 -2 1 0 -1 Se pueden utilizar para la detección de bordes basado en las máscaras anteriores las funciones edge o imfilter. Existen dos máscaras adicionales (a +45o y -45o) para detectar bordes basado en el método de Sobel, que no pueden calcularse con la función edge. Para ello se aplica: % Definición de máscaras >> w45=[-2, -1, 0; -1, 0, 1; 0, 1, 2] w45 = -2 -1 0 -1 0 1 0 1 2 >> w45p=rot90(w45) w45p = 0 1 2 -1 0 1 -2 -1 0 % Filtrar la imagen con un criterio de umbral II=imfilter(double(I), w45p, 'symmetric'); t = 0.3*max(abs(II(:))); IIp= II >= t; La conversión a tipo double se realiza para mantener la precisión en los cálculos antes de realizar la aproximación de imfilter. El siguiente programa determina los bordes en las cuatro orientaciones, aplicando determinado umbral, y las combina % Se define el umbral umbral=0.3;
% Se definen las máscaras w(:,:,1)=fspecial('sobel'); w(:,:,3)=rot90(w(:,:,1)); w(:,:,2)=[-2, -1, 0; -1, 0, 1; 0, 1, 2]; w(:,:,4)=rot90(w(:,:,2)); % Se aplica Sobel en las cuatro orientaciones, con umbral for i=1:4 II(:,:,i) = imfilter(double(I),w(:,:,i),'symmetric','same'); II(:,:,i) = II(:,:,i) >= umbral.*max(abs(II(:))); figure;imshow(II(:,:,i)); end % Imagen resultante II=imlincomb(1,II(:,:,1), 1,II(:,:,2), 1,II(:,:,3), 1,II(:,:,4)); figure; imshow(II); |
A continuación se muestra el resultado de la deteción de bordes para diferentes umbrales Detección de cruces por cero en el filtro laplaciano: Como se ha visto en las aplicaciones de filtros, el filtro laplaciano se utiliza para mejorar la nitidez de la imagen por su capacidad de captar altas discontinuidades como resultado de aplicar la segunda derivada. Adicionalmente, detectar un borde es detectar el cruce por cero de la segunda derivada de la imagen, como se ha tratado en gradiente. Considerando lo anterior, se puede entonces detectar bordes al detectar los cruces por cero del filtro laplaciano, para ello se puede utilizar la siguiente función: >> II=edge(I, 'zerocross', 0.3, fspecial('laplacian',0.01)); El resultado de aplicarlo a una imagen se muestra en las siguientes figuras  fspecial('laplacian',0.01) | 
fspecial('laplacian',0.99) |
Laplaciana de la gausiana: Como se ha expuesto en la sección de filtros, es el resultado de aplicar la segunda derivada a una función gausiana (de ahí su nombre laplaciano de la gausiana). Existen diferentes formas para emular la segunda derivada representada a través de este método, para ello debe existir un centro positivo y un entorno de valores negativos que posteriormente se aproximan a cero en la medida que se aleja del centro de la máscara. Debe cumplirse la condición de que la suma de los coeficientes sean cero para que cuando el nivel de gris sea semejante, el filtro devuelva cero (fondo o background de la imagen). A continuación se muestran algunas máscaras para aplicar el filtro laplaciano cuando se varía la desviación estándar (sigma).  sigma=0.4 >> -fspecial('log', 5, .4) ans = -0.2475 -0.2475 -0.2479 -0.2475 -0.2475 -0.2475 -0.3545 -1.2336 -0.3545 -0.2475 -0.2479 -1.2336 10.3145 -1.2336 -0.2479 -0.2475 -0.3545 -1.2336 -0.3545 -0.2475 -0.2475 -0.2475 -0.2479 -0.2475 -0.2475 | 
sigma=0.5 >> -fspecial('log', 5, .5) ans = -0.0448 -0.0468 -0.0564 -0.0468 -0.0448 -0.0468 -0.3167 -0.7146 -0.3167 -0.0468 -0.0564 -0.7146 4.9048 -0.7146 -0.0564 -0.0468 -0.3167 -0.7146 -0.3167 -0.0468 -0.0448 -0.0468 -0.0564 -0.0468 -0.0448 | 
sigma=0.6 >> -fspecial('log', 5, .6) ans = -0.0056 -0.0192 -0.0483 -0.0192 -0.0056 -0.0192 -0.2758 -0.2426 -0.2758 -0.0192 -0.0483 -0.2426 2.4429 -0.2426 -0.0483 -0.0192 -0.2758 -0.2426 -0.2758 -0.0192 -0.0056 -0.0192 -0.0483 -0.0192 -0.0056 |
Nótese como mientras menor es el valor de sigma, más alta y estrecha será la campana, lo cual es útil para discriminar bordes más estrechos. Lo anterior puede ser una desventaja, puesto que mientras menor es el valor de sigma, más bordes se detectarán, tal y como muestran las siguientes figuras  Imagen original (I) | 
>> II=edge(I, 'log', [], 3); imshow(II) | 
>> III=edge(I, 'log', [], 2); imshow(III) |  >> IV=edge(I, 'log', [], 1); imshow(IV) |
Aunque el Laplaciano responde a transiciones en la intensidad de la imagen, se emplea en pocas ocasiones en la práctica para la detección de bordes, ello es debido a que un operador de segunda derivada es muy sensible a la presencia de ruido y puede producir bordes dobles. La detección del contorno de una forma en la imagen es el proceso de unión, en su forma más simple, de bordes previamente detectados, tal y como se describe en detección básica de contornos. Un programa en Matlab que permite seleccionar píxeles, basado en bordes para obtener un contorno, se muestra a continuación. mag= 20; %Umbral de magnitud ang=45*pi/180; %Umbral de dirección
% Se definen máscaras wx=fspecial('prewitt'); wy=wx'; % Se aplican filtros gx=imfilter(I,wx); gy=imfilter(I,wy);
% Obtiene la magnitud del gradiente II=abs(gx)+abs(gy);
%Obtiene dirección III=atan(double(gy./gx));
[m,n]=size(II); IV=zeros(m,n); % Imagen dependiente de la magnitud for i=1:m for j=1:n if (II(i,j)> mag) IV(i,j)=1; end end end IV=uint8(III*255);
V=zeros(m,n); % Imagen dependiente de la dirección for i=1:m for j=1:n if (abs(III(i,j))>= ang) V(i,j)=1; end end end V=uint8(III*255); |
En este caso se utilizan las máscaras de Prewitt, pero pueden utilizarse otros tipos de máscara, sustituyendo wx y wy en el programa. |