% bordet.m
% Script de MathLab para detectar el borde de las imagenes.

% Introduccion
%%%%%%%%%%%%%%%
clc
disp('   DETECTOR DE BORDES PARA MATHLAB');
disp('   ======== == ====== ==== =======');
disp(' ');
disp('Imagenes del MathLab: flujet, spine, gatlin2, clown, earth, mandrill');
disp(' ');
disp(' ');

% Pregunta si quiere borrar todas las imagenes y variables
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
sBorrar = input('Desea borrar todos los datos anteriores (S/N)? ', 's');
disp(' ');
if (sBorrar == 'S') | (sBorrar == 's')
	clear;
end

% Entrada de la imagen
%%%%%%%%%%%%%%%%%%%%%%%
sArchivo = input ('Ingrese el nombre de la imagen (*.mat): ', 's');
load (sArchivo)

% Entrada de la tolerancia de la deteccion de bordes
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
nTolerancia= input ('Ingrese la tolerancia para detectar los bordes (0 = sin tolerancia, 15 = mucha tolerancia): ');

% Pregunta si quiere ativar la correccion de zonas constantes
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
sCorrect = input('Desea evitar que los intervalos constantes se detecten como bordes (S/N)? ', 's');

% Crea una nueva figura y muestra la imagen a la que se le detectarán los bordes
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
clc
figure
image(X), colormap(copper)
disp('MOSTRANDO IMAGEN ORIGINAL. Presione cualquier tecla para continuar ...');
pause

% Comienza a detectar los bordes, creando otra matriz con la imagen de los mismos
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
clc
disp(' CALCULANDO LOS BORDES. Espere por favor ...');
[m,n]=size(X);										% obtiene el tamaño de la matriz original
mBorde=ones(m,n);									% Crea la matriz borde iniciada en 1 (1 es Negro)
for i = 2: 1: m-1									% Recorre la matriz en busca de los bordes
	for j = 2: 1: n-1
		if (sCorrect == 'S') | (sCorrect == 's')	% Si esta activada la correccion ...
			% Primero se fija que los valores que rodean al elemento actual y dicho elemento sean (al menos uno)
			%   distintos entre sí (dependiendo de la tolerancia). Esto evita que en los intervalos que la funcion
			%   es constante nos detecte un borde, ya que en ese caso, tambien cumple la ecuacion de Laplace pero no
			%   es un borde en realidad.
			if (abs(X(i+1, j) - X(i, j-1)) > nTolerancia) | (abs(X(i+1, j) - X(i, j)) > nTolerancia) | (abs(X(i+1, j) - X(i, j+1)) > nTolerancia) | (abs(X(i+1, j) - X(i-1, j)) > nTolerancia) | (abs(X(i-1, j) - X(i, j+1)) > nTolerancia) | (abs(X(i-1, j) - X(i, j)) > nTolerancia) | (abs(X(i-1, j) - X(i, j-1)) > nTolerancia) | (abs(X(i-1, j) - X(i+1, j)) > nTolerancia) | (abs(X(i, j+1) - X(i, j)) > nTolerancia) | (abs(X(i, j+1) - X(i, j-1)) > nTolerancia) | (abs(X(i, j+1) - X(i+1, j)) > nTolerancia) | (abs(X(i, j+1) - X(i-1, j)) > nTolerancia) | (abs(X(i, j-1) - X(i, j+1)) > nTolerancia) | (abs(X(i, j-1) - X(i, j)) > nTolerancia) | (abs(X(i, j-1) - X(i+1, j)) > nTolerancia) | (abs(X(i, j-1) - X(i-1, j)) > nTolerancia)
				% Calcula el elemento actual aplicando la ecuacion de Laplace
				nElemento = X(i+1, j) + X(i, j-1) + X(i, j+1) + X(i-1, j) - 4 * X(i, j);
				if (abs(nElemento) <= nTolerancia)		% Para que cumpla con Laplace el elemento debe ser
														%   igual a cero, pero como se trata de una funcion
														%   discrete es muy comun que no de exactamente cero.
														%   Es por esto que uso la tolerancia.
					mBorde(i, j) = 256;	 				% Si encontró el borde, le asigna un color alto (256 es blanco)
				end % if abs(nElemento) <= nTolerancia
			end % if LARGO
		else
			% Calcula el elemento actual aplicando la ecuacion de Laplace
			nElemento = X(i+1, j) + X(i, j-1) + X(i, j+1) + X(i-1, j) - 4 * X(i, j);
			if (abs(nElemento) <= nTolerancia)		% Para que cumpla con Laplace el elemento debe ser
													%   igual a cero, pero como se trata de una funcion
													%   discrete es muy comun que no de exactamente cero.
													%   Es por esto que uso la tolerancia.
				mBorde(i, j) = 256;	 				% Si encontró el borde, le asigna un color alto (256 es blanco)
			end % if abs(nElemento) <= nTolerancia
		end % if (sCorrect == 'S') ...
	end % for j = 1:1:n
end % for i = 1:1:m
disp(' ');
disp(' FINALIZO EL CALCULO DE LOS BORDES. Presione cualquier tecla para verlos ...'), pause

% Crea una nueva figura y muestra el borde en ella
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
figure						
image(mBorde), colormap(gray(256))

% Borra todas las variables temporales que usa el programa
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
clear sBorrar;
clear sArchivo;
clear nTolerancia;
clear nElemento;
clear sCorrect;
clear m;
clear n;
clear i;
clear j;

% Mensaje de salida
%%%%%%%%%%%%%%%%%%%%
clc
disp(' ');
disp('  La matriz que contiene al borde se llama "nBorde".');
disp(' ');
disp('------------------------------------------------------------------------');
disp(' ');
disp('  Este programa fue desarrollado por Leandro Lucarella. PADRON: 77.891');
disp('     para la Facultad de Ingeniería de la Universidad de Buenos Aires.');
disp('     Catedra de Análisis Matemático II, curso 8.');
disp(' ');
disp('     Comentarios y/o sugerencias a: lluca@cnba.uba.ar       | (C) 1999');
disp(' ');
disp(' ');