lunes, 18 de febrero de 2013

Deteccion de formas


Para la tarea 2 de la clase de visión se nos pidió realizar un programa el cual detectara formas en una imagen, separadas por sus diferentes bordes, después de realizar esto se pintarían de colores diferentes cada forma y la de mayor tamaño se pintaría de gris, después de hacer esto hay que encontrar el centro de masa de cada forma y colocarle una etiqueta. Explicare cada paso por partes.

Convolucion y Binarizacion

Primero que nada para poder hacer la parte de detección de formas debemos tener hecho la parte de detección de bordes por medio de convolucion y a partir de la imagen que nos genera usar binarizacion.
Como no había hecho anteriormente la parte de binarizacion la explicare aquí para la parte de convolucion ya tengo una entrada que explica eso y el código utilizado para esa parte es el mismo.

Para realizar la parte de binarizacion es muy sencillo, partiendo de la imagen obtenida de la detección de bordes con convolucion, generamos un valor máximo, recorremos la imagen y sacamos el promedio de cada pixel si su promedio es menor que el valor lo cambiamos a negro si no cumple con esto se hace blanco. De esta manera obtenemos una imagen con los bordes bien definidos con la que podemos trabajar en la detección de formas.

El código que utilice para binarizacion es el siguiente:





Ejemplos


Original

                                          Convolucion                                    Binarizacion


Original

                   
                                        Convolucion                                      Binarizacion

Como las 2 imágenes anteriores ya tenían sus bordes bien definidos de inicio pondré un 3r ejemplo utilice las anteriores ya que me gusta su resultado final en las figuras ya que desde el inicio tienen formas bien marcadas.

Original

                                 
                                             Bordes                                      Binarizacion


Ya que tenemos bien toda esta parte podemos pasar a la primera parte de detección de formas.

Detección de formas


BFS

Para esta parte partiremos de la imagen obtenida de la binarizacion, lo que haremos aquí es empesar a recorrer la imagen desde el punto 0,0 generamos un color random, creamos una cola en la cual agregaremos el primer valor a checar en este caso 0,0 que se convertirá en nuestro punto de partida después creamos un while que seguirá hasta que la cola este vacía como tenemos actualmente el valor 0,0 se cumple la condición lo primero que haremos dentro de la condición sera eliminar el valor que ya vamos a revisar para no repetirlo y empesaremos a revisar los vecinos en el caso de 0,0 solo tiene 2 uno a su derecha y el otro abajo de igual forma esto lo verificamos con trys que verifica que existan vecinos, una ves que encontramos vecinos revisamos si su valor r,g,b es igual al del punto de partida si es igual se pinta del color generado y se agrega a la cola, esto se hace con todos los vecinos y así vamos revisando todas los vecinos hasta que se encuentre con un borde ya que como binarizamos la imagen cuando encuentre otro valor que no sea negro significara el comienzo de otra forma.

Imagen explicativa:



Código utilizado:

Ejemplos


Partiendo de las imágenes anteriores









Figura de mayor área

Después de haber coloreado la imagen también se nos pidió pintar el fondo de la figura de mayor área de color gris, para esto lo que hice fue crear 2 listas una que en la cual guardare la cantidad de pixeles de cada corrida en la función bfs por ende cada corrida es una figura diferente entonces en cada corrida por medio de un contador sumo la cantidad de pixeles que contiene la figura lo regreso y lo almaceno en la lista contador y de la misma forma regreso el color que contiene esa figura y lo almaceno en la otra lista de esta manera quedara en la misma posición ejemplo:
lista contador[0]=2000
lista color[0]=(0,0,0)
De esta forma de ser el 2000 el valor mas grande en la lista sabre que el color que tengo que repintar de gris es el negro.Una ves que tenemos todas las figuras pintadas, todos los valores almacenados en la lista buscamos el valor mas alto de la cadena contador usando:

máximo =contador.index(max(contador))

en este caso nos regresara a la variable máximo la posición del valor mayor, ya lo único que hacemos es conociendo la posición del máximo sacar el color del cual esta pintado esa parte de la siguiente manera:

 gris=colores[máximo]

Conociendo todo esto solo recorremos la imagen buscando el color de la variable gris en este caso y lo repintamos de color gris.


El código que realice quedo de la siguiente manera:




 

      Primer Resultado                                      Área mayor repintada


               


Obtención de centros y etiquetado

Para obtener los centros de cada figura se hizo algo parecido a lo de obtener el valor mayor, cree 2 listas  en las cuales el bfs me regresara cada valor de i,j que se agreguen a la cola esto para utilizarlos después con una formula para obtener su centro, la cual quedo de la siguiente manera:

centro.append((sum(centro1)/float(len(centro1)),sum(centro2)/float(len(centro2))))

centro1 siendo los valores de i

centro2 los valores de j

La formula la aplique con un try ta que hay casos en fotos que pequeñas manchas 1 solo pixel lo detecta como una figura y causa errores al querer dividir entre 0.

La formula nos almacenara en otra lista los centros de cada figura y después con esto recorremos la cadena y dibujamos un circulo en cada uno de esos puntos para diferenciar los centros. Al mismo tiempo que se dibuja los círculos hay que crear las labels para diferenciar las figuras, esta parte también la hice pero tuve problemas con la ventana al mostrar las labels lo cual aun no eh resuelto y dejo solo las imagenes hasta los puntos.


El código que utilice:







El código completo se encuentra en mi repositorio:
















1 comentario:

  1. Están los puntos de masa (muy chiquitos), pero no las etiquetas... Esta vez redondeo arriba y van 5 pts.

    ResponderEliminar