jueves, 18 de julio de 2013

Reporte de Proyecto Final

En esta entrada hablaré sobre el proyecto final que mostré en la clase de visión computacional.

El proyecto que elegí fue el reconocimiento de gestos de las manos usando Python y OpenCV en Ubuntu 12.04. Lo más relevante del proyecto se encuentra en la presentación que di en clase, la cual adjunto a continuación:




FORTALEZAS
Con el programa se logra mover el cursor de la computadora y hacer click's derecho e izquierdo.

Lo que descubrí fue que se necesitó menos código del que esperaba. Con relativamente pocas líneas de código, gracias a OpenCV se logra hacer el procesamiento de las imagenes de la mano. En este procesamiento se aplican algunos filtros para lograr obtener una mejor imagen con la cual trabajar y además se realiza el convex hull para, en pocas palabras, rastrear los dedos de la mano.

Para el movimiento del cursor se utilizó xdotool, que como lo dice la página de ubuntu manuals permite simular actividad del mouse, entre otras cosas (http://manpages.ubuntu.com/manpages/lucid/man1/xdotool.1.html)

La combinación del procesamiento en Python+OpenCV y xdotool dió un buen resultado que permite mover el mouse mediante las coordenadas que se obtienen del procesamiento de las imagenes.

DEBILIDADES
Lo que se notó, y se planea mejorar, es la identificación de la mano, ya que el código procesa todos los objetos que se le pongan en frente. Debido a esto, el cursor puede descontrolarse un poco, o se puede dificultar un poco la realización de las demás acciones.

Para esto, así como lo sugirió la Dra. Elisa Schaeffer, sería útil aplicar un filtrado usando el método de medidas de similitud que se usó en las tareas de laboratorio de visión computacional. De esta forma se podría crear una "plantilla" que le diga al programa qué forma debería tener una mano, y así al procesar una imagen, descarte todo aquello que no tenga forma de mano.

PLANES A FUTURO
Mi deseo es entender y aprender más sobre reconocimiento en visión computacional. Esta es un área que me interesa mucho y quisiera poder trabajar más con cosas relacionadas en un futuro.

En cuanto a lo hecho en este proyecto, me gustaría añadir más funcionalidades y me gustaría ver que tuviera un uso provechoso con personas que lo necesiten.

jueves, 11 de julio de 2013

Detección de Agujeros

Para esta tarea lo que hicimos fue detectar agujeros en una imagen. Como van a ver, es algo bastante simple.

TEORÍA
El método para saber si en una imagen hay un agujero (o agujeros) es el siguiente:

1) Realizar la sumatoria de todos los valores de cada fila y cada columna (por separado cada fila y columna) de la matriz de pixeles. Se podrán presentar dos casos:

  • Si hay agujeros oscuros, la suma de la columna y la suma de la fila donde se encuentra el agujero será un valor bajo (colores relativamente más oscuros)
  • Si hay agujeros claros, la suma de la columna y la suma de la fila donde se encuentra el agujero será un valor alto (colores relativamente más claros)
Por si es confuso, la siguiente imagen puede ayudar a entender de qué hablo al decir que se deben realizar las sumatorias de las filas y columnas:



aquí además podemos suponer que hay un posible agujero claro en la intersección de la última fila y la última columna, ya que la sumatoria de la última fila es 30 y la sumatoria de la última columna es 16, ambas son las mayores en relación a todas las demás.

El número de fila y columna se tomarán como coordenadas de referencia para saber en qué pixel hay un posible agujero.

2) Después de tener las coordenadas donde posiblemente hay un agujero, debemos ubicarnos en el pixel con esas coordenadas y usando una máscara definida por nosotros mismos, realizar una convolución como también lo hicimos en el post anterior. La diferencia aquí es que debemos hacer un promedio de los pixeles vecinos. Este promedio se va a comparar contra un umbral establecido por nosotros mismos:

  • En el caso de agujeros oscuros, el umbral debe ser relativamente bajo. Esto porque si se detecta un agujero, el promedio de la vecindad debe ser oscuro.
  • En el caso de agujeros claros, el umbral debe ser relativamente alto. Esto porque si se detecta un agujero, el promedio de la vecindad debe ser claro.
Para fines de simplicidad, se usará una máscara de 3x3 cuyos valores son únicamente 1's


Como vemos, el promedio del pixel y sus vecinos es relativamente alto (mayor a los demás pixeles).
De aquí podemos deducir que encontramos un agujero. ( Cabe remarcar que en los casos donde el agujero es oscuro las sumatorias y los promedios dan valores relativamente bajos).


CÓDIGO
Lo primero es pasar la imagen a escala de grises tal como sucedió en el post anterior. Lo añadido para este programa es que utilizó una matriz de numpy para almacenar los valores de la imagen para poder trabajar más cómodamente.

Sobre esta matriz, podemos usar el método sum, para obtener las sumatorias de filas y columnas.

Para saber qué pixeles son candidatos a ser agujeros se hace lo siguiente para ambos casos:

  • Para agujeros oscuros, se busca un pixel que se MENOR al pixel anterior a él, y al pixel próximo a él.
  • Para agujeros claros, se busca un pixel que sea MAYOR al pixel anterior a él, y al pixel próximo a él.
Esto nos ayuda a quedarnos sólo con los pixeles más oscuros de la imagen.

El código es el siguiente:
///
///

Cuando hay posibles agujeros, dibujo una línea en la columna y otra línea en la fila del candidato.

//

//
Dentro de este mismo ciclo, me aseguro de que el candidato sea en realidad un agujero mediante el promedio de los vecinos. La subrutina que usé para esto es la siguiente:

//

//

Y es todo. Si el método anterior encuentra un agujero, pinta un pequeño cuadrado sobre él.

Los resultados son los siguientes:

Agujeros oscuros:









Agujeros claros:



Aquí el código completo: