12/10/08

Acabando

Finalmente he implementado la parte que faltaba por hacer, distinguir entre objetos parados y abandonados mirando si hay movimiento en los alrededores del objeto. Para esto lo lógico sería trazar un circulo alrededor del objeto y mirar dentro de él, pero normalmente las imágenes que vamos a tener no serán cenitales (desde arriba sin ningún angulo). En cámaras con angulo el circulo se convertiría en una elipse por lo que he rebuscado en los apuntes de mate del instituto para que introduciendo el ángulo de la cámara con la pared el programa obtenga la altura y anchura de la elipse.

Un vez obtenidos el alto y el ancho, como recorrer los pixels de una elipse es algo complicado y no es excesivamente importante ceñirse perfectamente a ella, simplifico recorriendo los pixels del rectángulo resultante de dichas altura y anchura.
Para detectar si hay movimiento dentro del rectángulo descrito utilizo otra vez la téctica de resta de imágenes , umbralizado y recuento de pixels blancos restando la imagen actual al fondo como ya comente en otros posts.

Vídeo de demostración:




como en vídeos anteriores:
tipo objeto - color


parado - amarillo

abandonado - rojo
parado_perdido - gris
abandonado_perdido - azul

Por otra parte tras hacer todo lo demás me he encontrado con que hay un montón de variables como el angulo de la cámara, los umbrales utilizados, los tiempos entre actualizado de background o el tamaño de trabajo de las imágenes que no se pueden fijar y difícilmente calcular porque dependen de la situación de la captura(posición de la cámara en el pc, angulo de la cámara, resolución .....).

Para hacer esto configurable al usuario he aprovechado las funciones que tiene OpenCV para el manejo de archivos xml de tal forma que se puedan tener varios archivos xml de configuración por ejemplo para cada cámara y cargar en cada caso el más conveniente, pudiendo también cargar una configuración por defecto.


Y con esto en principio parece que el proyecto estaría completo salvo algún retoque. Ahora sería el momento de ponerme con la memoria... :-s


Bueno, y como lo prometido es deuda, aquí van los vídeos del programa en funcionamiento para los otros ángulos de cámara de la escena que llevo usando todo este tiempo:







Y aquí un puñao de otras escenas desde distintos ángulos:


















17/6/08

Diferenciación entre los objetos que permanecen en la imagen y los que no.

Bueno, pues he hecho un hueco para subir lo que dejé hecho antes de los exámenes.

He hecho que la estructura donde guardo los objetos que detecto guarde una submatriz de la imagen con el objeto la cual comparo con la imagen actual para saber si los objetos siguen en el mismo sitio donde los he detectado, con lo que cuando se detecta que un objeto no esta tras un cierto margen para evitar fallos este se eliminará.

Además según esto he asociado a cada objeto un estado y un contador para ver cuanto tiempo llevan en ese estado si se necesita saber(no es tiempo real, es un contador simple, el tiempo es relativo a la frecuencia con la que se actualizan los objetos) , los distintos estados se reflejan en el siguiente diagrama:

Donde N>M ya que los objetos que consideramos abandonados son más peligrosos mientras que los parados son susceptibles de ser fallos de detección.

De momento la transición entre objetos parados y abandonados se hace automáticamente si el objeto sigue apareciendo en la segunda vez que se actualizan los objetos ya que me falta detectar el movimiento de alrededor del objeto para poder saber si el objeto esta o no abandonado.

A continuación muestro un par de vídeos de ejemplo, en los que he marcado los distintos tipos de objetos de la siguiente forma:

tipo objeto color

parado amarillo

abandonado rojo
parado_perdido gris
abandonado_perdido azul

Con este vídeo tendréis que agudizar la vista porque los recuadros amarillos no se ven muy bien, aparecen varios cuando llega el hombre de la mochila y al final del vídeo cuando pasa un grupo de hombres de derecha a izquierda.





En la versión final solamente marcare los objetos abandonados de color rojo y los parados de algún otro color más suave, ya que aunque no los detecte como abandonados son susceptibles de serlo.

Creo que haciendo lo comentado antes para la diferenciación de objetos parados y abandonados y par de retoques más ya estará el proyecto completo, pero esto y la memoria ya los haré este verano para presentarlo en septiembre ya que ahora estoy un poco ahogado de prácticas y exámenes y me es imposible dedicarle tiempo.

22/5/08

histmadrid

Mientras sigo dándole al proyecto aprovecho para colgar un enlace a una página para una práctica que estoy haciendo con dos compañeros para la asignatura de Sistemas Multimedia Distribuidos. La practica se llama histmadrid y consiste en hacer una página (con una serie de requisitos...CSS, javascript...) sobre la historia de alguna calle de Madrid. Nosotros hemos escogido la Plaza Mayor, este es el enlace:

http://plazamayordemadrid.freehostia.com

A ver si con esto consigo que suba algún puesto en google, para conseguir algún punto extra ;-)

Por cierto, la página esta en construcción, con lo que encontrareis secciones vacías, cosas que cambian de un día para otro, etc...

22/4/08

Reduce y Venceras !

Parece que he conseguido solucionar el problema de ralentización que tenia al usar el algoritmo de actualización de background.

La solución a resultado ser muy simple, por cada imagen que capturo del vídeo o de la webcam me creo una copia bastante más pequeña para trabajar con ella, una vez detectados los objetos como siempre pero usando la imagen pequeña, interpolo con el mismo factor que use para reducir las imágenes para obtener la posición de dichos objetos en la imagen grande y los muestro.

4/4/08

Esto empieza a coger color.

Una vez hecha la estructura para guardar los objetos, que me ha llevado más tiempo de lo esperado, como lo prometido es deuda, aquí está el vídeo que muestra los resultados:



