UNIVERSITAT JAUME I II31 SISTEMAS INFORMÁTICOS INGENIERÍA INFORMÁTICA Curso 2011 2012 Memoria Técnica del Proyecto Detección y seguimiento de objetos en movimiento Proyecto presentado por el Alumno Adriana Lopataru Dirigido por Raúl Montoliu Castellón, a 15 de septiembre de 2012 -2- RESUMEN Este proyecto consiste en implementar una técnica de detección y segmentación de objetos en movimiento conocida como Sakbot, presentado en [1] (“The Sakbot System for Moving Object Detection and Tracking” de Rita Cucchiara, C. Grana, G. Neri, M. Piccardi y A. Prati). Las posibles aplicaciones están relacionadas con temas de video vigilancia. Sakbot es un sistema para la detección de objetos en movimiento y seguimiento en videos de vigilancia de tráfico. El sistema esta dotado de técnicas de detección robustas y eficientes, cuyas características principales son el refresco estadístico y basado en conocimiento de la imagen de fondo y el uso de información HSV para la supresión de sombras. Para el proyecto se ha utilizado un trozo de un video de vigilancia de tráfico, obtenido desde la página http://www.ee.cuhk.edu.hk/~xgwang/MITtraffic.html. En esta página se pueden encontrar distintos vídeos de tráfico filmados con una cámara estática. La motivación del proyecto consiste en detectar todos los objetos en movimiento en videos de vigilancia para su posterior utilización en módulos de seguimiento. -3- PALABRAS CLAVE Detección movimiento, Seguimiento, Seguridad, Procesamiento imágenes, OpenCV. -4- Índice 1. INTRODUCCIÓN ...................................................................................................... - 10 1.1 MOTIVACIÓN .......................................................................................................... - 10 - 1.2 CONCEPTOS .......................................................................................................... - 10 - 1.2.1 Visión por computador .................................................................................. - 10 - 1.2.2 Segmentación de imagen ............................................................................. - 11 - 1.3 OBJETIVOS ............................................................................................................ - 11 - 1.4 PLANIFICACIÓN ...................................................................................................... - 13 - 1.4.1 A priori .......................................................................................................... - 13 - 1.4.2 A posteriori.................................................................................................... - 17 - 2. OPENCV Y HERRAMIENTAS ................................................................................. - 22 2.1 INTRODUCCIÓN A OPENCV ..................................................................................... - 22 - 2.1.1 Mostrar una imagen ...................................................................................... - 23 - 2.1.2 Mostrar un video ........................................................................................... - 25 - 2.2 FUNCIONES PARA EL TRATAMIENTO DE IMAGEN ......................................................... - 26 - 2.3 FUNCIONES PARA EL TRATAMIENTO DE VIDEO ........................................................... - 27 - 3. EL ALGORITMO SAKBOT ...................................................................................... - 30 3.1 INTRODUCCIÓN ...................................................................................................... - 30 - 3.2 ANÁLISIS ............................................................................................................... - 31 - 3.2.1 El sistema ..................................................................................................... - 31 - 3.2.2 Arquitectura .................................................................................................. - 31 - 3.2.3 Supresión de fondo ....................................................................................... - 33 - 3.2.3.1 Operadores morfológicos........................................................................... - 34 - -5- 3.2.4 Etiquetado y Análisis objetos ........................................................................ - 35 - 3.2.5 Actualización de fondo .................................................................................. - 37 - 3.2.6 Detección de sombras .................................................................................. - 38 - 3.3 DISEÑO ................................................................................................................. - 40 - 3.4 IMPLEMENTACIÓN ................................................................................................... - 42 - 3.4.1 Clase VideoSourceReader ........................................................................... - 43 - 3.4.2 Clase VideoSourceWriter.............................................................................. - 45 - 3.4.3 Clase MVO ................................................................................................... - 45 - 3.4.4 Clase Sakbot ................................................................................................ - 46 - 3.4.4.1 Estructura general ..................................................................................... - 46 3.4.4.2 Supresión de fondo .................................................................................... - 47 3.4.4.3 Aplicar el umbral y eliminar sombras ......................................................... - 48 3.4.4.4 Aplicar operadores morfológicos ............................................................... - 49 3.4.4.5 Etiquetado.................................................................................................. - 51 3.4.4.6 Flujo óptico promedio................................................................................. - 53 3.4.4.7 Guardar el resultado .................................................................................. - 55 3.4.4.8 Actualización de la imagen de fondo ......................................................... - 55 3.4.5 3.5 Ejecución programa ...................................................................................... - 56 - VALIDACIÓN Y PRUEBAS .......................................................................................... - 57 - 4. CONCLUSIONES ..................................................................................................... - 63 5. BIBLIOGRAFÍA ........................................................................................................ - 65 6. ANEXOS .................................................................................................................. - 67 6.1 INSTALACIÓN OPENCV ........................................................................................... - 67 - 6.2 UTILIZACIÓN VISUAL STUDIO ................................................................................... - 67 - -6- Índice de figuras Ilustración 1 - Diagrama Gantt a priori ............................................................................ - 16 Ilustración 2 - Diagrama Gantt a posteriori ..................................................................... - 20 Ilustración 3 - Ejemplo mostrar imagen .......................................................................... - 23 Ilustración 4 - Ejemplo mostrar video.............................................................................. - 25 Ilustración 5 - Metodología del desarrollo del proyecto .................................................. - 30 Ilustración 6 - Arquitectura Sakbot .................................................................................. - 32 Ilustración 7 - Imagen diferencia fondo ........................................................................... - 33 Ilustración 8 – Efector operadores morfológicos ............................................................. - 34 Ilustración 9 - Umbral y operadores morfológicos .......................................................... - 35 Ilustración 10 - MVOs marcados .................................................................................... - 36 Ilustración 11 - MVO sin umbral ..................................................................................... - 36 Ilustración 12 - Actualización de imagen de fondo ......................................................... - 38 Ilustración 13 - Detección de sombras............................................................................ - 39 Ilustración 14 - Diseño clases ......................................................................................... - 41 Ilustración 15 - Captura video de prueba ........................................................................ - 43 Ilustración 16 - Ejemplo VideoSourceReader ................................................................. - 44 Ilustración 17 - Clase Sakbot .......................................................................................... - 46 Ilustración 18 - Métodos acceso a R, G, B ..................................................................... - 47 Ilustración 19 - Supresión de fondo ................................................................................ - 48 Ilustración 20 - Resultado umbral ................................................................................... - 48 Ilustración 21 - Métodos morfológicos ............................................................................ - 50 Ilustración 22 - Resultado operadores morfológicos ....................................................... - 50 Ilustración 23 - Calculo flujo óptico promedio ................................................................. - 54 - -7- Ilustración 24 - Ejemplo video utilizado en las pruebas .................................................. - 57 Ilustración 25 - Imagen de diferencia con umbral = 10 ................................................... - 58 Ilustración 26 - Imagen de diferencia con umbral = 25 ................................................... - 58 Ilustración 27 - Imagen de diferencia con umbral = 75 ................................................... - 59 Ilustración 28 - Imagen de diferencia con umbral = 100 ................................................. - 59 Ilustración 29 - Resultado detección de sombras sobre un coche .................................. - 60 Ilustración 30 - Resultado detección de sombras en una escena ................................... - 61 Ilustración 31 - Fantasma de objeto no actualizado ....................................................... - 62 Ilustración 32 - Región de fotograma actualizado ........................................................... - 62 - -8- CÁPITULO 1 1. INTRODUCCIÓN ...................................................................................................... - 10 1.1 MOTIVACIÓN .......................................................................................................... - 10 - 1.2 CONCEPTOS .......................................................................................................... - 10 - 1.2.1 Visión por computador .................................................................................. - 10 - 1.2.2 Segmentación de imagen ............................................................................. - 11 - 1.3 OBJETIVOS ............................................................................................................ - 11 - 1.4 PLANIFICACIÓN ...................................................................................................... - 13 - 1.4.1 A priori .......................................................................................................... - 13 - 1.4.2 A posteriori.................................................................................................... - 17 - -9- 1. Introducción 1.1 Motivación En la última década, muchos enfoques han sido propuestos para la detección y seguimiento de objetos en movimiento en videos dedicados principalmente a la vigilancia del tráfico y vigilancia de seguridad. La detección de objetos en movimiento en videos (o MOVs por sus siglas en inglés) se basa en la suposición de que en casi cada fotograma los MVOs se perciben claramente como distintos de la imagen de fondo y de los fotogramas anteriores. El seguimiento tiene como objetivo describir las trayectorias de movimiento de los objetos en el tiempo. El principal problema a resolver en el seguimiento es encontrar correspondencias de un mismo objeto físico en diferentes fotogramas. Este problema puede resultar trivial o difícil dependiendo de varios aspectos del entorno, tales como la densidad y la proximidad de los objetos, formas rígidas o variables, la presencia de oclusiones, y otros. 1.2 Conceptos A continuación se van a explicar aquellos términos que se considera necesario conocer para la lectura del proyecto. 1.2.1 Visión por computador La visión por computador es un sub campo de la inteligencia artificial. Su propósito es programar un ordenador para que entienda una escena o características de una imagen. Los objetivos típicos de la visión artificial incluyen: La detección, segmentación, localización y reconocimiento de ciertos objetos en imágenes (por ejemplo, caras humanas). La evaluación de los resultados (ej.: segmentación, registro). Registro de diferentes imágenes de una misma escena u objeto, por ejemplo, hacer concordar un mismo objeto en diversas imágenes. Seguimiento de un objeto en una secuencia de imágenes. - 10 - Mapeo de una escena para generar un modelo tridimensional de la escena; tal modelo podría ser usado por un robot para navegar por la escena. Estimación de las posturas tridimensionales de humanos. Búsqueda de imágenes digitales por su contenido. Estos objetivos se consiguen por medio de reconocimiento de patrones, aprendizaje estadístico, geometría de proyección, procesado de imágenes, teoría de gráficos y otros campos. [15] 1.2.2 Segmentación de imagen La segmentación temporal de video es el primer paso para el análisis de secuencias de video orientado a la extracción automática de información referente a su contenido (video parsing). La segmentación es el proceso de dividir una imagen digital en varias partes (grupos de píxeles) u objetos. El objetivo de la segmentación es simplificar y/o cambiar la representación de una imagen en otra más significativa y más fácil de analizar. La segmentación se usa tanto para localizar objetos como para encontrar los límites de estos dentro de una imagen. Más precisamente, la segmentación de la imagen es el proceso de asignación de una etiqueta a cada pixel de la imagen de forma que los píxeles que compartan la misma etiqueta también tendrán ciertas características visuales similares.[14] 1.3 Objetivos El principal objetivo es lograr una aplicación que detecte los objetos en movimiento en un video dado. Por ejemplo, dado un video filmado con una cámara estática, la idea sería procesar esta grabación y obtener una colección de elementos (objetos, personas, vehículos) que se encuentran en movimiento. Esta colección de elementos se puede utilizar, a posteriori, como entrada a módulos de seguimiento. Este trabajo, en concreto, se limita a marcar los elementos encontrados sobre la grabación. El proceso de identificación de los elementos en movimiento se tiene que realizar de forma automática especificando únicamente el video de origen y el de salida. Esta aplicación debe obtener el video resultante de forma rápida. Además, el procesado del video de entrada se debe realizar sin modifica el video original. Para conseguir la aplicación se pretende realizar el estudio de un algoritmo que permite la detección de objetos en movimiento. El algoritmo que se va a estudiar e - 11 - implementar se denomina Sakbot, y corresponde a un algoritmo de segmentación aplicable a cualquier tipo de video que presenta una imagen de fondo estática. La aplicación se implementara utilizando la herramienta OpenCV, explicada en detalle en los próximos capítulos. Otro objetivo de este proyecto consiste en familiarizase con esta herramienta y estudiar los métodos que ofrece para la manipulación de video e imágenes. Por último, otro de los objetivos consiste en aplicar y evaluar los conocimientos adquiridos como estudiante y ampliar estos conocimientos con la experiencia adquirida durante el desarrollo de este proyecto. - 12 - 1.4 Planificación 1.4.1 A priori Después de determinar el proyecto a realizar con el tutor, se procedió a hacer una planificación previa del proyecto a desarrollar. En esta planificación se estimó tanto la planificación como el coste temporal de cada tarea Según la planificación realizada, el proyecto comenzó el 24 de octubre de 2011 y la previsión era que finalizara el 1 de junio de 2012. A la hora de realizar la planificación se tuvieron en cuenta los posibles imprevistos que podrían influir en el retraso de varias tareas. El proyecto contó con un total de 300 horas invertidas en 150 días laborables y se siguió la siguiente distribución de horas por mes: Tarea Total Determinar el ámbito del proyecto Estudio bibliografía Estudio de tareas a realizar Planificación temporal de tareas Horas Octubre Noviembre Diciembre Enero Febrero Marzo Abril Mayo Junio 300h 12h 44h 34h 44h 42h 32h 32h 46h 4 h 4h 10 h 8h 2h 8h 8h 8h 8h 10 h 10h 20 h 16h Búsqueda e instalación del software de desarrollo Estudio utilización software y técnicas de 4h desarrollo Diseño 12 h 12h Supresión de fondo 24 h 18h Etiquetado objetos 24 h 24h Análisis objetos 24 h 14h Detección de sombras 24 h 24h Actualización de fondo 24 h 8h Realización de pruebas 24 h Análisis resultados 12 h 12h Reunión con el profesor 12 h 12h Reunión con el profesor 2h 2h Evaluación global de 2h 2h 6h 10h 16h 16h - 13 - 8h 14h resultados Definición de futuras 2h 2h 4h 4h 40 h 36h mejoras Conclusiones Realización de la memoria del proyecto 4h Realización de la presentación del 10 h 10h proyecto Tabla 1 - Horas por mes Con esta planificación, la fecha final del proyecto es 11 de junio de 2012. Nombre tarea Duración Principio (horas) Final Proyecto Sakbot 300 24/10/11 11/06/12 1. Proceso de análisis y planificación 60 24/10/11 02/12/11 1.1 Determinar el ámbito del proyecto 4 24/10/11 25/10/11 1.2 Estudio bibliografía 10 26/10/11 01/11/11 1.3 Estudio de tareas a realizar 8 02/11/11 07/11/11 1.4 Planificación temporal de tareas 8 08/11/11 11/11/11 1.5 Búsqueda e instalación del software de desarrollo 10 14/11/11 18/11/11 1.6 Estudio utilización software y técnicas de desarrollo 20 21/11/11 02/12/11 180 05/12/11 30/04/12 2.1 Diseño 12 05/12/11 12/12/11 2.2 Implementación 120 13/12/11 20/03/12 2.2.1 Supresión de fondo 24 13/12/11 04/01/12 2.2.2 Etiquetado objetos 24 05/01/12 20/01/12 2.2.3 Análisis objetos 24 23/01/12 07/02/12 2.2.4 Detección de sombras 24 08/02/12 23/02/12 2.2.5 Actualización de fondo 24 24/02/12 20/03/12 2.3 Realización de pruebas 24 21/03/12 12/04/12 2.4 Análisis resultados 12 13/04/12 20/04/12 2.5 Reunión con el profesor 12 23/04/12 30/04/12 3. Revisión final del proyecto 60 01/05/12 11/06/12 2. Proceso de desarrollo - 14 - 3.1 Reunión con el profesor 2 01/05/12 01/05/12 3.2 Evaluación global de resultados 2 02/05/12 02/05/12 3.3 Definición de futuras mejoras 2 03/05/12 03/05/12 3.4 Conclusiones 4 04/05/12 07/05/12 3.5 Realización de la memoria del proyecto 40 08/05/12 04/06/12 3.6 Realización de la presentación del proyecto 10 05/06/12 11/06/12 Tabla 2 - Planificación a priori En el proceso de análisis y planificación se define el alcance del proyecto, así como las herramientas de desarrollo de software y los objetivos que se quieren llegar a conseguir. Además, se realiza la tarea del estudio de la bibliografía, fundamental para definir las tareas de diseño e implementación del proceso de desarrollo. En el proceso de desarrollo se realizan las tareas de diseño, implementación, pruebas y evaluación de resultados para cada uno de los cuatro algoritmos. Este es el proceso más importante del proyecto puesto que aquí es donde se implementará el proyecto propiamente dicho. El primero de los algoritmos es el que en principio conllevará más tiempo debido a que se presupone que muchas de las funciones que se implementarán serán posteriormente reutilizadas en los otros algoritmos. En la revisión final del proyecto se realiza la evaluación global de los resultados obtenidos en el proceso anterior. Una vez estudiados detenidamente los mismos, se realiza una tarea consistente en definir qué posibles mejores o qué posibles vías de desarrollo se podrían aplicar en un futuro para acercarse a la consecución de los objetivos marcados. También se realiza una tarea con las conclusiones obtenidas después de evaluar los cuatro algoritmos. Finalmente, se realizan las tareas de redactar la memoria y la presentación del proyecto. - 15 - Ilustración 1 - Diagrama Gantt a priori - 16 - 1.4.2 A posteriori Durante el desarrollo del proyecto hubo modificaciones en la planificación debido al surgimiento e imprevistos. Entre estos destaca el hecho de que el alumno tuvo que estudiar para los exámenes y se hubo que retrasar todo el proyecto. Comentar también, que el tiempo previsto para el desarrollo de las distintas fases del proyecto se vio modificado. Algunas tareas costaron más tiempo, otras menos en completar. El número total de horas invertidas no se vio afectado. Tarea Total Hora Octubr Noviemb Diciembr Ener Febrer Marz Abri May Juni Juli Agost s re e o o o l o o o o 42h 34h 44h 42h 32h 32h 0h 0h 44h 16h e 300h 12h Determinar el ámbito del 4 h 4h proyecto Estudio bibliografía 20 h 8h 12h Estudio de tareas a 8h 8h 8h 8h 10 h 10h 10 h 6h realizar Planificació n temporal de tareas Búsqueda e instalación del software de desarrollo Estudio utilización software y 4h técnicas de desarrollo Diseño Supresión de fondo Etiquetado 12 h 12h 10 h 10h 30 h 8h 22h - 17 - objetos Análisis objetos Detección de sombras Actualizaci ón de fondo Realización de pruebas Análisis resultados 20 h 20h 10 h 2h 50 h 24 h 8h 34h 16h 16h 8h 12 h 12h 12 h 12h Reunión con el profesor Reunión con el 5h 5h 2h 2h 4h 4h 4h 4h 40 h 29h profesor Evaluación global de resultados Definición de futuras mejoras Conclusion es Realización de la memoria 11h del proyecto Realización de la presentació 5h 5h n del proyecto Tabla 3 - Horas por mes a posteriori En la siguiente tabla se muestra la relación entre las tareas realizadas, las horas invertidas para cada una de ellas y la fecha de inicio y fin. - 18 - Duración Principio (horas) Nombre tarea Proyecto Sakbot Final 300 24/10/11 10/08/12 1. Proceso de análisis y planificación 60 24/10/11 02/12/11 1.1 Determinar el ámbito del proyecto 4 24/10/11 25/10/11 1.2 Estudio bibliografía 20 26/10/11 08/11/11 1.3 Estudio de tareas a realizar 8 09/11/11 14/11/11 1.4 Planificación temporal de tareas 8 15/11/11 18/11/11 1.5 Búsqueda e instalación del software de desarrollo 10 21/11/11 25/11/11 1.6 Estudio utilización software y técnicas de desarrollo 10 28/11/11 02/12/11 180 05/12/11 30/04/12 2.1 Diseño 12 05/12/11 12/12/11 2.2 Implementación 120 13/12/11 20/03/12 2.2.1 Supresión de fondo 10 13/12/11 19/12/11 2.2.2 Etiquetado objetos 30 20/12/11 16/01/12 2.2.3 Análisis objetos 20 17/01/12 30/01/12 2.2.4 Detección de sombras 10 31/01/12 06/02/12 2.2.5 Actualización de fondo 50 07/02/12 20/03/12 2.3 Realización de pruebas 24 21/03/12 12/04/12 2.4 Análisis resultados 12 13/04/12 20/04/12 2.5 Reunión con el profesor 12 23/04/12 30/04/12 3. Revisión final del proyecto 60 02/07/12 10/08/12 3.1 Reunión con el profesor 5 02/07/12 04/07/12 3.2 Evaluación global de resultados 2 04/07/12 05/07/12 3.3 Definición de futuras mejoras 4 05/07/12 09/07/12 3.4 Conclusiones 4 09/07/12 11/07/12 3.5 Realización de la memoria del proyecto 40 11/07/12 08/08/12 3.6 Realización de la presentación del proyecto 5 08/08/12 10/08/12 2. Proceso de desarrollo Tabla 4 – Planificación a posteriori - 19 - Ilustración 2 - Diagrama Gantt a posteriori - 20 - CÁPITULO 2 2. OPENCV Y HERRAMIENTAS ................................................................................. - 22 2.1 INTRODUCCIÓN A OPENCV ..................................................................................... - 22 - 2.1.1 Mostrar una imagen ...................................................................................... - 23 - 2.1.2 Mostrar un video ........................................................................................... - 25 - 2.2 FUNCIONES PARA EL TRATAMIENTO DE IMAGEN ......................................................... - 26 - 2.3 FUNCIONES PARA EL TRATAMIENTO DE VIDEO ........................................................... - 27 - - 21 - 2. OpenCV y herramientas Este capítulo introduce algunos de los conceptos básicos de la biblioteca OpenCV. Con ello se pretende dar una idea al lector acerca de cómo se ha podido trabajar con los videos, accediendo a las propiedades de los distintos fotogramas. 2.1 Introducción a OpenCV Las siglas OpenCV provienen de los términos anglosajones “Open Source Computer Vision Library”. Por lo tanto, OpenCV es una librería de tratamiento de imágenes, destinada principalmente a aplicaciones de visión por computador en tiempo real. OpenCV es una biblioteca libre de visión por computador disponible en 0. La biblioteca está escrita en C y C++ y puede ser usada en Linux, Windows y Mac OS X. Se están desarrollando interfaces para Python, Ruby, Matlab y otros lenguajes. OpenCV fue diseñada y orientada hacia las aplicaciones en tiempo real. Una de las metas de OpenCV es proporcionar una infraestructura de visión por computador simple de usar que ayude a la gente a construir rápidamente sofisticadas aplicaciones de visión. La biblioteca de OpenCV contiene cerca de 500 funciones que abarcan muchos campos en visión, desde la imagen médica, calibración de cámaras o robótica. La licencia de código abierto de OpenCV se ha realizado de forma que es posible construir un producto comercial usando todo o parte de OpenCV. No es obligatorio mostrar el código del producto ni las mejoras realizadas al dominio público. OpenCV está encaminado en proveer las herramientas básicas necesarias para resolver los problemas de la visión por computador. En algunos casos, las funcionalidades de alto nivel en la biblioteca serán suficientes para resolver los problemas más complejos de la visión por computador. Incluso cuando no sea el caso, los componentes básicos en la biblioteca serán suficientes para permitir la creación de una solución completa por parte del usuario en prácticamente cualquier problema de visión. A continuación, se presentan algunos ejemplos de utilización de la librería OpenCv y algunas de las funciones básicas utilizadas durante el desarrollo de este proyecto. Información adicional se puede encontrar en [7] y [5]. - 22 - OpenCV dispone de utilidades para leer desde una amplia gama de tipos de archivos de imágenes hasta de video y cámaras. Estas utilidades son parte de un conjunto de herramientas llamado HighGUI, el cual está incluido en el paquete de OpenCV. A continuación, se van a mostrar dos ejemplos básicos para entender el funcionamiento de OpenCV. En el primero se cargará una imagen y se mostrará por pantalla. En el segundo, se mostrará por pantalla un video almacenado en el disco. 2.1.1 Mostrar una imagen Veamos un ejemplo con el siguiente programa, que cargará la imagen lena.jpg, lo mostrará en una ventana. Debe tener la imagen en el directorio de trabajo. En la figura [Ilustración 3] se muestra el código de un primer ejemplo de un programa escrito en C utilizando algunas de las herramientas proporcionadas por la biblioteca OpenCV para crear un programa que abra una imagen y la muestre por pantalla. #include "cv.h" #include "highgui.h" #include <stdio.h> char name0[]="lena.jpg"; // se define el fichero a cargar int main() { IplImage* imagen= cvLoadImage(name0); cvNamedWindow( "test", CV_WINDOW_AUTOSIZE); cvShowImage( "test", imagen ); cvWaitKey(0); cvDestroyAllWindows(); cvReleaseImage(&imagen); return 0; } Ilustración 3 - Ejemplo mostrar imagen Una vez compilado y ejecutado el programa desde la línea de comandos con un único argumento, el programa carga una imagen en memoria y la muestra por pantalla. Entonces, el programa espera hasta que el usuario pulse una tecla para cerrar la ventana con la imagen y salir. A continuación, se va a explicar brevemente cada una de las líneas del programa para entender qué es lo que hace cada comando. - 23 - IplImage* img = cvLoadImage(name0); Esta línea carga la imagen. La función cvLoadImage() determina el formato del archivo a partir del nombre pasado como argumento, reserva la memoria necesaria para la estructura de datos de la imagen y devuelve un puntero. Este puntero se utiliza para manipular tanto la imagen como sus datos. cvNamedWindow(“test”, CV_WINDOW_AUTOSIZE); cvNamedWindow() abre una ventana en la pantalla que puede contener y mostrar una imagen. El primer argumento se refiere al nombre que se la asigna a la ventana. El segundo define propiedades de la ventana. En el ejemplo presentado, con CV_WINDOW_AUTOSIZE el tamaño de la ventana es el mismo independientemente del tamaño de la imagen y ésta se ajusta al tamaño de la ventana. cvShowImage(“test”, imagen); Una vez tenemos una imagen cargada en un formato IplImage, podemos mostrarla mediante cvShowImage(). Esta función necesita que ya se haya creado una ventana. cvWaitKey(0); Esta línea detiene la ejecución del programa y espera una interrupción de teclado. Si se le pasa como argumento un número positivo, el programa espera ese número de milisegundos y de no producirse antes la interrupción sigue con la ejecución. Si el argumento es 0 o un número negativo, el programa espera indefinidamente a que se pulse una tecla. cvReleaseImage(&imagen); Esta función libera la memoria reservada para contener la estructura de datos de la imagen. Una vez realizado esto, el puntero imagen apunta a NULL. cvDestroyWindow(“test”); cvDestroyAllWindows(); Finalmente, se destruye la ventana. Esta función cierra la ventana y recolocará el uso de memoria asociado. - 24 - 2.1.2 Mostrar un video En la [Ilustración 4] se muestra el código de un segundo ejemplo de un programa escrito en C utilizando algunas de las herramientas proporcionadas por la biblioteca OpenCV para crear un programa que abra un video almacenado en disco y lo reproduzca mostrando su contenido por pantalla. #include “highgui.h” Int main(int argc, char** argv) { cvNamedWindow(“Example”, CV_WINDOW_AUTOSIZE); cvCapture* capture = cvCreateFileCapture(argv[1]); IplImage* frame; Int frameIndex = 0; while(1) { frame = cvQueryFrame(capture); if(!frame) break; cvShowImage(“Example”, frame); char c = cvWaitKey(33); if (c==27) break; } cvReleaseCapture(&capture); cvDestroyWindow(“Example”); } Ilustración 4 - Ejemplo mostrar video Una vez compilado y ejecutado el programa desde la línea de comandos con un único argumento, el programa carga un video almacenado en el disco del ordenador y fotograma a fotograma va mostrando el contenido del mismo por pantalla. Después de mostrar cada fotograma, el programa espera 33 ms por si el usuario desea detener y salir de la reproducción del video, en caso contrario muestra el siguiente fotograma hasta que finalice la reproducción de todo el video. A continuación, se va a explicar brevemente cada una de las líneas del programa para entender qué es lo que hace cada comando. En la primera línea creamos una nueva ventana, como ya se comentó en el apartado anterior. A través de esta ventana se mostrará el video. CvCapture* capture = cvCreateFileCapture(argv[1]); - 25 - La función cvCreateFileCapture() coge de su argumento el nombre del archivo AVI a ser cargado y devuelve un puntero a una estructura de datos CvCapture. Esta estructura contiene toda la información sobre el archivo AVI que está siendo leído, incluido su información de estado. El puntero apunta al principio del video. frame = cvQueryFrame(capture); Una vez dentro del bucle, se empieza a leer del arhivo AVI. cvQueryFrame() toma como argumento el puntero a la estructura CvCapture. cvQueryFrame(). Si no se ha mostrado todavía el último fotograma, el fotograma obtenido con cvQueryFrame() se muestra por pantalla. c = cvWaitKey(33); if ( c == 27 ) break; Una vez se ha mostrado el fotograma por pantalla, se esperan 33 ms. Si el usuario pulsa una tecla, c contendrá el valor ASCII de la tecla; si no, contendrá el valor -1. Si el usuario pulsa la tecla Esc (ASCII 27), el programa sale del bucle de lectura del video. En caso contrario, después de 33 ms se sigue ejecutando el bucle. cvReleaseCapture(&capture); Una vez se ha salido del bucle de lectura del video, se libera la memoria usada con la estructura CvCapture. Esta función también cierra cualquier archivo abierto que referencie al archivo AVI. 2.2 Funciones para el tratamiento de imagen En este apartado se presentan algunas de las funciones implementadas en la biblioteca OpenCV para el tratamiento de imágenes y que se han utilizado para la realización del proyecto. 0- 65 IplImage* cvCloneImage( const IplImage* image ) Crea una copia completa de la imagen pasada como argumento incluyendo la cabecera, ROI y los datos. void cvReleaseImage( IplImage** image ) Libera la cabecera y los datos de una imagen. - 26 - IplImage* cvCreateImage( CvSize size, int depth, int channels) Crea la cabecera y asigna los datos de una imagen. El primer argumento especifica el tamaño de la imagen (anchura y altura). El segundo especifica la profundidad de bits de los elementos (píxeles) de la imagen. El tercero especifica el número de caracteres por píxel. IplImage* cvLoadImage( const char* filename, int iscolor=CV_LOAD_IMAGE_COLOR ) Carga una imagen almacenada en el disco con nombre filename y devuelve un puntero a dicha imagen. El segundo argumento especifica el color de la imagen cargada: o Si el valor es mayor que 0, se fuerza a que la imagen sea de 3 canales. o Si el valor es 0, se fuerza a que la imagen sea en una escala de grises. o Si el valor es menor que 0, la imagen se carga como es. void cvCvtColor( const CvArr* src, CvArr* dst, int code ) Convierte una imagen de un espacio de color a otro. El primer argumento especifica la imagen que se quiere transformar y el segundo la imagen destino donde se almacena una vez modificada. El tercer argumento especifica el tipo de conversión a realizar 2.3 Funciones para el tratamiento de video En este apartado se presentan algunas de las funciones implementadas en la biblioteca OpenCV para el tratamiento de video y que se han utilizado para la realización del proyecto. [14] o IplImage* cvQueryFrame( CvCapture* capture ) Coge y devuelve un fotograma de una cámara o archivo. o double cvGetCaptureProperty( CvCapture* capture, int property_id ); Obtiene la propiedad de un video especificada como argumento. A continuación se detallan las distintas propiedades: o CV_CAP_PROP_POS_MSEC. Posición actual del video en milisegundos o tiempo de captura del video. o CV_CAP_PROP_POS_FRAMES. Posición del próximo fotograma decodificado / capturado. - 27 - o CV_CAP_PROP_POS_AVI_RATIO. Posición relativa del video. o CV_CAP_PROP_FRAME_WIDTH. Anchura de los fotogramas en el flujo de video. o CV_CAP_PROP_FRAME_HEIGHT. Altura de los fotogramas en el flujo de video. o CV_CAP_PROP_FPS. Número de fotogramas por segundo. o CV_CAP_PROP_FOURCC. Código de 4 caracteres del códec utilizado. o CV_CAP_PROP_FRAME_COUNT. Número de fotogramas en el archivo de video. - 28 - CÁPITULO 3 3. EL ALGORITMO SAKBOT ...................................................................................... - 30 3.1 INTRODUCCIÓN ...................................................................................................... - 30 - 3.2 ANÁLISIS ............................................................................................................... - 31 - 3.2.1 El sistema ..................................................................................................... - 31 - 3.2.2 Arquitectura .................................................................................................. - 31 - 3.2.3 Supresión de fondo ....................................................................................... - 33 - 3.2.3.1 Operadores morfológicos........................................................................... - 34 3.2.4 Etiquetado y Análisis objetos ........................................................................ - 35 - 3.2.5 Actualización de fondo .................................................................................. - 37 - 3.2.6 Detección de sombras .................................................................................. - 38 - 3.3 DISEÑO ................................................................................................................. - 40 - 3.4 IMPLEMENTACIÓN ................................................................................................... - 42 - 3.4.1 Clase VideoSourceReader ........................................................................... - 43 - 3.4.2 Clase VideoSourceWriter.............................................................................. - 45 - 3.4.3 Clase MVO ................................................................................................... - 45 - 3.4.4 Clase Sakbot ................................................................................................ - 46 - 3.4.4.1 Estructura general ..................................................................................... - 46 3.4.4.2 Supresión de fondo .................................................................................... - 47 3.4.4.3 Aplicar el umbral y eliminar sombras ......................................................... - 48 3.4.4.4 Aplicar operadores morfológicos ............................................................... - 49 3.4.4.5 Etiquetado.................................................................................................. - 51 3.4.4.6 Flujo óptico promedio................................................................................. - 53 3.4.4.7 Guardar el resultado .................................................................................. - 55 3.4.4.8 Actualización de la imagen de fondo ......................................................... - 55 3.4.5 3.5 Ejecución programa ...................................................................................... - 56 - VALIDACIÓN Y PRUEBAS .......................................................................................... - 57 - - 29 - 3. El algoritmo Sakbot 3.1 Introducción La metodología seguida en el desarrollo del proyecto ha sido un proceso lineal y se puede apreciar en la Ilustración 5. En primer lugar se ha realizado la tarea de análisis, estudiando el algoritmo a implementar. A continuación se ha realizado la tarea de diseño del programa, basada en la especificación de los pasos del algoritmo. En la siguiente fase se implemento lo que se diseño en la fase de diseño. Finalmente, se han realizado una serie de pruebas con distintos vídeos, se han anotado los resultados y se han obtenido las conclusiones. Ilustración 5 - Metodología del desarrollo del proyecto - 30 - 3.2 Análisis 3.2.1 El sistema Sakbot tiene como objetivo la detección y el seguimiento de distintos objetos, tales como vehículos y peatones en escenas de tráfico, pero también personas caminando fuera de este ámbito. Sakbot está destinado a ser de uso general y por lo tanto adecuado para las aplicaciones que van desde seguimiento de vehículo hasta la vigilancia visual. A diferencia de otros trabajos, Sakbot no aborda solo el caso relativamente sencillo de la vigilancia de vehículos, donde una clase de objetos en movimiento (es decir, vehículos) se puede detectar a lo largo de un cierta dirección de movimiento fijo. Se consideran los casos más complejos tales como personas y vehículos que se desplazan, que tienen distintas formas, velocidades, trayectorias, la presencia de infraestructuras y posibles oclusiones. Sakbot se concibe como un sistema de propósito general que adopta una única cámara fija, capaz de tratar con varias situaciones de funcionamiento: a) cambios de condiciones de luz debidos a condiciones atmosféricas, las horas del día, las sombras. b) movimientos de cámara limitados, de alta frecuencia, debidos a vibraciones y el viento, que se compensan en un pre-procesamiento del video c) los cambios de fondo, el fondo de la escena podría cambiar, ya sea porque los objetos se detienen (por ejemplo, un vehículo se detiene) o porque los objetos (previamente fijos, considerados objetos de fondo) comienzan su movimiento. d) los objetos se pueden mover con cualquier trayectoria y velocidad En este contexto, el proceso debe presentar una fase de detección de movimiento general y robusto y un sistema de seguimiento flexible, capaz de adaptarse a distintas aplicaciones. Para la fase de detección, se utiliza una técnica de supresión de fondo con adaptación selectiva de la imagen de fondo, mejorada con datos de movimiento a nivel de objeto, en lugar de a nivel de pixel. 3.2.2 Arquitectura La arquitectura de Sakbot consta de varios pasos que se pueden apreciar en la Ilustración 6. El tiempo de procesamiento de estos pasos determina el límite superior de la tasa de procesamiento alcanzable. - 31 - Ilustración 6 - Arquitectura Sakbot Los pasos del algoritmo Sakbot son los siguientes: 1) Cada fotograma esta supuesta a un previo paso de corrección de movimiento. Este paso es omitido en este trabajo. 2) La supresión de la imagen de fondo se utiliza para detectar los objetos en movimiento. Esto paso utiliza la información dada por la crominancia de cada pixel para diferenciar el primer plano de la imagen de fondo. El resultado es una imagen escalar, en niveles de gris, que contiene solo los MVO candidatos. 3) La detección de sombras pretende mejorar la detección de MVOs y la actualización de la imagen de fondo. Se aplica análisis de crominancia para detectar los pixeles sombreados, y así descartar sombras fijas que pertenecen a la imagen de fondo. 4) El etiquetado es el proceso de identificar los MVOs candidatos. 5) Sobre los MVOs candidatos, se aplica un proceso de análisis, descartando aquellos que no cumplen las condiciones como la superficie mínima, flujo óptico promedio mínimo, etc. - 32 - 6) La actualización de fondo se ejecuta constantemente, para hacer frente a los cambios del entorno, como objetos (antes estacionarios) que empiezan a moverse, objetos que paran su movimiento, cambios de luz, etc. 7) El resultado del algoritmo Sakbot, la lista de objetos en movimiento, se puede utilizar en módulos de seguimiento. Este paso no es objeto de este trabajo. 3.2.3 Supresión de fondo Con este paso se desea obtener la imagen diferencia, DB (diferencia con la imagen de fondo). La formula utilizada es la siguiente: ( ) ( ( ) ( )) (| ( ) ( ) | ) Donde: – la distancia calculada. - el fotograma actual, en el momento t. – la imagen de fondo, en el momento t. ( ) – el pixel que se encuentra en la posición de coordenadas (x, y) La formula se aplica para cada pixel. El resultado es una imagen escalar, en tonos de gris, que contiene solo los puntos en movimiento candidatos. Ilustración 7 - Imagen diferencia fondo - 33 - Con el fin de limitar la dependencia de los resultados de un determinado umbral, se utiliza a continuación un umbral con histéresis combinado con morfología. Primero se seleccionan los puntos con un umbral bajo ( ), luego se aplican operadores morfológicos (cierre y apertura) con el fin de eliminar puntos aislados o zonas pequeñas de ruido. Después de este proceso se lleva a cabo el etiquetado, aceptando los objetos que contienen por lo menos un punto mayor que el umbral alto ( ). 3.2.3.1 Operadores morfológicos Los efectos de los operadores morfológicos básicos se puede observar en las imágenes de abajo. Ilustración 8 – Efector operadores morfológicos Las figuras (b) y (c) muestran como la imagen se cambia bajo los 2 operadores morfológicos más comunes, erosión y dilación. Con la erosión, cada pixel del objeto que toca un pixel del fondo es añadido al fondo. Con la dilación, cada pixel del fondo que toca un pixel del objeto es añadido al objeto. La erosión hace los objetos más pequeños, y puede separar un objeto en varios. La dilación hace los objetos más grandes, y puede unir varios objetos en uno. La figura (d) presenta la apertura que se define como una erosión seguida de una dilación. La figura (e) presenta el proceso inverso, el cierre, que se define como una dilación seguida por una erosión. Tal como se puede observar, la apertura elimina zonas pequeñas y finas líneas de pixeles de los objetos. De modo similar, el cierre elimina zonas - 34 - pequeñas y finas líneas de pixeles del fondo. Estas técnicas son útiles para manejar imágenes con ruido. [8] Ilustración 9 - Umbral y operadores morfológicos En la ilustración se puede ver el efecto de aplicar el umbral y los operadores morfológicos sobre la imagen . A la izquierda tenemos la imagen sin procesar, obtenida con la formula explicada anteriormente. A la derecha, tenemos la imagen después de haber aplicado el umbral bajo y los operadores morfológicos de cierre y apertura. 3.2.4 Etiquetado y Análisis objetos Después de aplicar la supresión de la imagen de fondo, la imagen en el momento t contiene un cierto número de “manchas” que pertenecen al primer plano de la imagen (anotados como , del ingles “foreground blob”). A continuación la colección de manchas se analizan, análisis que consiste de dos pasos: 1) Las manchas con un área menos que el umbral de área se descartan. El umbral depende de la imagen que se analiza, respectivamente de los siguientes factores: a. distancia entre la cámara y escena b. Tamaño típico de objetos de la escena 2) Se calcula el flujo óptico promedio (anotado aOF, del inglés “average optical flow”) para cada mancha. Las manchas con aOF menor que el umbral se descartan. - 35 - Estos objetos descartados son objetos que aparentemente se mueven debido a un error local en la imagen de fondo, y por lo tanto no se pueden aceptar como MVO. Ilustración 10 - MVOs marcados El resultado de este proceso se puede observar el la Ilustración 10. Los objetos en movimiento detectados están marcados por un rectángulo azul. Ilustración 11 - MVO sin umbral En la Ilustración 11 se pueden observar los objetos detectados si no se aplican los umbrales mencionados anteriormente. Los objetos marcados son las denominadas manchas (detectadas solo con la diferencia con la imagen de fondo), ya que no se consideran objetos en movimiento hasta que no se aplican los umbrales. - 36 - 3.2.5 Actualización de fondo Las imágenes procesadas con el algoritmo Sakbot provienen de imágenes captadas por una cámara, por lo tanto pertenecen a una escena en constante movimiento. Esto supone que la imagen de fondo cambia en el transcurso del video analizado, especialmente si se tratan de imágenes que pertenecen a cámaras de vigilancia que graban de forma continua durante largos periodos de tiempo. En este contexto, el algoritmo se tiene que adaptar, ajustar a estos cambios. Esto se consigue mediante un paso de actualización de la imagen de fondo. El modelo de actualización utilizado en el algoritmo Sakbot se basa en la hipótesis estadística que los puntos que pertenecen a la imagen de fondo son los puntos más probables observados en una ventana limitada de tiempo de observación. Como función estadística, se utiliza la mediana de los fotogramas de muestreo, que se ha comprobado que es eficaz y requiere un número limitado de fotogramas, por lo tanto gasta menos tiempo y recursos de memoria. La imagen de fondo esta normalmente calculada con una función adaptativa que toma en consideración los valores previos de la imagen de fondo y el fotograma actual. Para mejorar la estabilidad de la actualización de fondo, se incluye un factor adaptativo (la imagen de fondo anterior con un peso adecuado ). Así definimos la función: ( ) Con la utilización de la estadística para el calcula de la imagen de fondo, los puntos que pertenecen a MVo no deberían ser incluidos en la imagen de fondo calculada, debido a su baja ocurrencia. Aun así, pueden ocurrir muchos errores, especialmente cuando los objetos son grandes, de color homogéneo, y lentos. En estos casos, los puntos de MVO podrían ser incluidos en la imagen de fondo. La actualización estadística y adaptativa se mejora para incluir una actualización selectiva, que no actualiza el valor de la imagen de fondo si el punto pertenece a un MVO en el fotograma actual. El inconveniente es la posibilidad de llegar a un punto muerto. Si por alguna razón un punto fijo es marcado erróneamente como en movimiento, se excluirá de la actualización de fondo, y por lo tanto se detectara como en movimiento para siempre. Para remediar este problema, los MVO se excluyen del calculo de la imagen de fondo después de una validación más: los MVO deben de tener un flujo óptico promedio (aOF) distinto de cero. - 37 - Se define la actualización S&KB (“estadística y basada en conocimiento) para cada punto que pertenece a como: { ( ) Ilustración 12 - Actualización de imagen de fondo La Ilustración 12 muestra el efecto de añadir la información basada en conocimiento de los objetos en movimiento. La ilustración (a) muestra la escena con 3 barreras cerradas. En la ilustración (b) una de las barreras se ha levantado y un coche esta pasando. En este fotograma 4 MVO son detectados: el coche, las personas, la barrera que se levanta y una barrera virtual en posición horizontal (marcada con un círculo). Este objeto es un falso positivo, ya que su flujo óptico es cero. Por lo tanto, los puntos que pertenecen al área de la barrera virtual se actualizaran en la imagen de fondo con valores actuales. Los puntos que pertenecen a los otros objetos detectados no se actualizaran. 3.2.6 Detección de sombras El módulo de detección de sombras pretende mejorar tanto la detección de MVO como el proceso de actualización de la imagen de fondo. La detección de sombras se basa en el análisis de crominancia, y se aplica solo a los puntos que pertenecen a los MVOs. Se utiliza para limitar los cálculos y para eliminar sombras fijas que pertenecen a la imagen de fondo. Para detectar las sombras, primero convertimos la imagen desde el espacio de colores (R, G, B) a (H, S, V). El espacio (H, S, V) reproduce mejor el comportamiento de la visión humana y es más sensible a cambios de luminosidad causadas por sombras. Se ha observado que un pixel “tapado” por una sombra se vuelve más oscuro (componente V), pero también sufre una saturación de color (componentes H y S). Por lo tanto, para un pixel sombreado se cumple lo siguiente: - 38 - ( ( { ) ) | ( | ( ) ( ) ( ) | ) | Donde: De forma intuitiva, esto significa que una sombra oscurece un pixel “tapado”, pero no demasiado. El rango de es , significando que un punto sombreado se oscurece en un 20%. En esta ecuación, mide el “poder” de la sombra, o la fuerza de la fuente de luz en comparación con la reflectancia de los objetos. Así, en escenas con mucha luz, se debería utilizar un valor bajo para . El rango típico para es ; valores más altos para tienen como efecto una detección de sombras demasiado sensible al ruido. El valor típico para y es 0.15. Ilustración 13 - Detección de sombras En la Ilustración 13 se muestra un ejemplo de la mejora que se puede obtener con este método. La figura de la izquierda muestra el fotograma original. En el fotograma de la derecha, los pixeles de fondo son de color negro, los pixeles sombreados detectados gastando solo la condición sobre le componente V están en gris claro, y los pixeles detectados gastando también las condiciones sobre H y S, en blanco. - 39 - En la figura se puede notar que el coche también contiene algunos pixeles de color gris claro, concluyendo que utilizando información de color reduce la incidencia de falsos positivos en la detección de sombras y las sombras reales son detectadas con mayor eficiencia. 3.3 Diseño Para la implementación del algoritmo Sakbot se ha decidido utilizar la estructura de clases presentada en la Ilustración 14. El programa presenta una clase principal, Sakbot, que contiene todos los métodos necesarios para: - Leer video de entrada - Procesar la información de cada fotograma para obtener los objetos en movimiento - Implementar cada paso del algoritmo Sakbot, presentados en el capitulo anterior - Escribir el video resultado, donde se marcan los objetos encontrados Aparte de la clase principal, se han implementado las siguientes clases: - VideoSourceReader o Ofrece métodos para obtener distintas propiedades del video y leer el video fotograma por fotograma. - VideoSourceWriter o Permite escribir los resultados a video de una forma sencilla - MVO o Define la estructura en la que se van a guardar los objetos encontrados. - 40 - Ilustración 14 - Diseño clases - 41 - 3.4 Implementación En el presente capitulo se van a describir los detalles de implementación del algoritmo Sakbot. Para el desarrollo del proyecto, se ha decidido utilizar la biblioteca OpenCV. Esta biblioteca, como ya se comentó en el capítulo anterior, proporciona una serie de rutinas que facilitan enormemente la manipulación de imágenes y videos. Esta manipulación es necesaria puesto que estos algoritmos básicamente funcionan comparando un fotograma con otro y se tiene que acceder a las propiedades de cada uno de ellos. Para la implementación de los distintos algoritmos utilizados se ha utilizado la aplicación Visual Studio C++ y por tanto el lenguaje de programación C++. Se ha decidido trabajar con esta aplicación debido a que permite una sencilla instalación de la biblioteca OpenCV (en el Anexo se comenta su instalación) y respecto al lenguaje de programación, ya en el capítulo anterior se comentó que esta biblioteca estaba implementada en C y C++. Además, otro de los aspectos fundamentales respecto a la elección de esta aplicación y de este lenguaje ha sido el conocimiento, por parte el alumno, de ambos debido al hecho de haber trabajado con ellos durante el transcurso de su carrera. Para comprobar si el algoritmo detecta correctamente los objetos en movimiento ha sido necesario disponer de unos videos de prueba. Los vídeos utilizados para las pruebas se han conseguido desde. Apreciamos que hayan ofrecido este material para el uso público. En la Ilustración 15 se muestra una captura de uno de los videos utilizados en las pruebas. - 42 - Ilustración 15 - Captura video de prueba Todos los vídeos utilizados se han obtenido utilizando cámaras fijas y captan imágenes de tráfico. En la 0 se pueden encontrar una colección de este tipo de capturas. 3.4.1 Clase VideoSourceReader Para la realización del proyecto se ha utilizado una clase con el fin de simplificar el uso de las funciones definidas por OpenCV para el tratamiento de videos. Las rutinas implementadas en esta clase se detallan a continuación: El constructor llama a la rutina cvCaptureFromAVI() con el nombre del archivo pasado como argumento, también obtiene el número total de fotogramas. o IplImage * QueryFrame(bool &stop) Si nos encontramos en el último fotograma del video pone a true la variable stop, en caso contrario devuelve el resultado de realizar una llamada a cvQueryFrame. o int GetNCols() Esta función devuelve el resultado de llamar a cvGetCaptureProperty pasándole como argumento CV_CAP_PROP_FRAME_WIDTH. - 43 - o int GetNRows() Esta función devuelve el resultado de llamar a cvGetCaptureProperty pasándole como argumento CV_CAP_PROP_FRAME_HEIGHT. o int GetNumFrames() Esta función devuelve el número total de fotogramas que contiene el video. En el constructor de la clase se obtiene el número total de fotogramas llamando a cvGetCaptureProperty pasándole como argumento CV_CAP_PROP_FRAME_COUNT. o double GetFramesPerSecond() Esta función devuelve el resultado de llamar a cvGetCaptureProperty pasándole como argumento CV_CAP_PROP_FRAME_FPS. En la Ilustración 16, se muestra un ejemplo de funcionamiento de esta clase. _videoInput = new VideoSourceReader(videoInputPath) ; numberFrames fps numberCol numberRow = = = = _videoInput->GetNumFrames(); _videoInput->GetFramesPerSecond(); _videoInput->GetNCols(); _videoInput->GetNRows(); while(!stop) { frame = _videoInput->QueryFrame(stop); } Ilustración 16 - Ejemplo VideoSourceReader En este ejemplo, se crea una estructura cvCapture con el nombre del video mediante el constructor de la clase. A través de ella, podemos obtener fácilmente información del video como el número de fotogramas, el número de fotogramas por segundo, el número de filas de los fotogramas del video o el número de columnas de los fotogramas del video. A continuación, se obtiene cada fotograma del video utilizando la función QueryFrame(). - 44 - 3.4.2 Clase VideoSourceWriter Para facilitar la escritura de los resultados a fichero, se ha creado la clase VideoSourceWriter. Las rutinas implementadas en esta clase se detallan a continuación. o VideoSourceWriter(const char* videoPath, int fps, CvSize size ) El constructor llama a la rutina cvCreateVideoWriter(videoPath, 0, fps, size) con el nombre del archivo de salida pasado como argumento, el numero de fotogramas por segundo deseado y el tamaño de la imagen. El segundo parámetro de esta función especifica el códec a utilizar. Se le pasa 0, para que Windows escoja el formato deseado según el tipo de fichero que se le pasa como argumento (ejemplo: si el fichero es “salida.avi”, el códec utilizado será para formato avi). o Void WriteFrame(IplImage* frame) Esta función escribe el fotograma frame a fichero. Utilizando la función cvWriteFrame() 3.4.3 Clase MVO La clase MVO esta diseñada para guardar los elementos encontrados en la imagen. Los métodos implementados para llevar a cabo esta tarea son: o AddPoint(int x, int y) Añade un punto de coordenadas x e y en la lista de puntos. o RemovePoint(int x, int y) Elimina el punto de coordenadas x e y de la lista de puntos. o Int GetArea() Calcula y devuelve el área de la zona ocupada por los puntos guardados en la lista. o AddMVO(MVO* b) Añade los puntos de b a la propia lista de puntos. - 45 - 3.4.4 Clase Sakbot A continuación vamos a detallar la implementación de los distintos pasos presentados en el algoritmo Sakbot. 3.4.4.1 Estructura general Ilustración 17 - Clase Sakbot El método principal de la clase es el método Run(). Este método se encarga de cargar el video de entrada y, fotograma por fotograma, ejecutar cada uno de los pasos del algoritmo Sakbot. Para finalizar, guarda los resultados en el video de salida. Los pasos que se ejecutan son, en orden: - Obtener fotograma actual - Suprimir la imagen de fondo, para obtener los objetos que pertenecen al primer plano - Aplicar el umbral Tlow, eliminado los pixeles no deseados - Eliminar sombras, para eliminar los pixeles sombreados - Aplicar operadores morfológicos - Etiquetar los objetos encontrados - Calcular el movimiento para cada objeto - 46 - - Guardar el resultado (en esta caso, marcar los objetos encontrados en la imagen resultado, que se guardara a video) Actualizar la imagen de fondo - A continuación, vamos a detallar cada método implementado. 3.4.4.2 Supresión de fondo La supresión de fondo se implementa en el método BackgroundDifference(frame, background). El objetivo de este método es obtener una imagen escalar, donde ( ) ( ( ) ( )) (| ( ) ( ) | ) La implementación es trivial. Por cada pixel con x = 0 - numero de columnas e y = 0 numero de filas, obtener los componentes R, G y B de las imágenes frame(el fotograma actual) y background (la imagen de fondo actual). El resultado es el valor máximo de las diferencias en R, G y B de las dos imágenes. El valor de R, G, B de los pixeles se obtiene mediante acceso directo (ver [7]para otros métodos de acceso al valor del pixel). Los métodos utilizados son los siguientes: static int GetR(IplImage* image, int row, int col) { return ((uchar *)(image->imageData + row*image->widthStep))[col*image>nChannels + 2]; }; static int GetG(IplImage* image, int row, int col) { return ((uchar *)(image->imageData + row*image->widthStep))[col*image>nChannels + 1]; }; static int GetB(IplImage* image, int row, int col) { return ((uchar *)(image->imageData + row*image->widthStep))[col*image>nChannels + 0]; }; Ilustración 18 - Métodos acceso a R, G, B El resultado es una imagen en niveles de gris, donde los pixeles de color negro se consideran que pertenecen a la imagen de fondo y los pixeles gris pertenecen al primer plano y son candidatos de ser pertenecientes a objetos en movimiento. - 47 - Ilustración 19 - Supresión de fondo 3.4.4.3 Aplicar el umbral y eliminar sombras En el paso anterior se ha obtenido el mapa de los pixeles pertenecientes al primer plano. Como se puede notar en la Ilustración 19, la imagen resultado presenta un cierto número de pixeles no deseados, que resultan por pequeños movimientos de la cámara, cambios de luz, o movimiento de elementos muy pequeños, como hojas de arboles. Vamos a eliminar estos puntos aplicando un umbral bajo y la detección de sombras. Tal como se detallo en los capítulos 3.2.3 y 3.2.6, se eliminan los puntos con un valor < y los puntos que se detectan como sombras. Estas dos operaciones se ejecutan solo sobre los puntos que tienen un valor > 0 en primer plano. , o solo sobre los puntos que pertenecen al Ilustración 20 - Resultado umbral Para aplicar el paso de detección de sombras, hace falta convertir las imágenes del espacio BGR al espacio HSV. Esto se consigue utilizando la función OpenCV cvtColor(). - 48 - o cvtColor(const Mat& src, Mat& dst, int code) Convierte una imagen desde un espacio de color a otro. - Src y dst son las imágenes de entrada y salida, respectivamente. - Code representa el tipo de transformación a llevar a cabo. Algunos de los códigos más utilizados son: o CV_BGR2HSV o CV_RGB2GRAY o CV_BGR2HLS El método definido en nuestro programa que ejecuta la aplicación del umbral es: o ApplyThreshold(IplImage* dbt, IplImage* frame, IplImage* background) - Dbt es la imagen obtenida durante la supresion de fondo. Frame es el fotograma actual. Background es la imagen de fondo El método primero convierte las imágenes frame y background al espacio HSV, utilizando copias para no modificar las imágenes originales. Luego, por cada pixel, si su valor es menor que o se detecta como sombreado, se elimina de . 3.4.4.4 Aplicar operadores morfológicos OpenCV proporciona funciones morfológicas. Estas permiten manipular imágenes binarias y a veces de varios canales de una manera que permite un mayor control sobre la segmentación de una imagen. Con el fin de llevar a cabo los operadores morfológicos, se requiere un elemento estructural. Se trata de un núcleo que especifica la forma del operador morfológico. Las formas CV_SHAPE_RECT y CV_SHAPE_ELLIPSE son los más comunes. Una vez definida la forma que vamos a utilizar, se crea el elemento de estructura. Es una matriz que debe de tener un numero impar de filas y columnas, es decir 3x3, 5x5 siendo las más comunes. 0 La función de OpenCV que aplica las operaciones morfológicas es: o morphologyEx(const Mat& src, Mat& dst, int op, const Mat& element, Point anchor) - src – imagen fuente dst – imagen destino - 49 - - element – elemento estrctural op – tipo de operación, una de las siguientes o MORPH_OPEN para apertura o MORPH_CLOSE para clausura void ApplyMorphology(IplImage* imagen) { // se utiliza un elemento rectangular de dimension 3x3 cv::Mat structElem = getStructuringElement(CV_SHAPE_RECT, Size(3,3), Point(1,1)); // aplicamos closing morphologyEx(Mat(imagen), Mat(imagen), MORPH_CLOSE, structElem); // aplicamos opening sobre el resultado de close morphologyEx(Mat(imagen), Mat(imagen), MORPH_OPEN, structElem); }; Ilustración 21 - Métodos morfológicos Ilustración 22 - Resultado operadores morfológicos Se puede observar el la Ilustración 22 que los pixeles causados por el ruido han desaparecido. Además, la forma de los objetos es más compacta, facilitando así el trabajo de las fases posteriores del algoritmo. - 50 - 3.4.4.5 Etiquetado El etiquetado es la tarea de encontrar. Marcar y guardar los objetos presentes en la imagen. Esto se lleva a cabo sobre la imagen , que en este punto marca solo los pixeles más probables de ser objetos en movimiento. La tarea implica la implementación de un algoritmo que identifique los puntos unidos de la imagen y guardar estos puntos en una estructura que luego se pueda utilizar el los próximos pasos. Lo que buscamos implementar es un algoritmo de conectividad. Existen varios algoritmos de conectividad de pixeles, que se definen según el grado de conectividad 0. Las distintas opciones son: - Conectividad 4. Un pixel es conectado con los pixeles que tocan sus bordes. - Conectividad 6. Un pixel es conectado con los pixeles que tocan una de sus esquinas, incluyendo los pixeles que tocan los bordes, de una forma hexagonal - Conectividad 8. Un pixel es conectado con los pixeles que tocan una de sus esquinas o bordes. Para aumentar la eficiencia del programa, se ha decidido implementar el algoritmo de conectividad 4, tal como se presenta en [3]. El algoritmo que se presenta en [3]es un algoritmo de 2 fases, tal como es definido en 0. En el primer pase: 1. Se itera por cada pixel, primero por columnas, luego por filas 2. Si el pixel no pertenece a la imagen de fondo (su valor es > 0 en nuestro caso) a. Establecer los vecinos del pixel actual b. Si no existen vecinos (pixeles con valor > 0) , marcar el pixel actual de forma única y continuar c. Si existen vecinos, encontrar los vecinos con la marca de menor valor y asignar esa marca al pixel actual d. Guardar la equivalencia entre marcas conectadas En el segundo pase: 1. Iterar por cada pixel, primero por columnas, luego por filas 2. Si el elemento no pertenece a la imagen de fondo a. Renombrar el pixel con el valor mínimo de las marcas equivalentes. - 51 - Tal y como se presenta este algoritmo, no es muy eficiente para utilizar en el programa, ya que necesitaríamos un pase más, para guardar las regiones identificadas en la lista de objetos. Por lo tanto, vamos a modificar este algoritmo y convertir las 3 fases en una sola, así minimizando el número de recorridos sobre la imagen. La propuesta es el siguiente algoritmo: Int k = 0 (marcador de regiones) Se itera por cada pixel de , primero por columnas, luego por filas. Si el pixel no pertenece a la imagen de fondo, entonces 1. Establecer si tiene vecino arriba ( ( ) > 0) y a la izquierda ( ( ) > 0) 2. Si no tiene vecinos (arriba = false e izquierda = false) a. Marcar el pixel con k. b. Crear objeto MVO y añadir el pixel (row, col). c. K++ 3. Si tiene vecino arriba (arriba = true e izquierda = false) a. Copiar el valor del pixel de arriba. ( )= ( ) b. Añadir el pixel (row, col) a MVO [ ( )]. Añadimos el pixel al MVO de la marca encontrada, ya que el pixel es conectado a esta región 4. Si tiene vecino a izquierda (arriba = false e izquierda = true) a. Copiar el valor del pixel de izquierda. ( )= ( ) b. Añadir el pixel (row, col) a MVO [ ( )]. 5. Si tiene vecinos arriba y a la izquierda a. Caso 1. Arriba e izquierda pertenecen a la misma región (están marcados con el mismo valor) i. Copiar el valor del pixel de arriba. ( )= ( ) ii. Añadir el pixel (row, col) a MVO [ ( )]. b. Caso 2. Arriba e izquierda pertenecen a regiones distintas. Estos significa que el pixel actual une 2 regiones, convirtiéndolas en una sola. i. Encontrar el mínimo valor de las 2 regiones. ii. Si existe equivalencia para el valor mínimo, entonces recuperar ese valor. Guardar equivalencia para el valor máximo, apuntando al valor recuperado. De esta forma, tanto mínimo y máximo apuntan a la misma equivalencia mínima. iii. ( ) = equivalencia mínima encontrada iv. Unir los MVO de las 2 regiones encontradas. - 52 - El algoritmo presentado se implementa en la función del programa o LabelForeground(IplImage* foregroundMap, vector<MVO*>& lista) - foregroundMap es la imagen Dbt lista es un parámetro de salida, que se rellena con los MVO encontrados 3.4.4.6 Flujo óptico promedio El método se implementa en la función OpticalFlow(IplImage *input1, IplImage* input2, vector<MVO*>& mvoList) de la forma que se presenta en 0, adaptado a las necesidades del programa. En 0 se presenta un ejemplo de utilización de las funciones ofrecidas por OpenCV para llevar a cabo la tarea de calcular el movimiento de un objeto entre 2 fotogramas. o cvCalcOpticalFlowPyrLK(const CvArr* prev, const CvArr* curr, CvArr*prevPyr, CvArr* currPyr, const CvPoint2D32f* prevFeatures, CvPoint2D32f* currFeatures, int count, CvSize winSize, int level, char* status, float* track_error, CvTermCriteria criteria, intflags) - prev Primer fotograma, en el momento t - curr Segundo fotograma, en el momento t + dt - prevPyr Buffer para la pirámide para el primer fotograma - currPyr Buffer para la pirámide para el segundo fotograma - prevFeatures Vector de puntos para los que se necesita calcular el flujo óptico - currFeatures Vector de puntos donde se guardaran las posiciones calculadas de los puntos del primer fotograma en el segundo. - count Numero de puntos encontrados (el tamaño real del vector currFeatures) - winSize Tamaño de la ventana de búsqueda - level - 53 - Nivel máximo para la búsqueda piramidal - status Vector. Cada elemento de este vector tendrá valor = 1 si se encontró el flujo para el elemento, 0 sino. - track_error Vector que guarda el error de flujo para cada elemento - criteria Específica el criterio para parar la búsqueda. El método cvCalcOpticalFlowPyrLK() se ejecuta para los puntos de cada elemento de la lista de MVO. Al final de la ejecución del método, utilizando los resultados obtenidos, se calcula el flujo óptico promedio. // ejecutar el algoritmo Lucas Kanade Piramidal cvCalcOpticalFlowPyrLK(correctedInput1, correctedInput2, pyramid1, pyramid2, frame1_features, frame2_features, number_of_features, optical_flow_window, 5, optical_flow_found_feature, optical_flow_feature_error, optical_flow_termination_criteria, 0 ); float sum = 0; for(int i = 0; i < number_of_features; i++) { // si el elemento no se encontro, eliminarlo if ( optical_flow_found_feature[i] == 0 ) { // punto no se movio, así que se puede eliminar b->RemovePoint(i); } else { float dx = frame1_features[i].x - frame2_features[i].x; float dy = frame1_features[i].y - frame2_features[i].y; sum += sqrt( square(dy) + square(dx) ); } } // flujo optico promedio mvoActual->averageOpticalFlow = (sum / number_of_features); Ilustración 23 - Calculo flujo óptico promedio La Ilustración 23 muestra la implementación del cálculo del flujo óptico promedio. Los parámetros de entrada para la función cvCalcOpticalFlowPyrLK() se inicializan previamente. CorrectedInput1 y correctedInput2 corresponden al fotograma anterior y fotograma actual, respectivamente, convertidas a imágenes en niveles de gris. La ventana utilizada - 54 - para la búsqueda es de tamaño 5x5. Los vectores de elementos se han inicializado con un tamaño de 500 elementos. El parámetro frame1_features contiene los puntos de mvoActual, para los que se tiene que calcular el flujo óptico. 3.4.4.7 Guardar el resultado Después del último paso, se pueden aplicar los últimos criterios para los objetos encontrados. Para que los MVO detectados se consideren objetos en movimiento, tienen que cumplir la condición de umbral de flujo óptico mínimo (que tenga un movimiento superior a un límite establecido), y un área mayor que un límite establecido. Los objetos que cumplen estas condiciones se marcan en la imagen resultado. La imagen compuesta por el fotograma actual y los objetos marcados se guarda al video de salida de programa. 3.4.4.8 Actualización de la imagen de fondo Para hacer frente al constante cambio de la imagen, la imagen de fondo se tiene que actualizar. La ecuación que se utiliza para esta tarea es: ( ) En el ámbito de la estadística, la mediana representa el valor de la variable de posición central en un conjunto de datos ordenados. Su cálculo no se ve afectado por valores extremos. [16] La frecuencia de actualización se tiene que escoger de tal forma que no implique un sobrecoste de procesamiento, pero que al mismo tiempo responda ante cambios del entorno de una manera rápida. Por lo tanto, la frecuencia escogida es de una vez cada segundo, o una vez por cada FPS fotogramas procesados. El algoritmo utilizado para la actualización de la imagen de fondo es el siguiente: 1. Obtener fotograma actual 2. Si el índice de la fotograma actual es igual al valor de fotogramas por segundo, entonces: a. Añadir fotograma actual al vector de historia de imágenes de fondo, manteniendo el tamaño máximo de este. b. Aplicar la función mediana para: - 55 - i. cada uno de los componentes R, G y B ii. cada pixel de las fotogramas [0, n-1] que pertenecen al vector de historia de imágenes de fondo más la imagen de fondo actual c. Actualizar el valor de la imagen de fondo actual con el valor calculado mediante la función mediana. 3.4.5 Ejecución programa El programa Sakbot.exe se ejecuta desde la línea de comandos, y requiere por lo menos 2 parámetros. Los parámetros aceptados por el programa son los siguientes: 1. –mov <enlace a video> Utiliza la opción para ejecutar el programa sobre un video (.avi) presente en disco 2. –cam <numero de cámara> Utiliza esta opción para ejecutar el programa sobre las imágenes obtenidas con una webcam. Las opciones [1] y [2] se excluyen mutuamente. 3. –outV <enlace a video> Enlace al nombre del video resultado, en caso de desear la escritura de los resultados a un video 4. –outR Utiliza la opción para mostrar los resultados en una ventana, en tiempo real de procesamiento. Las opciones [3] y [4] se excluyen mutuamente. 5. –m Los objetos encontrados se van a marcar en las imágenes resultado utilizando una mascara. 6. –nb Por defecto, los objetos se van a marcar utilizando rectángulos. Esta opción deshabilita este comportamiento. - 56 - 3.5 Validación y pruebas Tal como se menciono en la introducción, el algoritmo Sakbot se utiliza principalmente para la monitorización de escenas de tráfico. Por lo tanto, las pruebas se han ejecutado sobre este tipo de videos, que han sido obtenidos desde la página [9]. Los videos obtenidos representan imágenes de una intersección, tomadas en días soleados. Los vídeos tienen un tamaño de 720x480 y el número de fotogramas por segundo es de 29fps. En la siguiente ilustración se presenta una captura de uno de estos videos. Ilustración 24 - Ejemplo video utilizado en las pruebas Los parámetros de ejecución del programa Sakbot se tienen que ajustar al tipo de escena que se esta utilizando, para obtener resultados satisfactorios. En concreto, hace falta afinar los valores de los umbrales utilizados. En las ilustraciones Ilustración 25, Ilustración 26, Ilustración 28 se pueden observar los efectos de utilizar distintos valores para el umbral bajo. El propósito de utilizar un umbral bajo es eliminar los puntos causados por el ruido. Se puede observar que utilizando un umbral demasiado pequeño no elimina los pixeles de ruido, pero utilizando un umbral con - 57 - un valor demasiado grande puede provocar la eliminación de pixeles que si nos interesan, como los que forman parte de objetos. El umbral escogido en la implementación para el tipo de escena con el que trabajamos es igual a 25. Este valor representa un compromiso entre el número de pixeles de ruido que no se eliminan y la consistencia de los objetos que se buscan. El umbral alto se utiliza conjuntamente con el umbral bajo para marcar los pixeles que tienen una diferencia fuerte con la imagen de fondo. Un objeto se descarta si no contiene por lo menos un pixel con un valor mayor al umbral alto. El valor escogido en la práctica para el umbral alto es igual a 75, ya que, como se puede observar en la Ilustración 28, un umbral mayor empieza a eliminar los pixeles que nos interesan. Ilustración 25 - Imagen de diferencia con umbral = 10 Ilustración 26 - Imagen de diferencia con umbral = 25 - 58 - Ilustración 27 - Imagen de diferencia con umbral = 75 Ilustración 28 - Imagen de diferencia con umbral = 100 Otra parte del algoritmo que utiliza umbrales es la detección y eliminación de sombras. Para establecer unos valores aceptables para los umbrales de sombreado, se han tomado varios de pixeles sombreados y comparado con el valor del mismo pixel cuando no esta sombreado. Mediante este procedimiento, se han obtenido los siguientes resultados: Pixel Pixel Sombreado Resultado Pixel Pixel Sombreado Resultado H 162 180 18 0 27 27 S 4 16 14 10 25 15 V 56 16 0.2 54 16 0.29 - 59 - Pixel iluminado Pixel del fondo sin sombreado Resultado 198 149 11 6 35 56 49 5 0.6 Tabla 5 - Valores H, S, V para pixeles sombreados Recordamos que los valores recomendados en - 65 - para os umbrales utilizados en la detección de sombras son los siguientes: - el rango de es - el rango típico para es - el valor típico para y es 0.15. También se menciona que los valores de y miden el cambio en la fuerza de la luz, por lo tanto se deben de ajustar al tipo de entorno con el que trabajamos. Los videos utilizados se han tomado en días soleados, por lo tanto las sombras tienen un color muy oscuro, casi negro. En las pruebas presentadas en Tabla 5 se puede observar que los valores para el componente V oscilan alrededor de 0.2. Por lo tanto, vamos a fijar = 0.1 y = 0.6. Según las pruebas realizadas, se ha visto que los valores resultado para H y V, en nuestro contexto, oscilan entre 15 y 30. Utilizando límites más altos se pueden clasificar puntos que pertenecen a los objetos como sombreados. Cabe destacar que los valores de referencia para y presentados en [1] no se pueden aplicar para los videos utilizados en las pruebas para este proyecto debido a la diferencia en calidad y tipo de videos utilizados. Ilustración 29 - Resultado detección de sombras sobre un coche En Ilustración 29 e Ilustración 30 se pueden observar los efectos de aplicar la ecuación de detección de sombras con los parámetros calculados anteriormente. Se pueden notar (en blanco) los pixeles detectados como sombras. Se puede observar que la ecuación detecta las sombras, pero, aparte, también detecta pixeles del proprio objeto como sombras también. Esto lleva a la conclusión que es difícil encontrar unos valores empíricos de umbral para los componentes H y S. - 60 - Ilustración 30 - Resultado detección de sombras en una escena Un aspecto muy importante del algoritmo Sakbot es la actualización de la imagen de fondo, del que vamos a pasar a hablar ahora. Mediante la práctica se ha observado que una buena actualización de la imagen de fondo mejora el proceso de segmentación de la imagen de diferencia. Se recomienda, en trabajos como [4], calcular la imagen de fondo a partir de fotogramas que no contienen movimiento, por ejemplo capturas de una intersección cuando no hay tráfico. La ecuación de mediana presentada en [1] utiliza un peso asignado a la imagen de fondo previa, lo que garantiza, junto con la utilización de la información de objetos detectados, que los objetos en movimiento no se van a introducir en la imagen de fondo. Dado que los videos utilizados para las pruebas de este proyecto no contienen fotogramas sin movimiento, la ecuación de actualización ha sido modificada. Estas modificaciones incluyen: - no se asigna un peso a la imagen de fondo previa - no se utiliza la información de los objetos detectados Estas modificaciones fuerzan una actualización más rápida de la imagen de fondo, garantizando que, por ejemplo, los objetos que pertenecen al primer fotograma del video, fotograma que se toma como valor para la imagen de fondo inicial, se eliminen en como máximo 5 segundos. En la Ilustración 31 se puede observar, marcado con azul, el objeto en movimiento y marcado con rojo el mismo objeto que aun pertenece a la imagen de fondo (que lleva el nombre de fantasma), resultando en un falso positivo (objeto detectado en movimiento, cuando no es así). A partir del segundo 4 de video, la región es actualizada correctamente y el objeto fantasma es prácticamente imperceptible, como se puede observar en la Ilustración 32. - 61 - Ilustración 31 - Fantasma de objeto no actualizado Ilustración 32 - Región de fotograma actualizado - 62 - 4. Conclusiones En este proyecto se ha estudiado e implementado el algoritmo Sakbot, algoritmo de segmentación video utilizado principalmente para videos de monitorización de tráfico. Para conseguir los objetivos marcados al inicio del proyecto, se tuvieron que buscar, estudiar, analizar y adaptar trabajos previos como soporte a la hora de implementar las distintas fases del algoritmo, como por ejemplo el trabajo presentado en - 65 -. Este proceso se considera necesario en el ámbito de un ingeniero informático. Del mismo modo, se espera que el trabajo presentado en este proyecto sirva de apoyo para futuros trabajos relacionados con esta temática. Durante los años de estudio de la carrera, el alumno ha ido adquiriendo conocimientos que le han permitido poder hacer frente a la realización de este proyecto. Estos conocimientos incluyen el aprendizaje de lenguajes de programación necesarios para poder implementar los distintos algoritmos, así como los conceptos contenidos en los fundamentos algorítmicos necesarios para poder entender la idea presentada en los documentos que se estudiaron previamente. Asimismo, en las distintas asignaturas donde se han estudiado técnicas de programación estructuradas y orientadas a objetos han permitido al alumno organizar los conceptos e implementarlos de forma adecuada, utilizando técnicas que permitieran crear una estructura en el código clara, ordenada y eficiente. Finalmente, los conocimientos adquiridos sobre el desarrollo de proyectos software han sido utilizados en la planificación y organización del proyecto. Para realizar el proyecto se han tenido que adquirir una serie de nuevos conceptos. El alumno no tenía conocimientos previos sobre la visión por computador y ha tenido que adquirir los necesarios para poder desarrollar el proyecto. Sin embargo, el ser un campo desconocido para el alumno, la elección de la temática del proyecto ha propiciado el contacto con este campo tan fascinante. Además, el alumno ha tomado contacto también con la biblioteca OpenCV, familiarizándose así con el uso de código desarrollado por otros. Destacar que la herramienta utilizada para la implementación de los algoritmos así como el lenguaje de programación utilizado, pese a haber sido utilizadas previamente por el alumno, le han servido de práctica y por tanto perfeccionamiento de su uso. Los resultados finales obtenidos, si bien no suponen la solución perfecta al problema planteado, si que ofrecen una idea de hacia donde se tiene que encaminar futuros estudios y así poder realizar una correcta detección de objetos en movimiento en videos. A nivel personal, el alumno se siente satisfecho con el trabajo realizado. Ha podido tomar un contacto con un proyecto real, participar en su concepción y realización. Si bien a lo largo de la carrera el alumno ha realizado tareas más o menos complejas, ninguna ha - 63 - resultado de la envergadura del presente proyecto. Se han tenido que aplicar muchos conceptos, que se habían estudiado por separado, conjuntamente para ir resolviendo los contratiempos que han ido surgiendo. Como primea idea acerca de realizar un futuro estudio que se plantea es estudiar otros métodos u algoritmos para obtener mejores resultados en segmentación de video, detección de objetos y sombras. Finalmente, otra posible idea es continuar el trabajo mediante la implementación del modulo de seguimiento, que toma como entrada los objetos encontrados por el algoritmo de segmentación para realizar un seguimiento de los objetos de interés. - 64 - 5. Bibliografía [1] “The Sakbot System for Moving Object Detection and Tracking”, R. Cucchiara, C. Grana, G. Neri, M. Piccardi, A. Prati [2] “Detecting Objects, Shadows and Ghosts in Video Streams by Exploiting Color and Motion Information”, R. Cucchiara, C. Grana, M. Piccardi, A. Prati [3] “Handbook Of Image And Video Processing”, Alan Conrad Bovik (http://books.google.es/books?id=UM_GCfJe88sC&q=region+labeling+algorithm&redir_esc=y#v=onepag e&q&f=false) [4] “Background Subtraction for Urban Traffic Monitoring using Webcams, (Master Thesis)”, Mark Smids, Rein van den Boomgaard [5] “Documentación OpenCV” http://opencv.willowgarage.com/documentation/cpp/index.html [6] “OpenCV” http://sourceforge.net/projects/opencvlibrary/files/opencv-win/2.1/ [7] “Tutorial de OpenCv”, Raúl Igual, Carlos Medtrano http://docencia-eupt.unizar.es/ctmedra/tutorial_opencv.pdf [8] “The Scientist and Engineer’s Guide to Digital Signal Processing”, Steven W. Smith http://www.dspguide.com/ch25/4.htm [9] “MIT Traffic Data Set” http://www.ee.cuhk.edu.hk/~xgwang/MITtraffic.html [10] “Binary Images with OpenCV” http://www.neuroforge.co.uk/index.php/binary-images-with-opencv [11] “Pixel connectivity” http://en.wikipedia.org/wiki/Pixel_connectivity [12] “Connected-component labeling” http://en.wikipedia.org/wiki/Connected-component_labeling [13] “Sparse optical flow demo program” - 65 - http://robots.stanford.edu/cs223b05/notes/optical_flow_demo.cpp [14] “Segmentación (procesamiento de imágenes )” http://es.wikipedia.org/wiki/Segmentaci%C3%B3n_(procesamiento_de_im%C3%A1genes) [15] “Visión artificial” http://es.wikipedia.org/wiki/Visi%C3%B3n_artificial [16] “Mediana (estadística)” http://es.wikipedia.org/wiki/Mediana_(estad%C3%ADstica) [17] “Image sequence server”, Universitat Karlsruhe http://i21www.ira.uka.de/image_sequences/ - 66 - 6. Anexos 6.1 Instalación OpenCV Para la implementación de este proyecto se ha utilizado la versión OpenCV 2.1 para Windows. Esta versión se puede bajar desde el siguiente enlace. En particular se ha utilizado el instalable OpenCV-2.1.0-win32-vs2008.exe, para su facilidad de integración y utilización con la herramienta Visual Studio 2008. Para instalar, solo hace falta ejecutar el instalable y seguir los pasos indicados. 6.2 Utilización Visual Studio Microsoft Visual Studio es un entorno de desarrollo integrado (IDE, por sus siglas en inglés) para sistemas operativos Windows. Soporta varios lenguajes de programación tales como Visual C++, Visual C#, Visual J#, y Visual Basic .NET, al igual que entornos de desarrollo web como ASP.NET. Visual Studio permite a los desarrolladores crear aplicaciones, sitios y aplicaciones web, así como servicios web en cualquier entorno que soporte la plataforma .NET (a partir de la versión .NET 2002). Así se pueden crear aplicaciones que se intercomuniquen entre estaciones de trabajo, páginas web y dispositivos móviles. La versión utilizada de esta herramienta es Visual Studio 2008. Los pasos a seguirá para poder utilizar OpenCV en Visual Studio son los siguientes: 1) En primer lugar crear un nuevo proyecto (lleno o vacío) C / C + +. 2) Para un proyecto de aplicación (*. Exe) añadir lo siguiente a las propiedades de su proyecto: - Ir a Directorios VC + + - Añadir 2 nuevos directorios Include: o \ OpenCV2.1 \ include o \ OpenCV2.1 \ include \ opencv - Añadir un nuevo Directorio de la Biblioteca (es la ruta de acceso donde se ha instalado OpenCV, carpeta lib): o \ OpenCV2.2 \ lib - Ir al vinculador en el menú de la izquierda y seleccione la opción de entrada. Añadir estas entradas en opción Dependencias adicionales: - 67 - o \ OpenCV2.1 \ lib \ opencv_core220d.lib o \ OpenCV2.1 \ lib \ opencv_highgui220d.lib o \ OpenCV2.1 \ lib \ opencv_video220d.lib o \ OpenCV2.1 \ lib \ opencv_ml220d.lib o \ OpenCV2.1 \ lib \ opencv_legacy220d.lib o \ OpenCV2.1 \ lib \ opencv_imgproc220d.lib 3) Para un proyecto de biblioteca compartida de carga dinámica (DLL) añadir lo siguiente a las propiedades de su proyecto: - - C / C + + - General - Directorios de inclusión adicionales: o C: \ OpenCV2.2 \ include \ OpenCV, C: \ OpenCV2.2 \ include Enlazador - General - Directorios adicionales de la biblioteca: o C: \ lib \ OpenCV2.2 Enlazador - Entrada - Dependencias Adicionales (debug): o opencv_core220d.lib opencv_highgui220d.lib opencv_video220d.lib opencv_ml220d.lib opencv_legacy220d.lib opencv_imgproc220d.lib Enlazador - Entrada - Dependencias Adicionales (liberación): o opencv_core220.lib opencv_highgui220.lib opencv_video220.lib opencv_ml220.lib opencv_legacy220.lib opencv_imgproc220.lib - 68 -