Mostrando entradas con la etiqueta prototipo. Mostrar todas las entradas
Mostrando entradas con la etiqueta prototipo. Mostrar todas las entradas

miércoles, 3 de marzo de 2010

Problematica en desarrollo de prototipos con ARToolkit

ARtoolkit parece ser la mejor herramienta para hacer el trabajo que queremos, esta desarrollada especialmente para reconocer figuras de manera sencilla, por lo tanto, parece lo mejor incluir esas figuras en nuestro prototipo de "mouse virtual" y que nuestro programa las interprete como quiera (flecha a la izq, derecha, arriba , abajo y click).


Viendo que Artoolkit es la herramienta que mas se estaría ajustando empezamos a hacer pruebas. Obtuvimos un resultado muy bueno bajo windows y a su vez un resultado muy malo en linux. En windows la performance del ejemplo "multiTest" (ejemplo contenido en el SDK estandar de ARToolkit) es muy buena y alentadora para poder ejecutarla en el hardware de la XO, la carga de la CPU ronda entre 10 -  20%. Por otro lado en linux la situación es muy diferente, la carga de la CPU al ejecutar "multiTest" es de 100%.
Ya que se usa el mismo hardware en ambas pruebas decidimos comenzar a investigar cual puede ser la causante del problema.

1- Driver de la tarjeta de video. En windows y en linux el driver de video no es el mismo evidentemente, quizás esta pueda ser una causante del problema. Lamentablemente esta hipótesis no tiene demasiada solución ya que se esta usando el driver del fabricante (nvidia) y siempre suele ser el mas performante por motivos obvios. Lo que se nos ocurre para mitigar este riesgo es probar en linux pero usando otro hardware que en particular tenga una tarjeta de video de otro fabricante (ATI sería lo mejor, ya que la
especificación del driver de video es libre y existen implementaciones de código abierto muy buenas).

2- Implementación de opengl. Investigando acerca del problema de la carga de CPU con Artoolkit nos encontramos con que alguien tenia el mismo problema. Resulta que esta persona armo unos ejemplo usando Artoolkit. Lo probo en windows usando glut32 (implementación oficial del utility kit para desarrollar en opengl) y freeglut (implementación libre de opengl que estamos usando en linux actualmente). El resultado era que usando glut32 la aplicación tenia un carga de CPU muy baja y usando freeglut una
carga muy alta. Vista esta situación decidimos compilar ArtoolKit en windows 2 veces, una usando glut32 (que es la distribución de ArtoolKIT estándar que ya probamos en nuestras maquinas) y otra usando freeglut. Una vez compilados los ejemplos corrimos "multiTest" y para nuestro asombro no hubo diferencia, funcionaba igual de bien con glut32 que con freeglut. Aquí nos quedo la interrogante de que podría estar pasando...

a- Las operaciones que hacen funcionar mal el ejemplo en freeglut no son usadas en multiTest, en este caso a nosotros no nos importa, porque lo que queremos desarrollar se basa en multiTest y no en el ejemplo encontrado en la web.

b- La implementación de las operaciones que usa multiTest en la implementación freeglut en windows es diferente a la implementación en linux, y freeglut es realmente nuestro problema.

c - El problema no es la implementación de glut y todavía no descubrimos cual es.

d - Otra posibilidad es que el codec de video que estamos usando en linux no esta funcionado bien. Al configurar Artoolkit en linux nos da la opción de usar GSstreamer o de usar Video4Linux. Este último no lo hemos podido hacer funcionar aun y quizás funcione mejor que Gstreamer,  no lo sabemos aun, aunque en todos lados recomiendan más usar Gstreamer.

Luego de probar todas las posibilidades nos dimos cuenta de que el problema no se correspondía con ninguna de estas hipótesis, sino que la función que devuelve los frames capturados por la cámara funciona mal bajo linux y se estaban procesando alrededor de 170 frames por segundo, por eso es que la performance
era tan mala. Para resolverlo basto con agregar un sleep hasta encontrar el punto en el que la aplicación procesa 10 fps aprox.

Decidimos usar Artoolkit para hacer el seguimiento de los marcadores y una vez que un marcador no es detectado entonces se convierte la imagen a un formato manejable por OpenCV y se aplica un algoritmo sobre el marcador no reconocido para poder determinar si hay un objeto conocido (llámese mano) tapando el marcador o si no hay nada. En caso de que se detecte una mano tapando el marcador se toma como que el usuario esta presionando el marcador, de lo contrario se ignora.


En este momento estamos trabajando en el algoritmo usando OpenCV para determinar si hay una mano sobre el marcador o no. Creeemos que usar colores brillantes es una buena idea y es performante, difícilmente se confundan ya que toda nuestra escena es una hoja blanca con marcadores en blanco y negro.

Muchos temas interesantes a resolver...

martes, 28 de abril de 2009

Construyendo un prototipo con openframeworks

Comenzamos con la construcción de un prototipo básico. Por el momento lo que logramos hacer es tomar como entrada la camara web y reconocer contornos y orientaciones de los objetos presentados.

También se tienen algunas propiedades de los objetos, como por ejemplo el área de los mismos (por el momento no consideramos objetos en 3 dimensiones sino que trabajamos con dibujos en 2d) y estamos trabajando para reconocer figuras tales como cuadriláteros, triángulos, círculos, etc.

Encontramos un paper de Desarrollo de interfaces naturales para aplicaciónes dirigidas a niños en el cual se plantea la siguiente estrategia de reconocimiento.

Se detalla en este apartado el proceso de reconocimiento y las técnicas empleadas en cada
una de las fases. El sistema es capaz, por el momento, de reconocer forma, color y orientación
de cartulinas repartidas sobre el escritorio (fondo blanco uniforme); para llevarlo a cabo se han implementado algoritmos estándar básicos de reconocimiento visual.

El proceso es el que se explica a continuación (ver Figura 1).


1. Captura. Como se ha comentado, el hardware de captura visual consiste en una webcam
conectada al PC
mediante puerto USB. Una llamada a la librería “VideoForWindows” de
Windows, devuelve un array de píxeles de
dimensión 320 x 200, en la cual cada píxel es
representado por sus componentes de color
RGB (Rojo, Verde y Azul) de 8 bits de resolución
en cada componente.



2. Umbralización de la imagen. Se genera un valor de umbral automático que representa un
valor de luminancia (entre 0 y 255) que separa el escritorio de los elementos tangibles. Se
genera un array binario. Para eliminar ruidos de señal de vídeo se aplica un filtrado de
mediana.


3. Visión retinal. Esta fase se encarga de la detección de movimiento. El objetivo es no mostrar
en pantalla resultados “falsos” y esperar hasta que el usuario haya terminado
de realizar su
disposición de elemento tangibles.



Figura 1. Flujo del proceso de reconocimiento visual


4. Segmentación de la imagen. Con la imagen estática, y a partir del array binario, se cuenta
y localiza cuántos elementos tangibles hay sobre el escritorio. A continuación se aplica el
algoritmo estándar de etiquetado de blobs (los blobs son puntos o regiones en una imagen que pueden ser tanto mas claras o mas oscuras que sus alrededores
).


5. Parametrización de los blobs. Una vez individualizados y etiquetados los blobs, se
parametrizan: se obtienen los valores que caracterizan las propiedades físicas de los
elementos tangibles que se han detectado en el proceso de segmentación: Área, contorno,
orientación, color.