Vous êtes sur la page 1sur 21

SEGMENTACIN DE IMGENES BASADA EN EL HISTOGRAMA

GONZALO LUZARDO M. gluzardo@espol.edu.ec gonchalox@gmail.com

1. Introduccin
Este trabajo consiste en tratar de resolver un problema clsico del campo de la visin artificial, que se denomina segmentacin de imgenes. La segmentacin en visin artificial consiste en identificar individualmente cada uno de los objetos o elementos presentes en una escena. En nuestro caso en particular, lo que buscamos es identificar una puerta y discriminarla de los dems objetos que pudieran estar presentes. Las imgenes que vamos a analizar, las cuales son claros ejemplos de los cuatro problemas a los que nos podramos enfrentar al momento de tratar de identificar la puerta, son las siguientes:

CASO 1: Puerta cerrada vista de frente(imagen1.jpg)

CASO 2: Puerta cerrada vista desde un lado (imagen2.jpg)

CASO 3: Puerta abierta (imagen3.jpg)

CASO 4: Puerta semiabierta (imagen4.jpg)

Para resolver nuestro problema de identificar la puerta en cada una de nuestras imgenes, las tcnicas de segmentacin que vamos a utilizar sern las siguientes: 1. Umbralizacin basada en el histograma 2. Umbralizacin basada en la determinacin de contornos

2. Umbralizacin basada en el histograma


En primer lugar, utilizando el cdigo MATLAB de la seccin 6.1 vamos a extraer el histograma para cada una de las imgenes que forman parte de nuestro problema y de esta forma obtener una primera aproximacin a la segmentacin que queremos realizar sobre cada una de ellas. Los histogramas obtenidos para cada caso son los siguientes:
Histograma Original 6000 5000
3000 4000 3500 Histograma Original

4000 3000 2000

2500 2000 1500 1000

1000
500

50

100

150

200

250

50

100

150

200

250

CASO 1
Histograma Original 5000

CASO 2
Histograma Original 4000

4000

3500 3000

3000

2500 2000

2000

1500
1000

1000 500

50

100

150

200

250

50

100

150

200

250

CASO 3

CASO 4

Observando los histogramas podemos notar claramente la naturaleza altamente ruidosa de los mismos. Podemos identificar algunos picos que podran considerarse como objetos identificables dentro de la imagen, as como una multitud de falsos mnimos y falsos mximos. Esta informacin obtenida servir para realizar nuestra primera aproximacin de segmentacin para cada una de las imgenes. La primera segmentacin que vamos a hacer ser la siguiente: aplicar un filtro de la mediana sobre el histograma para tratar de eliminar los falsos mximos y falsos mnimos, para luego considerar los picos (modas) como el nmero de objetos (clases) presentes en nuestra imagen y el umbral de separacin entre dos clases como la media suma de sus picos.

Utilizando el cdigo MATLAB para segmentar una imagen de la seccin 6.2, para cada caso obtuvimos los siguientes resultados.
Histograma con maximos y fronteras (Euclideas)

6000

5000

4000

3000

2000

1000

50

100 150 *Numero de clases identificadas: 7 *Tamao de la ventana: 11

200

250

Histograma con maximos y fronteras (Euclideas) 4000 3500 3000 2500 2000 1500 1000 500 0

50

100 150 200 *Numero de clases identificadas: 11 *Tamao de la ventana: 11

250

Histograma con maximos y fronteras (Euclideas) 5000 4500 4000 3500 3000 2500 2000 1500 1000 500 0 0 50 100 150 *Numero de clases identificadas: 9 *Tamao de la ventana: 11 200 250

Histograma con maximos y fronteras (Euclideas)

4000 3500 3000 2500 2000 1500 1000 500 0

50

100 150 200 *Numero de clases identificadas: 15 *Tamao de la ventana: 11

250

Los datos que obtuvimos para cada uno de los casos fueron los siguientes:
Identificando las clases (objetos) en la imagen Clases (objetos) identificadas climbs = 1.0e+003 * 1.6749 5.0431 2.3578 2.4067 1.6709 0.5880 Numero de clases identificadas: 7 Buscando las fronteras por suma de medias Fronteras encontradas hills = 1.0e+003 * 0 1.6782 0.5553 1.6395 1.4181 0.2833 Dibujamos el histograma identificando las clases encontradas Identificando las clases en la imagen original Clases identificadas...Dibujando

0.4705

0.4807

Identificando las clases (objetos) en la imagen Clases (objetos) identificadas climbs = 1.0e+003 * 1.2060 3.6765 2.7442 2.3056 2.2946 2.2915 0.0520 0.0671 Numero de clases identificadas: 11 Buscando las fronteras por suma de medias Fronteras encontradas hills = 1.0e+003 * 0 1.0763 0.3354 2.4060 2.2898 2.2813 0.0145 0.0592 0.0030 Dibujamos el histograma identificando las clases encontradas Identificando las clases en la imagen original Clases identificadas...Dibujando

2.2948

2.4166

0.0395

2.2805

1.9018

1.4511

Identificando las clases (objetos) en la imagen Clases (objetos) identificadas climbs = 1.0e+003 * 2.3519 1.5530 3.2618 3.2588 4.2558 0.0454 0.0500 0.0551 Numero de clases identificadas: 9 Buscando las fronteras por suma de medias Fronteras encontradas hills = 1.0e+003 * 0.1525 0.0457 0 1.1428 0.6130 3.2555 2.3837 0.0010 Dibujamos el histograma identificando las clases encontradas Identificando las clases en la imagen original Clases identificadas...Dibujando Identificando las clases (objetos) en la imagen Clases (objetos) identificadas climbs = 1.0e+003 * Columns 1 through 12 0.0002 1.6293 2.5529 3.0752 2.7458 3.8296 0.0145 0.0140 0.0153 Columns 13 through 15 0.0185 0.0958 0.1040 Numero de clases identificadas: 15 Buscando las fronteras por suma de medias Fronteras encontradas hills = 1.0e+003 * Columns 1 through 12 0 0.4703 1.9062 0.4623 2.7878 2.0541 0.0139 0.0136 0.0145 Columns 13 through 16 0.0169 0.0216 0.0912 0.0030 Dibujamos el histograma identificando las clases encontradas Identificando las clases en la imagen original Clases identificadas...Dibujando

0.1112

0.0515

0.0708

0.0645

0.0641

0.0142

0.8313

0.0639

0.0275

El tamao de ventana que hemos utilizado para el filtrado del histograma es de 11. Como podemos apreciar los histogramas filtrados lucen mucho mejor que los originales, observamos que aquellos que podramos considerar como falsos mximos y falsos mnimos han sido eliminados. Podemos notar que esta primera segmentacin que hemos aplicado resulta ser bastante buena, claramente podemos apreciar como los diferentes elementos presentes en la imagen han sido por as decirlo identificados. Adicionalmente esta primera segmentacin nos ayuda a poder estimar de manera heurstica el intervalo en niveles de gris que corresponde a la puerta la cual queremos identificar, en nuestro caso este intervalo se encuentra cercano a 50. Esta informacin la utilizaremos para poder etiquetar dentro del histograma a aquellos pixeles que corresponden a la puerta. Otra manera de estimar el umbral o fronteras entre dos clases es mediante restitucin sucesiva del umbral, el cual, dada dos clases con una distribucin normal de los pixeles en cada una, y una misma varianza entre clases, estima el umbral de manera reiterada a travs de la media suma de sus medias estimadas utilizando las muestra presentes en la clase hasta que el umbral se estabilice (Umbralizacin Semi-Bayes). Lo que vamos hacer es implementar esta tcnica de umbralizacin y comparar con los resultados obtenidos mediante la umbralizacin a travs de media suma de los picos. Utilizando el cdigo de MATLAB 6.3 que contiene un algoritmo para de umbralizacin mediante restituciones sucesivas del umbral, para cada caso obtuvimos los siguientes resultados:

Histograma con maximos y fronteras (Semi Bayes)

6000

5000

4000

3000

2000

1000

50

100 150 *Numero de clases identificadas: 7 *Tamao de la ventana: 11

200

250

Histograma con maximos y fronteras (Semi Bayes) 4000 3500 3000 2500 2000 1500 1000 500 0

50

100 150 200 *Numero de clases identificadas: 11 *Tamao de la ventana: 11

250

Histograma con maximos y fronteras (Semi Bayes) 5000 4500 4000 3500 3000 2500 2000 1500 1000 500 0 0 50 100 150 *Numero de clases identificadas: 9 *Tamao de la ventana: 11 200 250

Histograma con maximos y fronteras (Semi Bayes)

4000 3500 3000 2500 2000 1500 1000 500 0

50

100 150 200 *Numero de clases identificadas: 15 *Tamao de la ventana: 11

250

