26/11/07

Primeros pasos con OpenCV (8)

22, 23, 25 y 26 de Noviembre.

Utilizando las funciones mencionadas anteriormente para convertir imágenes a escala de grises, hacer la resta de dos y pasar a binario, las he combinado en ese orden para obtener imágenes en las que solo aparece lo que va cambiando de las imágenes en blanco con fondo negro para usarlas en el filtro de partículas que debo implementar.

Antes de nada con esto me he dedicado a investigar las funciones de detección de movimiento de que dispone opencv. Con estas funciones he modificado mi código para que detecte la direccionalidad del movimiento en una zona concreta.

Para esto he utilizado las funciones :

void cvUpdateMotionHistory( const CvArr* silhouette, CvArr* mhi,
double timestamp, double duration );
void cvCalcMotionGradient( const CvArr* mhi, CvArr* mask, CvArr* orientation,
double delta1, double delta2, int aperture_size=3 );
double cvCalcGlobalOrientation( const CvArr* orientation, const CvArr* mask, const CvArr* mhi,
double timestamp, double duration );
Con estas funciones y utilizando región de interés para limitar los resultados a una zona en concreto he calculado la dirección en la que se producen los movimientos en una zona y lo he mostrado mediante una linea como se puede ver en el siguiente video:



En la parte derecha se puede observar el historial de movimiento que se va actualizando con cvUpdateMotionHistory, a la izquierda se puede observar la imagen que va marcando la orientación creada a partir del historial con cvCalcMotinGradient y abajo está la imagen en binario en la que he dibujado una línea indicando la dirección del movimiento dentro del recuadro con el angulo obtenido de cvCalcGlobalOrientation.

Una de las mayores dificultades que he tenido ha sido escoger los parámetros para pasarle a las funciones, ya que en los manuales no queda muy claro para que se usan algunos de ellos. Para resolver esto me ha sido de gran ayuda de un ejemplo que viene con opencv llamado motempl.cpp.

El otro gran problema que me ha surgido utilizando estas funciones es que creaba y liberaba en cada iteración las imágenes de historial y de orientación como venia haciendo con las otras imágenes usadas sin darme cuenta de que de esa forma no se actualizaba el historial, con lo que no obtenía resultados.

Una vez resueltos estos temas he utilizando las funciones para dibujar de opencv y repasando un poco de geometría básica he conseguido obtener correctamente la dirección del movimiento en una zona.

20/11/07

Primeros pasos con OpenCV (7)

19 de Noviembre.

Ahora me he dedicado a acceder a los píxeles individuales de una región de las imágenes para por ejemplo calcular el número de pixels blancos dentro de dicha región, cosa que será de utilidad para desarrollar el filtro de partículas entre otras cosas.

Entre las distintas formas disponibles de acceder individualmente a los pixels he escogido la siguiente:
IplImage* img  = cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
int step = img->widthStep/sizeof(uchar);
uchar* data = (uchar *)img->imageData;
data[i*step+j] = 111;
Por lo que he leido esta es la forma más eficiente y sencilla de hacerlo, aunque también existe otra forma con C++ usando una clase que resulta aún más sencilla.

Además para probar esto sobre el ejemplo anterior le he añadido una "trackbar" a la ventana donde muestro las imágenes umbralizadas para poder variar el factor de umbralizado durante la ejecución y asi poder probar mejor el programa.

En el siguiente vídeo se puede ver el resultado:


El programa cuenta el número de pixels blancos que hay en la zona delimitada por el recuadro dibujado en la imagen y lo muestra por la consola con el número de pixels blancos del total del recuadro. Se puede apreciar como aumenta el número cuando hay más pixels blancos en el recuadro.

19/11/07

Primeros pasos con OpenCV (6)

16 y 17 de Noviembre.

Pese a modificar la forma de ir leyendo las imágenes el proceso sigue siendo mucho más lento que con un vídeo, por lo que me he decidido convertir las secuencias de imágenes en vídeos para trabajar con ellos de una forma más cómoda.

En un primer momento cree un programa utilizando la propia libreria OpenCV con este fin, pero los resultados no fueron los esperados, ya que el programa creaba un archivo con extensión avi pero con 0 bytes. El código básicamente hace lo siguiente:

writer=cvCreateVideoWriter( opciones);

for i=1 to numImagenes {
img=cvLoadImage(ruta);
cvWriteFrame(writer,img);
cvReleaseImage(&img);
}
cvReleaseVideoWriter(&writer);

No se porque no funciona, pero tras horas de intentarlo al final he utilizado un programa llamado VirtualDub que tiene licencia GNU y puede descargarse de www.virtualdub.org y finalmente he convertido las secuencias de imágenes en vídeos con facilidad.

Tras esto he probado los vídeos con mi código y he comprobado que funcionan bien y a una velocidad correcta.

También he aprovechado estos vídeos para probar el programa de ejemplo de actualización de fondos (background) y he obtenido unos resultados bastante interesantes que me pueden servir en el proyecto, pero la velocidad del algoritmo es bastante lenta y los vídeos no se muestran a una velocidad normal. Tengo que probar si esto se debe al resto de cosas que hace el programa o a la actualización de fondo en si.

14/11/07

Primeros pasos con OpenCV (5)

12 y 13 de Noviembre.

Siguiendo con el ejemplo anterior he hecho que mi programa de prueba valla obteniendo la resta de cada imagen en escala de grises con la imagen anterior del vídeo con la función cvSub y valla mostrando la imagen resultante, elresultado es el siguiente:



La en la parte de superior se pueden ver las imágenes a color y en escala de grises y en la inferior la imagen resultado de la resta y en binario(de izquierda a derecha). El resultado de la imagen resta no es muy bueno ya que no se ven muy bien los cambios.

Tras esto he modificado mi código para que en vez de leer los frames de un vídeo valla leyendo las imágenes obtenidas de http://www.cvg.rdg.ac.uk/PETS2006/data.html que contienen ejemplos de abandono de equipaje en una estación de tren.

No se si por que las imágenes son más grandes que las de los vídeos que he usado hasta ahora o porque de la forma que lo he implementado el programa va leyendo los nombres de las imágenes de un archivo de texto, pero si mantengo las cuatro ventanas anteriores las dos que quedan más atras van a "tirones", por tanto próximamente cambiare la forma de obtener los nombres de los archivos para ver si es lo que ralentiza el proceso.

Por otro lado me he dado cuenta de que estaba haciendo las restas del revés y al cambiarlo he obtenido una mejora en las imágenes resultado de esta. El resultado es el siguiente:




A la izquierda se puede ver la imagen resultado de la resta y a la derecha en escala de grises.

10/11/07

Primeros pasos con OpenCV (4)

9 y 10 de Noviembre

Una vez convertidas las imágenes a escala de grises las he umbralizado convirtiéndolas a binario usando la función cvThreshold con el flag CV_THRES_BINARY o CV_THRES_BINARY_INV (segun se quiera una cosa o otra). Esta función tiene dos parametros de tipo double que marcan el "valor de Threshold" y el máximo, he ido probando y con valores alrrededor de 100 y 250 respectivamente se obtienen buenos resultados, pero depende mucho del tipo de video y sobre todo del brillo.

Una vez hecho esto he probado la función cvRectangle que dados dos puntos ( creo q el inferior izquierdo y el superior derecho ) y un color en RGB dibuja un rectángulo en una imagen, esto resultara útil a la hora de depurar el programa.

Primeros pasos con OpenCV (3)

8 de Noviembre

Como la librería OpenCV no tiene otra forma de manejar eventos, he mantenido el cvWaitkey() y he ido probando valores hasta que el vídeo se veía a una velocidad razonable.

Tras esto me he dedicado ha convertir las imágenes del vídeo a escala de grises utilizando la función cvCvtColor que en un principio me daba un error en tiempo de ejecución porque para que esta funcionase la imagen destino debía haber sido creada previamente con el mismo ancho y alto que la original y con 8 bits.

Con esto conseguí que desapareciera el error, pero la imagen salia invertida, cosa que tras investigar un poco con el google descubrí que se solucionaba modificando un campo que tienen las imágenes q indica la dirección al de la imagen de origen.

5/11/07

Primeros pasos con OpenCV (2)

Puente de todos los santos (1-4 Noviembre 2007)

Finalmente me he dado cuenta de que el programa si funcionaba correctamente pero era tan rápido que no daba tiempo a ver nada.

Esto lo he solucionado colocando un cvWaitKey(40) al final del bucle para que de tiempo a verse la imagen. Ahora el programa funciona correctamente, pero no me convence del todo la solución ya que la función usada espera una que se pulse una tecla...

Primeros pasos con OpenCV

31 de Octubre del 2007

Creación de un programa que muestre los frames de un vídeo almacenado en disco.

Para poder compilar un programa en eclipse usando las librerías de openCV hay que añadir lo siguiente en las propiedades del proyecto:

-En windows:

En GCC C++ Compiler->Directories
Include Paths -I:

"C:\Archivos de programa\OpenCV\cv\include"
"C:\Archivos de programa\OpenCV\cvaux\include"
"C:\Archivos de programa\OpenCV\cxcore\include"
"C:\Archivos de programa\OpenCV\otherlibs\highgui"
"C:\Archivos de programa\OpenCV\otherlibs\cvcam\include"
En
MinGw C++ Linker ->Libraries
Libraries -I :
cv , cvaux , cxcore , highgui y cvcam
Y en Libraries Search Path (-L) añadir "C:\Archivos de programa\OpenCV\lib"

En linux:

C/C++ build -->Settings. En la ventana derecha:
• GCC C++ Compiler --> Directories. En "Include Paths (-I)" añadir el
path: /usr/include/opencv
• GCC C Compiler --> Directories. En "Include Paths (-I)" añadir el
path: /usr/include/opencv
• GCC C++ Linker --> Libraries:
• En "Libraries (-l)" añadir las librerías una por una que se incluyen en el
proyecto (Hay 4: cv, cvaux, highgui y cxcore).
• En "Library Search Path (-L)" añadir el path: /usr/local/lib
• GCC C++ Assembler --> General: En "Include Paths (-I)" añadir el
path: /usr/include/opencv

Creo un programa que tras unos problemas con eclipse consigo compilar, pero el resultado obtenido no es el esperado, no se ve nada ni aparece la ventana que debería crearse.

Comienzo del Proyecto.

29 y 30 de Octubre del 2007.

Comienzo el proyecto : "
Detección de objetos abandonados en estancias controladas" del grupo GAVAB de la URJC con Antonio Sanz y Juan José Pantrigo como tutores.

Resumen: En este proyecto se pretende desarrollar una aplicación informática orientada a la seguridad que detecte el abandono de objetos en zonas de paso.

En estos días he tenido una primera toma de contacto con los laboratorios del GAVAB y he instalado en alguno de sus ordenadores lo necesario para la realización del proyecto (por lo menos de momento), eclipse + CDT y openCV.

Finalmente para instalar eclipse en windows he usado una compilación que incluye el CDT y el compilador mingw llamada
WASCANA y he descargado he instalado la librería OpenCV de la web.

En ubuntu además del eclipse con CDT he instalado una serie de paquetespara poder compilar con openCV (libcv, ffmpeg, gstreamer).