domingo, 17 de febrero de 2013

Tarea 2: Detección de Formas

Link al repositorio: https://github.com/synnick/viscomp

Para la detección de formas, lo solicitado fue lo siguiente:
  • Agregar una rutina que detecta todos los componentes conexos separados por bordes.
  • El componente más grande debe suponerse ser el fondo, y colorearse gris.
  • Los demás dibujos se les asignan colores fuertes. Colocando el borde en blanco y un punto negro en el centro indicando el centro de masa.
  • A un lado del centro de masa, se agrega una etiqueta ID del componente.
  • El programa debe imprimir un listado con los porcentajes de la parte del total que abarca un componente y su ID.
La imagen utilizada, por su contenido en formas sencillas es la siguiente:


Previo a la detección de formas

Antes de iniciar la detección de formas, lo primero es utilizar las rutinas programadas en el post anterior para lo detección de contornos. Esto para poder determinar las separaciones que existen entre componentes conexos y además diferenciar contornos de la figura en sí. 

Para detectar los contornos se realizaron los siguientes pasos:
  • Conversión de imagen a escala de grises.
  • Convolución de la imagen con la siguiente máscara:
  • Binarización de la imagen.

Con lo anterior la imagen se prepara para poder detectar los componentes en la misma, quedando así.


Rutina que detecta los componentes conexos

BFS

Para crear esta rutina, lo primero que hice fue programar un BFS iterativo que pudiera colorear, a partir de un pixel inicial, todos sus vecinos que comparten el mismo color. Esto lo hice en base a un pseudo código visto en clase y al código utilizado por la Dra. para el ejemplo con texto ASCII. 

El funcionamiento es el siguiente. Tenemos un punto de inicio en las coordenadas x, y. En base a ese punto, guardamos el valor de su pixel en una variable, para así poder recorrer todos los pixeles que son del mismo color y "marcarlos" de un color determinado. Mientras se recorren estos pixeles, contamos la cantidad de los mismos para después poder calcular el promedio que tiene esa figura con respecto al total de pixeles. 

Es necesario recalcar que solo se recorren los pixeles blancos, ignorando los negros para que los birdes sirvan efectivamente como limitantes del recorrido.

Un ejemplo del uso de DFS para pintar un contenido en un simple círculo:

Original

Iniciando en (0, 0)                        Iniciando en (300, 250)                    Iniciando en (180, 180)

Código de BFS:


Ahora, volviendo a la imagen original, se recorrerá cada pixel de la imagen binarizada, aplicando BFS a cada pixel negro que se encuentre y coloreando sus vecinos con un color aleatorio. Esto no significa que se correrá una vez la función para cada pixel, ya que cuando se recorra bfs desde un determinado pixel, se marcarán sus vecinos y ya no será necesario volver a usar bfs en ellos. Cada que se termine un recorrido, se asumirá que se pinto una figura completa, y se guardarán sus coordenadas x y y en listas por si se necesitan para calcular el centro de masa. Además se guarda su total de pixeles para poder obtener el promedio y sus respectivos ID.

Después de calcular todo lo anterior, aún tenemos que identificar el fondo. Se nos pidió asumir que la figura con mayor porcentaje de pixeles es el fondo, por lo cual se  hace uso de los promedios para encontrar la mayor y repintarla, ahora en gris. Lo restante es calcular los centros de masa para cada figura e imprimir los promedios.

Los centros de masa son calculados en base a las listas x, y mencionadas anteriormente y promediando cada unos para obtener el "centroide". Estos son desplegados como labels en Tkinter para poder etiquetar las figuras.

Resultado:



Se localizaron 5 objetos (etiquetados del 0 al 4). El objeto 0 es la orilla naranja, el objeto 1 es el círculo gris, el objeto 2 es la boca verde, el objeto 3 es el círculo celeste y el objeto 4 es el círculo azul. Las etiquetas 0 y 1 se superponen debido a que el centro de masa del círculo y el centro de masa del rectángulo naranja son similares. Las etiquetas como se mencionó anteriormente son colocadas como labels en Tkinter.

Los porcentajes aparecen del lado derecho de la captura, mostrando la figura 0 con un 28.04%, el círculo  siendo el mayor con un 58.30%, la boca con un 2.87% y los ojos con un 4.25% cada uno.

Por el tamaño del círculo, se asume que es el fondo, aunque en este caso no lo es.

La imagen de resultado sin las etiquetas pero con los centros de masa marcados como puntos negros:


Código de Detección de Componentes:


Otras imagenes con la detección de componentes en funcionamiento:

             Original                                    Previo a la Detección                    Formas Detectadas


 

Etiquetas y promedios


Original

        Previo a la Detección                                                  Formas Detectadas
,                    


Etiquetas y promedios


1 comentario: