II31 SISTEMAS INFORMÁTICOS Memoria Técnica del Proyecto

Anuncio
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 -
Descargar