14 diciembre 2010

Manipulación de imágenes

Esta entrada esta enfocada a la manipulación de imágenes. En mi caso me toco manipular las imágenes de manera que se pueda cambiar al color de una region en particular del mismo color.

Para realizar esto utilice la herramienta octave con el modulo image para la manipulación de imágenes.

Primero genere una matriz de 10 x 10 de ceros y unos de manera aleatoria mediante la siguiente instrucción:


Para representar esta matriz como una imagen utilice la siguiente instrucción
imgplot(y)
 
La cual genero la siguiente imagen:

Para realizar el cambio de color de una región seleccionada de la imagen, realice una rutina la cual esta compuesta por funciones

La primera es la función principal, la cual ejecuta las demás y devuelve la matriz ya modificada. La idea general de esta rutina es la de ir revisando los valores adyacentes al pixel indicado para revisar si es del mismo color que el principal, si es así le cambia el color y revisa los valores adyacentes a ese valor que se le acaba de cambiar el color. Esto lo realiza mediante funciones recursivas. A continuación dejo las funciones que genere:

function res = colorear(m,x,y)
#Funcion que cambia de color los pixeles adyacentes al indicado
#m es la matriz a la cual se le quiere manipular
#x es la fila del valor seleccionado para cambiar los valores adyacentes del mismo color
#y es la fila del valor seleccionado para cambiar los valores adyacentes del mismo color
z = m(x,y);
m = colorearsec(m,x,y,z);
res = m;
endfunction

function res = colorearsec(m,x,y,z)
#Función recursiva que cambia de color el pixel indicado y ejecuta las funciones para cambiar los adyacentes
m(x,y) = 3;
m = derecha(m,x,y,z);
m = abajo(m,x,y,z);
m = izquierda(m,x,y,z);
m = arriba(m,x,y,z);
res = m;
endfunction
function res = derecha(m,x,y,z)
#Función que cambia de color el pixel a la derecha del especificado
[x1,y1]= size(m);
if((y+1)
if(m(x,y+1)==z)
m(x,y+1)=3;
m = colorearsec(m,x,y+1,z);
endif
endif
res = m;
endfunction
function res = izquierda(m,x,y,z)
#Función que cambia de color el pixel a la izquierda del especificado
[x1,y1]= size(m);
if((y-1)>0)
if(m(x,y-1)==z)
m(x,y-1)=3;
m = colorearsec(m,x,y-1,z);
endif
endif
res = m;
endfunction
function res = abajo(m,x,y,z)
#Función que cambia de color el pixel a abajo del especificado
[x1,y1]= size(m);
if((x+1)
if(m(x+1,y)==z)
m(x+1,y)=3;
m = colorearsec(m,x+1,y,z);
endif
endif
res = m;
endfunction
function res = arriba(m,x,y,z)
#Función que cambia de color el pixel arriba del especificado
[x1,y1]= size(m);
if((x-1)>0)
if(m(x-1,y)==z)
m(x-1,y)=3;
m = colorearsec(m,x-1,y,z);
endif
endif
res = m;
endfunction

Al ejecutar la rutina para cambiar el color de los pixeles adyacentes al que se encuentra en la posición y(1,2) tenemos el siguiente resultado:

Como podemos observar los valores adyacentes al pixel seleccionado cambiaron al valor '3'.

Si graficamos esta matriz tenemos el siguiente resultado:


El problema que encontré con estas funciones es que como utiliza funciones recursivas es fácil que se llegue al limite de recursividad de la herramienta octave por lo que tendremos que aumentar este limite. Aun habiendo hecho esto la herramienta tiende a fallar cuando son muchas llamadas recursivas. Trate de solucionar este detalle creando rutinas que utilicen ciclos pero el proceso es muy lento. Como quiera dejo las rutinas creadas por si quieren darle un vistazo.

function res = colorear2(m,x,y)
z = m(x,y);
m(x,y) = 3;
[x1,y1] = size(m);
encontrado = 0;
do
encontrado = 0;
for i = 1:x1
for j = 1:y1
if (m(i,j)==z)
if ((derecha2(m,i,j,z) ==1)|(izquierda2(m,i,j,z)==1)|(arriba2(m,i,j,z)==1)|(abajo2(m,i,j,z)==1))
encontrado = 1;
m(i,j) = 3;
break;
endif
endif
endfor
if (encontrado == 1)
break;
endif
endfor
until encontrado == 0
res = m;
endfunction
function res = derecha2(m,x,y,z)
#Función que cambia de color el pixel a la derecha del especificado
[x1,y1]= size(m);
res = 0;
if(m(x,y)==z)
if((y+1)
if(m(x,y+1)==3)
res = 1;
endif
endif
endif
endfunction
function res = izquierda2(m,x,y,z)
#Función que cambia de color el pixel a la izquierda del especificado
[x1,y1]= size(m);
res = 0;
if(m(x,y)==z)
if((y-1)>0)
if(m(x,y-1)==3)
res = 1;
endif
endif
endif
endfunction
function res = abajo2(m,x,y,z)
#Función que cambia de color el pixel a abajo del especificado
[x1,y1]= size(m);
res = 0;
if(m(x,y)==z)
if((x+1)
if(m(x+1,y)==3)
res = 1;
endif
endif
endif
endfunction
function res = arriba2(m,x,y,z)
#Función que cambia de color el pixel arriba del especificado
[x1,y1]= size(m);
res = 0;
if(m(x,y)==z)
if((x-1)>0)
if(m(x-1,y)==3)
res = 1;
endif
endif
endif
endfunction


1 comentario: