Archivo

Posts Tagged ‘cámara’

La PlayStation®Eye

junio 11, 2010 1 comentario

Hasta hace poco veníamos usando una cámara web prestada por nuestro tutor, la PS3 Eye, desarrollada por Sony para su consola PlayStation 3. Según nos comentaron, esta cámara es muy utilizada para sistemas de visión por computadora por presentar distintas características que la hacen muy superior al resto de las cámaras USB del mercado, siendo capaz de proveer en teoría hasta 60fps a una resolución de 640×480 pixels y 120fps a 320×240 pixels.

Exclusivamente para Windows, existen unos drivers desarrollados por Code Laboratories que permiten alcanzar 640×480@30fps (por compatiblidad con muchos de los programas que utilizan cámaras web en Windows). Esta empresa también provee, gratuitamente, un SDK para obtener 640×480@60fps (la cual se podría utilizar desde nuestro código modificado del reacTIVision, en Windows, para mejorar el framerate).

PS3 Eye

La PS3 Eye

Recientemente encontramos un artículo muy interesante en el que se explica qué es lo que hace a esta cámara superior al resto y por qué sería difícil encontrar una mejor (restringiéndonos al estándar USB 2.0 actual).

Básicamente, la cámara brinda la opción de enviar el video sin comprimir (RAW), lo que hace que se minimice la latencia (tiempo entre que la imagen “ocurre” y está disponible para utilizar en la PC). Entregar 640×480@60fps en formato RAW está al límite del ancho de banda que se puede lograr con USB 2.0, por lo que sería inútil esperar una cámara USB 2.0 con mayores prestaciones que garantice una baja latencia.

Actualmente estamos intentando conseguir una de estas cámaras para uso exclusivo nuestro. Luego, sería necesario ver cómo hacerla funcionar en las otras platafromas que intentaremos soportar (Linux y Mac OSX).

Categorías:Hardware Etiquetas:

Captura exclusiva del video por reacTIVision

Un problema que presenta reacTIVision respecto a ARToolKit, es que al acceder a la cámara desde su propio ejecutable (que se comunicará con nuestra aplicación por medio de un socket) un segundo proceso (nuestra aplicación) no tendría acceso, en principio, a la imagen original por ya estar siendo consumida.

Poder utilizarla podría ser interesante por ejemplo para agregarla a la salida visual de nuestra aplicación, dibujando la interfaz de usuario “aumentada” sobre la imagen capturada original, en caso de no estar usando un proyector. Utilizando ARToolKit esto no es un problema, dado que la herramienta se presenta en forma de una librería cuya funcionalidad se accederá (básicamente) invocando a una función que recibe un frame de imagen como parámetro y devuelve la información sobre la ubicación de los fiducials. En este escenario, la imagen puede utilizarse posteriormente como se quiera.

Por esto, antes de continuar quisimos estudiar la factibilidad de poder acceder a esta imagen también desde nuestra aplicación. Investigando un poco, encontramos software como SplitCam para Windows, que crea una segunda cámara virtual con la misma imagen que captura la original. Si bien podríamos buscar aplicaciones similares para las otras plataformas que intentaremos soportar (Mac OSX, Linux) preferimos encontrar una solución que sea en cierta medida independiente de la plataforma.

Para esto, estudiamos los fuentes del reacTIVision y encontramos el lugar donde la imagen es obtenida de la cámara y comenzada a procesar. La idea sería entonces tomar esa imágen antes de continuar el procesamiento y hacérsela llegar una aplicación externa.

La primer idea fue enviar el frame de video a una aplicación de ejemplo en openFrameworks utilizando OSC, ya que este será el protocolo de comunicación utilizado por los distintos módulos de nuestra aplicación. Para eso, se extendió el addon ofxOSC de openFrameworks para soportar el tipo de datos blob y poder enviar información binaria. Debido a la restricción de tamaño de los paquetes UDP (protocolo sobre el que se implementa OSC en ofxOSC), fue necesario dividir cada frame en una serie de mensajes de OSC enviados por separado, uno para cada línea horizontal de imagen.

El resultado de esta implementación no fue positivo: un gran porcentaje de los paquetes se perdían y los frames llegaban a la aplicación con una velocidad mucho menor (unos 10fps) a la que se generaban:

Fue ahí que hicimos el siguiente cálculo: estábamos intentando enviar 640 * 480 (resolución) * 3 (bytes por pixel en color 24-bits) * 30 (fps) = 26,4 MB/s utilizando los servicios de red. Sin mucha esperanza, hicimos una prueba adicional intentando enviar esa información por TCP y obteniendo resultados también negativos: si bien los paquetes ya no se perdían por ser TCP un protocolo que resuleve este problema, los frames tampoco llegaban en tiempo real.

La tercer alternativa, que finalmente tuvo éxito, fue utilizar memoria compartida entre procesos para hacer una copia del frame obtenido y poder accederlo desde nuestra aplicación. Para esto, se utilizó la librería multi-plataforma POCO (ya incluida en openFrameworks y que agregamos al proyecto de reacTIVision) compartiendo un mismo segmento de memoria entre el módulo reacTIVision (que realizaría la escritura) y nuestra aplicación (que leería la información escrita). La implementación resultó ser eficiente, entregando los frames en tiempo real y prácticamente sin variar la utilización del CPU.