Si observamos los resultados obtenidos notamos que no son muy buenos e incluso son peores a los que obtuvimos estimando los umbrales como las medias sumas de los picos. Al parecer considerar que cada una de las clases posee la misma varianza, algo que en realidad claramente no sucede, ocasiona que las fronteras entre clases se inclinen ms hacia la clase con mayor nmero de muestras. Una manera de corregir este error sera utilizando una estimacin del umbral con Bayes completo el cual si considera la varianza en cada una de las clases. El problema de aplicar un Bayes completo radica en el incremento de la cantidad de clculos que debemos realizar. En vez de utilizar Bayes-completo, hemos optado por estimar los umbrales de una manera diferente: el umbral entre dos clases dadas estar ubicado en el valor mnimo presente entre los picos de ambas clases. Como vemos esta estimacin resulta ser ms sencilla y mucho ms fcil de calcular. Adicionalmente vamos a etiquetar el histograma utilizando el valor obtenido del nivel de gris donde puede localizarse la puerta, de tal forma que aquella clase que contenga dentro el valor de gris igual a 50 corresponder a la puerta. Utilizando el cdigo de MATLAB 6.4 el cual establece el umbral entre las clases como el valor mnimo entre sus picos, para cada caso obtuvimos los siguientes resultados:

Histograma con maximos y fronteras

6000
Clase Puerta

5000

4000

3000

2000

1000

50

100 150 *Numero de clases identificadas: 7 *Tamao de la ventana: 11


Histograma con maximos y fronteras

200

250

4000 3500 3000 2500 2000 1500 1000 500 0

Clase Puerta

50

100 150 200 *Numero de clases identificadas: 11 *Tamao de la ventana: 11

250

Histograma con maximos y fronteras 5000 4500 4000 3500 3000 2500 2000
Clase Puerta

1500 1000 500 0 0 50 100 150 *Numero de clases identificadas: 9 *Tamao de la ventana: 11 200 250

Histograma con maximos y fronteras

4000 3500 3000


Clas e Puerta

2500 2000 1500 1000 500 0

50

100 150 200 *Numero de clases identificadas: 15 *Tamao de la ventana: 11

250

Analizando los resultados podemos darnos cuenta de algunas mejoras respecto a los resultados obtenidos anteriormente. Podemos observar que existen regiones de la puerta que en un principio fueron clasificadas errneamente, esta vez clasificadas de manera correcta; estas regiones corresponden a las zonas oscuras correspondientes al marco de la puerta. Aun podemos mejorar nuestros resultados realizando un preprocesamiento sobre la imagen. Este preprocesamiento consistir en aplicar un filtro gausiano sobre la imagen original. De esta forma eliminaremos las frecuencias altas presentes en la imagen, y en teora una mejor clasificacin. Adicionalmente vamos a marcar sobre la imagen slo aquellos pixeles que segn el histograma corresponden a la puerta. Utilizando el cdigo MATLAB de la seccin 6.5 donde realizamos preprocesado de imgenes, obtuvimos los siguientes resultados:
Histograma con maximos y fronteras 7000

6000
Clase Puerta

5000

4000

3000

2000

1000

50

100 150 *Numero de clases identificadas: 8 *Tamao de la ventana: 11

200

250

Histograma con maximos y fronteras

4000 3500 3000 2500 2000 1500 1000 500 0

Clase Puerta

50

100 150 200 *Numero de clases identificadas: 15 *Tamao de la ventana: 11

250

Histograma con maximos y fronteras

5000

4000

3000

2000

Clase Puerta

1000

50

100 150 200 *Numero de clases identificadas: 13 *Tamao de la ventana: 11

250

Histograma con maximos y fronteras

4000 3500 3000


Clase Puerta

2500 2000 1500 1000 500 0

50

100 150 200 *Numero de clases identificadas: 13 *Tamao de la ventana: 11

250