Como se puede ver detecta las partes de la imagen que se quedan quietas un tiempo (y alguna cosilla que no :-( ). En cuanto cambie unas cuantas cosas del código que no me acaban de gustar mis siguiente tarea será diferenciar cuales de estas zonas que detecto siguen en la imagen con el paso de los frames.

Además como me sugirieron los profesores he aplicado un filtro de gauss para solucionar el problema de los objetos que se mostraban no-conexos, para esto además he bajado un poco el umbral para la umbralización. Aquí muestro los resultados del cambio.

antes:



después:



por último en el siguiente enlace que me ha pasado Gillermo(un alumno de la superior que hizo el pfc de sistemas con GAVAB) podéis ver unos vídeos de un italiano que usa el filtro de partículas para seguimiento con diferentes técnicas.

http://es.youtube.com/user/brizio73

5/3/08

Detección de objetos que se quedan quietos(II).

Ya he conseguido hacer funcionar más o menos bien el algoritmo que pensé para obtener la posición de los objetos que se quedan quietos, aunque no estaba del todo seguro porque me parecía un poco "pesado" dichos cálculos no han supuesto una ralentización apreciable ya que solo ejecuto esta parte cada vez que actualizo el fondo (cosa que hago cada cierto número de frames por ser esto si terriblemente pesado y por no ser necesario continuamente).

El algoritmo consiste en lo siguiente:
Voy recorriendo la imagen pixel a pixel, si es blanco lanzo un algoritmo recursivo que comprueba los pixels adyacentes(arriba, abajo, izquierda y derecha) y si son blancos se llama a si mismo para cada uno de los puntos blancos guardando en una lista dichos pixels y obteniendo de esta posteriormente el máximo y mínimo de la x y la y que delimitaran al objeto.

Una vez probado que funciona el algoritmo me dispongo a hacer ciertas mejoras ya que si un objeto no es conexo es detectado como varios, esto tengo pensado solucionarlo de dos formas. Una rebajando el valor del umbralizado, esto producirá más ruido en la imagen (pixels blancos sueltos) pero esto se soluciona desechando los objetos menores de cierto tamaño.
La otra forma es fusionar los objetos detectados con pocos pixels de separación.

Por otra parte he pensado en, en vez de ir pixel a pixel, ir de dos en dos o tres en tres, ya que, esto hará que sea más rápido pero no afectara al resultado ya que de esta forma como mucho se pierden pixels sueltos que no me interesa recoger.

En cuanto haga esto y meta los objetos detectados en una estructura para poder manejarlos, ya que de momento solo los dibujo según los voy detectando, colgare un vídeo en el que se pueda ver el resultado, porque como lo tengo ahora no se aprecia muy bien.

Mientras tanto os dejo una noticia relacionada con la visión artificial en los videojuegos.
link.

29/2/08

Detección de objetos que se quedan quietos.

Bueno, tras los exámenes he retomado el proyecto con como primer objetivo una vez conseguido la percepción de los objetos que se quedan quietos (vamos, conseguir una imagen binaria aislándolos) de detectarlos, esto es a partir de la imagen binaria obtener su posición.

Con esto me he atascado un poco porque se me ocurrían varias formas de hacerlo, pero no acababa de ver cual era la más apropiada para el problema, pero finalmente me decidí por una, aunque no estoy muy seguro de que sea la mejor opción no obstante sigo trabajando en esto pero aún no he obtenido resultados reseñables.

Mientras me pego un poco con las clases de c++ dejo el vídeo de GAVAB para que lo vea quien no lo halla visto (atención a la música, solo faltan Juanjo y Antonio corriendo a cámara lenta a lo David Jaseljof...jejeje).dddd






14/1/08

Percepción de objetos que se quedan quietos.

4 y 8 de Enero de 2008.

He comenzado a crear una clase historial para el fondo en la que en principio guardo un buffer de imágenes del fondo donde la ultima es la última tomada al actualizar el fondo y las anteriores corresponden a actualizaciones previas.
Además con cada actualización almaceno una imagen obtenida restando la primera y la última del buffer y umbralizada con un valor umbral relativamente alto para evitar que aparezcan los pequeños cambios. Con esto consigo que aparezcan en blanco solamente los objetos que se quedan parados y sigo detectándolos durante n-1 actualizaciones (siendo n el tamaño del buffer). Aquí dejo un vídeo que muestra el resultado:



La imagen de la derecha va mostrando la imagen obtenida como he explicado anteriormente.


Este método me permite cuanto mayor sea el buffer poder distinguir mejor los objetos que se quedan quietos, pero al aumentar el buffer también aumenta la memoria utilizada y se tarda más en detectar los cambios.
Tras esto me he propuesto dar más funcionalidad a esta clase haciendo que en cada actualización detecte los objetos que aparezcan y guarde en algún tipo de registro las posiciones de los objetos detectados, teniendo en cuenta que si un objeto no permanece en blanco en la imagen n-1 actualizaciones es que se ha movido (el número de actualizaciones que considerare para este caso probablemente sera menor de n-1 para evitar que algún tipo de interferencia provoque que se deje de detectar un objeto).

Curiosidades.

.

Os dejo el enlace de una noticia que he visto en un blog y me ha parecido interesante sobre un nuevo uso que le van a dar en PCs al procesador Cell que usa la PlayStation 3. Además trae un vídeo en el que usan un interfaz tipo "minority report".

Pulsad la imagen para verlo.


2/1/08

Nuevo enfoque para detectar los objetos en movimiento.

Tras estar haber utilizado las funciones para actualización de fondos se me ha ocurrido cambiar la forma en la que obtenía las imágenes en binario con los objetos que se movían en la imagen en blanco y el resto en negro.

En vez de restas sucesivas con la imagen anterior, he aprovechado el echo de estar usando actualización de fondo para ir restando en cada iteración la imagen actual con el fondo. Esto me genera una serie de ventajas respecto a la implementación anterior, principalmente que de esta forma puedo obtener figuras sólidas y no siluetas como anteriormente y además las figuras siguen siendo detectadas cuando se quedan quietas hasta que no se integran con el fondo.

Como única desventaja he podido apreciar que esta técnica introduce algo de ruido, pero las ventajas me hacen pensar que esta forma me será mucho más útil a la hora de hacer el seguimiento y el ruido que surge es casi despreciable.

En el siguiente video se puede apreciar el resultado:


Tras esto me voy a dedicar a crear algún tipo de historial del fondo para detectar cuando se producen cambios, pero antes voy a rehacer mi código ya que debido a que he ido haciendo muchas pruebas con varias cosas al final ha quedado muy desordenado y complicado de depurar.