miércoles, 15 de mayo de 2013

Laboratorio 10: Detección de Movimiento

Para la tarea, se nos pidió realizar una detección de movimiento en una serie de frames, utilizando métodos propios sin ayuda de librerías de visión en los procesamientos. Lo que realicé fue lo siguiente.

Las herramientas usadas fueron:
  • PIL: Para leer los frames, dibujar en ellos y guardar los resultados.
  • Numpy: Para realizar cálculos rápidos y eficientes a las matrices de las imágenes.
  • Pygame: Para mostrar en tiempo real la animación y la detección del movimiento del programa.
Generar animaciones. 

Utilizando principalmente PIL para su creación, generé aleatoriamente coordenadas dentro de un tamaño definido de una imagen, y programé rutinas sencillas para mover un rectángulo de una a otra siguiendo los ejes principales. Cada movimiento se almacena como un frame por separado en una carpeta ("output_frame_%d.png", donde %d es el número del frame en cuestión). 

Nota: Inicialmente, esto se convertía en un video, pero para eliminar la necesidad de utilizar OpenCV u otra librería para leer los frames del video, utilicé directamente las imágenes anteriores como frames para procesar. 

El resultado de ver las imágenes una tras otra es una sencilla animación de un cuadrado en movimiento por la pantalla:


Código usado:



Detección de Movimiento


Para detectar movimiento lo primero que hice fue obtener los cambios que ocurrían en cada dos frames, calculando la diferencia entre ellos posición por posición (valor absoluto) y binarizando los resultados. Normalmente en aplicaciones reales existiría ruido aún después de realizar esto, por lo que habría que hacer un blur/smooth para eliminarlo, pero en el caso de las animaciones sencillas usadas no hubo problema.

Lo siguiente es la parte importante. Con el procedimiento anterior, se obtiene una imagen totalmente negra donde no hubo cambios y blanca donde lo hubo. Originalmente lo que se hace aquí es buscar bordes, y obtener las bounding box de los mismos. Eso lo realicé en mi proyecto, por lo que esta vez quisé intentar algo diferente. 

Cree una especie de grid o rejilla cuadriculada en toda la imagen (de un tamaño definido, modificable).

Rejilla de 5 pixeles

Rejilla de 15 pixeles

Rejilla de 20 pixeles


Con esta rejilla, es posible dividir los pixeles de la imagen en cuadrantes más grandes. Utilizando la imagen binarizada (matriz de la imagen) se buscan aquellos cuadrantes que contienen algún pixel blanco en dicha imagen (por ahora con que uno solo toque basta, pero es modificable). 

Sí por lo menos un pixel blanco está dentro del cuadrante, el cuadrante se pinta de verde, indicando que algún objeto pasó por ahí. Naturalmente, cuando un objeto es de un cierto tamaño, puede estar contenido en más de un cuadrante.

Dirección de Movimiento


La dirección del movimiento es otra cosa posible de determinar. Conociendo dos posiciones (anterior y actual, o actual y siguiente) de un objeto es posible calcular el ángulo hacia donde se movió, y por lo tanto a partir de el la dirección de movimiento (izquierda, derecha, arriba, abajo). El programa se limita a esas 4, pero cambiando los rangos de los ángulos es posible agregar más direcciones, mientras sean en dos dimensiones (x o y,  dirección en z no está implementado).

El programa coloca una flecha (ascii art) apuntando hacia la dirección del movimiento en el centro del objeto e imprime en la terminal su dirección y angulo.


Ejemplo de funcionamiento:






Código:


1 comentario:

  1. Detección de movimiento de un objeto, movimiento 2D, generador propio
    ->
    12 pts.

    ResponderEliminar