Al observar los resultados obtenidos notamos que la segmentacin realizada es relativamente buena. Hemos podido identificar claramente las regiones pertenecientes a la puerta las cuales se encuentran marcadas de color verde. Como vemos tambin existen pixeles o regiones mal clasificadas (regiones que no forman parte de la puerta marcados como parte de ella), esto se debe a que a que dichos pixeles poseen una intensidad en niveles de gris igual o similar a aquellos pixeles que si forman parte de la puerta. Para mejorar an ms nuestra segmentacin podramos optar por: 1. Ecualizar la imagen de entrada para incrementar su contraste. 2. Postprocesar la imagen segmentada: Una vez segmentada la imagen, eliminar aquellos pixeles que se encuentran fuera de una zona rectangular con una relacin de aspecto que no corresponde a la puerta que estamos buscando. 3. Utilizar un clasificador que no slo considere la informacin de la intensidad de luz de la imagen sino tambin su croma (color). Una posible desventaja de utilizar algunas de estas mejoras radica en la necesidad de hacer clculos adicionales a los que hemos hecho hasta el momento, lo que no podra ser un inconveniente para una aplicacin montada sobre un robot que en tiempo real est constantemente buscando una puerta para luego dirigirse hacia ella.

3. Umbralizacin basada en la determinacin de contornos


Es estas seccin vamos a realizar una segmentacin basada en contornos o tambin llamada basada en deteccin de bordes. La idea bsica consiste en buscar cambios bruscos en los niveles de gris presentes en una imagen, lo que resulta ser un indicativo de la presencia de bordes en la misma. Para la deteccin de bordes vamos a utilizar los operadores de derivacin (filtros del gradiente y laplacianos) los cuales se ha comprobado que dan muy buenos resultados. La deteccin de bordes puede ser particularmente til en nuestro caso ya que la puerta (con niveles de intensidad bajos) tiene los bordes muy bien definidos debido a que se encuentra sobre la pared que tiene un nivel de intensidad mucho ms altos.

Utilizando el cdigo MATLAB de la seccin 6.6 la cual realiza una extraccin de bordes aplicando el filtro del gradiente de Prewitt, obtuvimos los siguientes resultados:

Si observamos los resultados notamos la eficacia del filtro aplicado. Los bordes de los objetos, especialmente los de la puerta, han sido identificados muy bien. Podramos detenernos aqu, pero por cuestiones de curiosidad, aplicaremos un filtro laplaciano para la extraccin de bordes. Utilizando el cdigo MATLAB de la seccin 6.7 pudimos obtener los siguientes resultados:

Si observamos los resultados obtenidos al aplicar ambos filtros podemos notar que ambos son igual de buenos, de tal forma que cualquiera de los dos se los podra considerar como vlido. Adicionalmente, se investigaron los filtros de Canny para la deteccin de bordes. El filtro de Canny combina un operador diferencial con un filtro gausiano para la deteccin de bordes. Utilizando el cdigo MATLAB de la seccin 6.8 pudimos obtener los siguientes resultados:

Podemos observar que el filtro de Canny nos da mejores resultados, esto es, el aplicar un filtro gausiano antes de la deteccin de bordes nos ayudar a eliminar las altas frecuencias presentes en la seal y que pueden ser consideradas como falsos bordes, obteniendo al final mejores resultados.

4. Conclusiones
Una vez culminado el presente trabajo podemos sacar las siguientes conclusiones: Mientras ms complejo resulta ser un algoritmo, ms difcil es su implementacin y los resultados no necesariamente sern mucho mejores a los obtenidos por un algoritmo mucho ms simple. Es mejor tener algoritmos simples que den buenos resultados a algoritmos complejos que den resultados un poco mejores (algo parecido a la Ley de Parsimonia1). El menor rendimiento obtenido con los algoritmos simples es recompensado con la simplicidad y rapidez que estos nos proporcionan. No podemos tener un algoritmo que funcione perfectamente en todos los casos. Si mejoramos cada vez ms un algoritmo, este funcionar muy bien para los casos objetos de de nuestro estudio y muy mal para los dems casos, esto quiere decir que el algoritmo se vuelve especfico y es incapaz de generalizar. La segmentacin se vuelve mucho ms dificultosa con imgenes de naturaleza compleja, donde existen una multitud de objetos a ser identificados, ruido ocasionado por la luz, por texturas complejas en los objetos, entre otros. La segmentacin basada en histograma en muy potente en imgenes no complejas y bajo condiciones preestablecidas que favorezcan a la deteccin. Por ejemplo deteccin de objetos sobre un fondo de un color prefijado. Sera muy til por ejemplo para contar elementos sobre una banda transportadora.

5. Referencias
GONZALEZ, WOODS, EDDINS. Digital Image Processing using MATLAB. Prentice Hall. 2004. MARAVALL DARIO. ``Reconocimiento de formas y visin artificial''. RAMA. 1993.

Determina que, entre dos soluciones, es probable que la correcta sea la ms sencilla.

6. Cdigo MATLAB
6.1. Extraccin y Trazado del histograma de una imagen
image_name = 'imagen1.jpg'; img = imread(image_name); [counts,x]=imhist(img); maxcounts = max(counts); h = bar(x,counts); set(h,'FaceColor',[102/255,153/255,102/255],'EdgeColor',[102/255,153/255,102/255] ); title 'Histograma Original'; axis([0 255 0 maxcounts+300]);

6.2. Segmentacin basada en histograma con filtrado de bordes y estimacin de fronteras mediante la suma de las medias de los picos del histograma
%<image_name> es el nombre del a imagen que vamos a procesar image_name = 'imagen4.jpg'; %nombre de la imagen que vamos a tratar hist_mean_filter = 11; %debe ser impar, filtro de histograma, minimo 1 maximo 256 filter_text = ''; img = imread(image_name); [m,n] = size(img); %Convertir a blanco y negro img = rgb2gray(img); bar_width = hist_mean_filter; [shist, err] = sprintf('Tamao de la ventana: %i\n',bar_width); %Obtenemos el histograma de la imagen original [counts,x]=imhist(img); maxcounts = max(counts); %Aplicamos un filtro de la media sobre el histograma counts_filtered = smooth(counts,bar_width); %Buscamos los mayores locales dentro de la imagen fprintf('Identificando las clases (objetos) en la imagen\n'); [climbs,xclimbs] = FindLocalMax(counts_filtered); fprintf('Clases (objetos) identificadas'); climbs clases = length(climbs); %numero de clases fprintf('Numero de clases identificadas: %i\n',clases); [sclases, err] = sprintf('*Numero de clases identificadas: %i\n *',clases); fprintf('Buscando las fronteras por suma de medias\n'); [hills,xhills]=FindFrontiers(counts_filtered,xclimbs); fprintf('Fronteras encontradas\n'); tit_s = 'Histograma con maximos y fronteras (Euclideas)'; hills figure %Dibujamos el histograma fprintf('Dibujamos el histograma identificando las clases encontradas\n'); color_clases = DrawHistClases(x,counts_filtered,xhills); %Dibujamos el histograma de clases title(tit_s); hold on; %Dibujamos los maximos en el histograma h = stem(xclimbs,climbs); set(h,'Color','r','LineStyle','-','Marker','s','MarkerEdgeColor','r','MarkerFaceColor','r','MarkerSize',2); axis([0 255 0 maxcounts+300]); xlabel(strcat(sclases, shist)); hold off; figure %Dibujamos la imagen original;

%Utilizamos los colores que representan a cada clase %para poder ser representados en una imagen de las mismas dimensiones de %la imagen original donde podamos visualizara a que clase corresponde cada pixel en una imagen fprintf('Identificando las clases en la imagen original\n'); img_clases = GetImgClases(img,xhills,color_clases); %imagen en nivel de gris, fronteras, colores para cada clase fprintf('Clases identificadas...Dibujando\n'); imshow(img_clases); title 'Imagen Segmentada';

%Busca los maximos y minimos locales function [max_arr,in] = FindGlobalMax(img_hist) ant = img_hist(1); sentido = 1; %1 sube y -1 baja cont = 1; max_arr(1) = 0; in(1) = 0; for N=1:length(img_hist) %fprintf('\nAnalizando %d \n', img_hist(N)); %La recta no ha cambiado if(img_hist(N) ~= ant) if(ant > img_hist(N)) if(sentido == 1) max_arr(cont) = ant; in(cont) = N-1; cont = cont + 1; sentido = -1; %fprintf('Maximo %d \n', img_hist(N)); end else sentido = 1; end end ant = img_hist(N); end

function[frontier,findex]=FindFrontiers(values,maxindex) findex = zeros(1,length(maxindex)+1); frontier = zeros(1,length(maxindex)+1); findex(1)= 1; frontier(1)= values(1); for N=1:length(maxindex)-1 findex(N+1) = round(maxindex(N) + (maxindex(N+1) - maxindex(N))/2); frontier(N+1) = values(findex(N+1)); end findex(length(maxindex)+1)= 256; %Maximo valor de un pixel frontier(length(maxindex)+1) = values(256)

function [colors] = DrawHistClases(x,counts,xhills) %En base al numero de clases obtenemos los colores que vamos a usar para %representar cada clase clases = length(xhills)-1; colors=zeros(clases,3); colors(:,1) = rand(1,clases); colors(:,2) = rand(1,clases); colors(:,3) = rand(1,clases); %Para colorearla de un color especifico la clase que corresponde a la %puerta

clase = 3; colors(clase,1) = 0.5; colors(clase,2) = 1; colors(clase,3) = 0.2; %Voy dibujando poco a poco cada una de las clases for c=1:length(xhills)-1 x = (xhills(c):xhills(c+1)); y = counts(xhills(c):xhills(c+1)); hold on h=bar(x,y); set(h,'FaceColor',colors(c,:),'EdgeColor',colors(c,:)); end hold off

function [img_clases] = GetImgClases(img,pos_clases,color_clases) [M,N] = size(img); img_clases = zeros(M,N,3); %Retorna una imagen a colores for m=1:M for n=1:N pixel = img(m,n); %Un for para verificar si el punto pertenece a una clase en %particular for c=1:length(pos_clases-1) if(pixel >= pos_clases(c) && pixel < pos_clases(c+1)) pcolor = color_clases(c,:); end end img_clases(m,n,:)=round(pcolor.*255); end end img_clases = cast(img_clases,'uint8');

6.3. Segmentacin basada en histograma con estimacin de fronteras mediante restitucin sucesiva del umbral
%<image_name> es el nombre del a imagen que vamos a procesar image_name = 'imagen4.jpg'; %nombre de la imagen que vamos a tratar hist_mean_filter = 11; %debe ser impar, filtro de histograma, minimo 1 maximo 256 filter_text = ''; img = imread(image_name); [m,n] = size(img); %Convertir a blanco y negro img = rgb2gray(img); bar_width = hist_mean_filter; [shist, err] = sprintf('Tamao de la ventana: %i\n',bar_width); %Obtenemos el histograma de la imagen original [counts,x]=imhist(img); maxcounts = max(counts); %Aplicamos un filtro de la media sobre el histograma counts_filtered = smooth(counts,bar_width); %Buscamos los mayores locales dentro de la imagen fprintf('Identificando las clases (objetos) en la imagen\n'); [climbs,xclimbs] = FindLocalMax(counts_filtered); fprintf('Clases (objetos) identificadas'); climbs clases = length(climbs); %numero de clases fprintf('Numero de clases identificadas: %i\n',clases); *',clases); [sclases, err] = sprintf('*Numero de clases identificadas: %i\n fprintf('Buscando las fronteras por suma de medias\n'); [hills,xhills]=FindFrontiersSemiBayes(counts_filtered',xclimbs); fprintf('Fronteras encontradas\n'); tit_s = 'Histograma con maximos y fronteras (Semi Bayes)';

hills figure %Dibujamos el histograma fprintf('Dibujamos el histograma identificando las clases encontradas\n'); color_clases = DrawHistClases(x,counts_filtered,xhills); %Dibujamos el histograma de clases title(tit_s); hold on; %Dibujamos los maximos en el histograma h = stem(xclimbs,climbs); set(h,'Color','r','LineStyle','-','Marker','s','MarkerEdgeColor','r','MarkerFaceColor','r','MarkerSize',2); axis([0 255 0 maxcounts+300]); xlabel(strcat(sclases, shist)); hold off; figure fprintf('Identificando las clases en la imagen original\n'); img_clases = GetImgClases(img,xhills,color_clases); %imagen en nivel de gris, fronteras, colores para cada clase fprintf('Clases identificadas...Dibujando\n'); imshow(img_clases); title 'Imagen Segmentada';

function[hills,xhills,climbs,xclimbs]=FindFrontiersSemiBayes(values,xmodes) xhills = zeros(1,length(xmodes)+1); hills = zeros(1,length(xmodes)+1); xclimbs = xmodes; climbs = values(xmodes); xhills(1)= 1; hills(1)= values(1); %Inicializacion for N=1:length(xmodes)-1 xhills(N+1) = round(xmodes(N) + (xmodes(N+1) - xmodes(N))/2); hills(N+1) = values(xhills(N+1)); end xhills(length(xmodes)+1)= 256; %Maximo valor de un pixel hills(length(xmodes)+1) = values(256); %Comenzamos con cada una de las clases %Para cada una de las clases for N=1:length(xmodes)-2 fprintf('Estabilizando clases: %i y %i\n',N,N+1); min_sec = xhills(N); uf = xhills(N+1); %la que iremos modificando paulatinamente fprintf('Frontera inicial: %i\n',uf); max_sec = xhills(N+2); stable = 0; %establece si se stabilizo la busqueda while(stable == 0) m1 = sum((values(min_sec:uf) .* [min_sec:uf]))/sum(values(min_sec:uf)); m2 = sum((values(uf:max_sec) .* [uf:max_sec]))/sum(values(uf:max_sec)); mc = round((m1+m2)/2); fprintf('Frontera obtenida: %i\n',mc); if(mc==uf) stable = 1; else uf = mc; end end xhills(N+1)=uf; end

6.4. Segmentacin basada en histograma con filtrado de bordes y estimacin de fronteras mediante la localizacin de los mnimos entre los picos
%<image_name> es el nombre del a imagen que vamos a procesar gray_level_element = 50; %nivel de gris de la puerta image_name = 'imagen1.jpg'; %nombre de la imagen que vamos a tratar hist_mean_filter = 11; %debe ser impar, filtro de histograma, minimo 1 maximo 256 filter_text = ''; img = imread(image_name); [m,n] = size(img); %Convertir a blanco y negro img = rgb2gray(img); bar_width = hist_mean_filter; [shist, err] = sprintf('Tamao de la ventana: %i\n',bar_width); %Obtenemos el histograma de la imagen original [counts,x]=imhist(img); maxcounts = max(counts); %Aplicamos un filtro de la media sobre el histograma counts_filtered = smooth(counts,bar_width); %Buscamos los mayores locales dentro de la imagen fprintf('Identificando las clases (objetos) en la imagen\n'); [climbs,xclimbs] = FindLocalMax(counts_filtered); fprintf('Clases (objetos) identificadas'); climbs clases = length(climbs); %numero de clases fprintf('Numero de clases identificadas: %i\n',clases); *',clases); [sclases, err] = sprintf('*Numero de clases identificadas: %i\n fprintf('Buscando las fronteras como los minimos\n'); [hills,xhills]=FindFrontiersMin(counts_filtered,xclimbs); fprintf('Fronteras encontradas\n'); tit_s = 'Histograma con maximos y fronteras'; hills figure %Dibujamos el histograma fprintf('Dibujamos el histograma identificando las clases encontradas\n'); color_clases = DrawHistClases(x,counts_filtered,xhills); %Dibujamos el histograma de clases title(tit_s); hold on; %Dibujamos los maximos en el histograma h = stem(xclimbs,climbs); set(h,'Color','r','LineStyle','-','Marker','s','MarkerEdgeColor','r','MarkerFaceColor','r','MarkerSize',2); axis([0 255 0 maxcounts+300]); xlabel(strcat(sclases, shist)); [xpos,yval] = FindPrototype(gray_level_element,xhills,xclimbs,climbs); text(xpos,yval + 200, 'Clase Puerta', 'HorizontalAlignment','center','BackgroundColor',[.7 .9 .7],'FontSize', 9); hold off; figure %Dibujamos la imagen original; fprintf('Identificando las clases en la imagen original\n'); img_clases = GetImgClases(img,xhills,color_clases); %imagen en nivel de gris, fronteras, colores para cada clase fprintf('Clases identificadas...Dibujando\n'); imshow(img_clases); title 'Imagen Segmentada';

function[frontier,findex]=FindFrontiersMin(values,maxindex) findex = zeros(1,length(maxindex)+1); frontier = zeros(1,length(maxindex)+1); findex(1)= 1; frontier(1)= values(1);

for N=1:length(maxindex)-1 fin = maxindex(N+1); inicio = maxindex(N); %Obtengo los valores presentes entre los intervalos reg = values(inicio:fin); h = min(reg); p = find(reg == h); f = round(inicio + p(1)); findex(N+1) = f ; frontier(N+1) = values(findex(N+1)); end findex(length(maxindex)+1)= 256; %Maximo valor de un pixel frontier(length(maxindex)+1) = values(256);

function [xpos,yval] = FindPrototype(el,xhills,xclimbs,climbs) for n=1:length(xhills-1) if(el > xhills(n) && el < xhills(n+1)) xpos = xclimbs(n); yval = climbs(n); end end

6.5. Segmentacin basada en histograma con preprocesado de imagen, filtrado de bordes y estimacin de fronteras mediante la localizacin de los mnimos entre los picos
%<image_name> es el nombre del a imagen que vamos a procesar gray_level_element = 50; %nivel de gris de la puerta image_name = 'imagen4.jpg'; %nombre de la imagen que vamos a tratar hist_mean_filter = 11; %debe ser impar, filtro de histograma, minimo 1 maximo 256 filter_text = ''; img = imread(image_name); [m,n] = size(img); %Convertir a blanco y negro img = rgb2gray(img); %Realizamos el preprocesamiento de la imagen fprintf('Aplicando filtro gausiano\n'); [img,b] = gaussian_low(img,90); img = cast(img,'uint8'); [shist, err] = sprintf('Tamao de la ventana: %i\n',bar_width); %Obtenemos el histograma de la imagen original [counts,x]=imhist(img); maxcounts = max(counts); %Aplicamos un filtro de la media sobre el histograma counts_filtered = smooth(counts,bar_width); %Buscamos los mayores locales dentro de la imagen fprintf('Identificando las clases (objetos) en la imagen\n'); [climbs,xclimbs] = FindLocalMax(counts_filtered); fprintf('Clases (objetos) identificadas'); climbs clases = length(climbs); %numero de clases fprintf('Numero de clases identificadas: %i\n',clases); [sclases, err] = sprintf('*Numero de clases identificadas: %i\n *',clases); fprintf('Buscando las fronteras como los minimos\n'); [hills,xhills]=FindFrontiersMin(counts_filtered,xclimbs); fprintf('Fronteras encontradas\n'); tit_s = 'Histograma con maximos y fronteras'; hills figure %Dibujamos el histograma fprintf('Dibujamos el histograma identificando las clases encontradas\n');

color_clases = DrawHistClases(x,counts_filtered,xhills); %Dibujamos el histograma de clases title(tit_s); hold on; %Dibujamos los maximos en el histograma h = stem(xclimbs,climbs); set(h,'Color','r','LineStyle','-','Marker','s','MarkerEdgeColor','r','MarkerFaceColor','r','MarkerSize',2); axis([0 255 0 maxcounts+300]); xlabel(strcat(sclases, shist)); [xpos,yval] = FindPrototype(gray_level_element,xhills,xclimbs,climbs); text(xpos,yval + 200, 'Clase Puerta', 'HorizontalAlignment','center','BackgroundColor',[.7 .9 .7],'FontSize', 9); hold off; figure %Dibujamos la imagen original; %Uilizamos los colores que representan a cada clase %para poder ser representados en una imagen de las mismas dimensiones de %la imagen original donde podamos visualizara a que clase corresponde ada pixel en una imagen fprintf('Identificando las clases en la imagen original\n'); img_clases = GetImgClasesDoor(img,xhills,gray_level_element); %imagen en nivel de gris, solo pinta la clase puerta fprintf('Clases identificadas...Dibujando\n'); imshow(img_clases); title 'Imagen Segmentada';

function [img_clases] = GetImgClasesDoor(img,pos_clases,p_door) [M,N] = size(img); img_clases = zeros(M,N,3); %Retorna una imagen a colores ci = 0; cf = 0; %Busco la clase a la cual pertenece la puerta for l=1:length(pos_clases)-1 if (p_door <= pos_clases(l+1) && p_door >= pos_clases(l)) ci = pos_clases(l); cf = pos_clases(l+1); end end for m=1:M for n=1:N pixel = img(m,n); if(pixel >= ci && pixel <= cf) pcolor = [0.5 1 0.2]; %verde img_clases(m,n,:)=round(pcolor.*255); else pcolor = [img(m,n) img(m,n) img(m,n)]; img_clases(m,n,:)=pcolor; end end end img_clases = cast(img_clases,'uint8');

6.6. Segmentacin basada en la deteccin de bordes utilizando un filtro de gradiente de Prewitt


image_name = 'imagen1.jpg'; %nombre de la imagen que vamos a tratar img = imread(image_name); [m,n] = size(img); %Convertir a blanco y negro

img = rgb2gray(img); [g,tg] = edge(img,'prewitt',0.05); imshow(g);

6.7. Segmentacin basada en la deteccin de bordes utilizando un filtro de la laplaciana


image_name = 'imagen4.jpg'; %nombre de la imagen que vamos a tratar img = imread(image_name); [m,n] = size(img); %Convertir a blanco y negro img = rgb2gray(img); [g,tg] = edge(img,'log',0.007); imshow(g);

6.8. Segmentacin basada en la deteccin de bordes utilizando un filtro de Canny


image_name = 'imagen4.jpg'; %nombre de la imagen que vamos a tratar img = imread(image_name); [m,n] = size(img); %Convertir a blanco y negro img = rgb2gray(img); [g,tg] = edge(img,'canny',[0.09 0.12],2.5); imshow(g);