martes, 29 de junio de 2010

Tests (II)

Ya que en indoor ya poseeemos videos de testing, y hemos visto que Runnin Gaussian se comportaría correctamente para modelar esta escena, se han estado buscando videos de outdoor, que pudieran sernos de utilidad para comprobar como se comporta el último método.

Se han conseguido varios ejemplos de cámaras de seguridad instaladas en espacios publicos, aunque los tamaños de los videos eran demasiado elevados.

Se han recomprimido los videos con diversos codecs, y he perdido algunos dias, testeando y reprogramando el interfaz y el algoritmo, ya que se producían efectos extraños en algunos frames de los videos, y he pensado que eran fallos de programación, pero algunos dias después me he percatado (por fin ¡¡¡) que eran debido al ruido que produce la compresión en función de los codecs, y eso impacta sobre la detección del fondo.

Finalmente, los videos se han comprimido en utilizando el codec MJPEG, que después de varias pruebas era el que menos ruido añadía a los frames. En el proceso de recompresión, también se han redimensionado a 420 x 340.

Se muestra a continuación, varias capturas de algunas pruebas realizadas:

1 - Cambios repentinos en la luminosidad de la escena:

En este test se quiere demostrar como se adapta el método a un posible cambio de claridad en el entorno, siempre con el fin de conseguir que se den las mínimas falsas detecciones posibles.






Respecto a los valores de inicialización del algoritmo, la intención es conseguir una tabla de valores aceptables que se adapten a las condiciones de una escena outdoor.

Los valores utilizados son el resultado de varias pruebas, partiendo de los valores que aconsejaban para un entorno indoor.

Como se puede observar, a partir del fram 950 empieza a cambiar la claridad de la escena, de izquierda a derecha, con un número despreciable de falsas detecciones.


2- Pequeños movimientos rápidos y constantes

En este test se añade a la situación del cambio de lumonosidad, la existencia de árboles en la escena sometidos a viento, lo que originará movimientos constantes.





Como podemos observar, en los momentos con más viento, no se produce un número de falsas detecciones excesiva en las áreas de los árboles, ya que el número de gaussianas por pixel en esa zona, amortizarán y se adaptarán a los cambios de valores de los píxeles.





Resultados:

Como se puede observar, esté método sería una buena elección para incluir en un proceso de tracking, además de por su tradición histórica, por la calidad de los resultados en un amplio caso de escenas. Por tanto, teniendo en cuenta que en facetas de precisión en entornos heterogéneos es aceptable, una posible mejora sería en aspectos de rendimiento.

Zivkovic en el estudio Efficient adaptive density estimation per image pixel for the task of background subtraction, propone una mejora de este método par que se comporte de forma adaptativa, en cuanto al número de guassianas por pixel, con la consecuente mejora de rendimiento.

Por otro lado, para perfeccionar la precisión de los métodos, otra posible opción sería estudiar algunos filtros a aplicar despues del procesado del frame, para eliminar falsas detecciones y sombras.

domingo, 27 de junio de 2010

Parámetros del modelo y pruebas

Examinando el documento de Wayne y Schoonees, Understanding Background Mixture Models for Foreground Segmentation, se han realizado algunas modificaciones, principalmente en las ecuaciones de actualización de parámetros del modelo.

Este documento hace un análisis del modelo propuesto por Stauffer-Grimson sobre el que estamos trabajando, a partir de varias pruebas empíricas, e intenta mostrar algunas aproximaciones al modelo teórico propuesto, mejorando algunas de sus partes, y proponiendo algunos valores de inicialización del modelo.

Principalmente, propone nuevas aproximaciones en los métodos de actualización. Si recordamos las fórmulas propuesto por Stauffer-Grimson :


Podemos observar que los valores carácteristicos de la gaussiana media y varianza, el parámetro de absorción que marca la velocidad de aprendizaje (p) , comunmente 0,01, es diferente al utilizado para actualizar los pesos de la Gaussiana que ha encajado (alfa), normalmente 0,05.

En este estudio Wayne y Schoonees, basándose en conceptos de probabilidad del teorema Bayesiano, redefinen las fórmulas de actualización de la media y la varianza, para que el parámetro de absorción se calcule en función de Alfa y el peso:



donde para evitar calcular la función de probabilidad en cada actualización propone:



en función si la gaussiana ha encajado o no.

Teniendo en cuenta que uno de los factores principales es una buena inicialización de los parámetros de las gaussianas, dado que no siempre se dará en caso de obtener un contexto donde podamos obtener una escena unicamente con el fondo, se provee una tabla con valores prácticos de los parámetros esenciales para una escena indoor.



A continuación se hará una serie de tests, para probar como se comporta el método en entornos indoor y outdoor, teniendo en cuenta la mayoría de las posibles escenas que se puedan dar en la vida real. Se harán pruebas con distintos parámetros de inicialización para extrapolar un conjunto de valores que se comporten bien en la moyoria de las condiciones.

Los parámetros más significativos son:

1- K (presentado en nuestro interfaz como Num Gaussianas)

Teniendo en cuenta que nuestro método, modela tanto el background como el foreground, el valor mínimo a tener en cuenta sería K=3, para modelar dos superficies de bakground y una de foreground por pixel. Considerar menos de 2 gaussianas para el background, el algoritmo sería innecesariamente complejo, y sería más recomendable usar el método de la media.
Se han hecho pruebas con hasta K=7, pero se ha comprobado que con un valor superior a 5 gaussianas, la mejora no es muy apreciable.

2- T

Es una medida de la mínima proporción de los datos que hay que tener en cuenta para formar parte del fondo. Elegiremos un valor pequeño, para fondos unimodales, y valores altos para fondos multimodales, provocados por pequeños movimientos repetitivos (movimiento de hojas,banderines,...), para asi poder incluir más de un color en el modelo del fondo.

3- Alfa

Velocidad de actualización.

4- Umbral

Podemos pensar en ello como el numero de varianzas alejadas de la media, para considerar a un valor como foreground.



TESTS

Se realizarán varios tests sobre escenas en el exterior, probando como se comporta el método en condiciones de cambios de luminosidad, modificaciones de la escena (objetos que pasan a ser parte del fondo) y movimientos constantes de pequeñas areas (hojas de los árboles).

sábado, 26 de junio de 2010

Implementación

1 - Estructuras de datos

- La estructura de la gaussiana en este caso, estará compuesta de una media para cada uno de los canales RGB, de una varianza común para los tres canales, de un peso asociado a esa gaussiana y de un factor de “importancia” para esa gaussiana (calculado como el peso entre la desviación estandar). El hecho de que exista una varianza común, se debe a una propuesta del documento de Stauffer & Grimson, para reducir el coste excesivo de la matriz, con la penalización de perder un poco de precisión.




- La estructura para almacenar las gaussianas del modelo, consistirá en una estructura de array con dimensión [alto X ancho X numeroGuassuinasMaximo] de estructuras del tipo comentado anteriormente.

arrayGaussianas = new Gaussiana[tamanio*numGaussianas]

- Para conocer el número de gaussianas por pixel en cada momento, construiremos una matriz gaussinasPorPixel donde almacenaremos en cada momento ese dato.

- En este caso se avitará la fase de entrenamiento. Para conseguirlo, las gaussianas iniciales se generarán con unos valores de media equivalentes a los valores que toma cada canal de ese pixel , una varianza inicial igual a un valor experimental elegido por nosotros y un peso igual a 1 (en el caso de ser la primera gaussiana generada). Estos valores se irán refinando con las posteriores actualizaciones.

2- Algoritmo de procesado

2.1. - En primer lugar, calcularemos, de las gaussianas que hay asociadas al pixel, el número de ellas q van a modelar el background, en funcion de que la suma de los pesos sea menor que T . Teniendo en cuenta que las gaussianas van ordenadas de mayor a menos, en funcion del parametro orden (peso/desviacion estandar).



2.2.- Recorremos todas las gaussianas asociadas a ese pixel . Para cada una:

2.2.1. - Calculamos la distancia del valor del pixel a la media, para comprobar si el valor encaja con la gaussiana en funcion de si la distancia es menor que la varianza * umbral

2.2.2.- Si encaja y la gaussiana pertence a el grupo de gaussianas que modelan el fondo, actualizamos sus parametros de media , varianza, peso y orden para esa gaussiana, y para las demás, actualizaremos el peso y el orden, en función de las fórmulas vistas en el post anterior.

Después renormalizamos los pesos para que sumen 1, y ordenamos las gaussianas de ese pixel de mayor a menos en función del parámetro orden.

2.2.3.- Si no encajara a ninguna generamos una nueva con los valores de inicializacion y recalculamos pesos y orden para todas.

2.2.4. - En función a la gaussiana que haya encajado con ese valor de pixel, decidiremos si el pixel corresponde a Background o Foreground

- Si ha encajado con alguna de las B primeras gaussianas que modelan el fondo, decidimos Background

- Si ha encajado con alguna gaussiana existente que no modela el fondo, o si ha habido que generar una nueva gaussiana, decidiremos Foreground.

jueves, 24 de junio de 2010

Mixture of Gaussians ( II )

En este método se propone como sistema de modelado, la suma ponderada de funciones Gaussianas por canal y píxel:



donde K es el número máximo de Gaussianas utilizadas para realizar la estimación del modelo (normalmente varía entre tres y cinco funciones distintas), G() representa cada una de las Gaussianas utilizadas, w son las ponderaciones que tienen cada una de las curvas, le media y la varianza son los parámetros estadísticos y Z es el valor del píxel en cuestión (magnitud vectorial perteneciente a R3).

Si asumieramos que trabajamos con imágenes en escala de grises, y el valor de K=5, el histórico de un pixel sería algo así:




Dicha estimación se utiliza para obtener un modelo de fondo y decidir si el píxel en cuestión se corresponde con el modelo de fondo o con un objeto de primer plano. En este caso, las Gaussianas representan tanto el fondo como el primer plano. Para decidirlo se aplicará un criterio de manera dinámica. De esta forma será posible introducir los objetos de primer plano en el modelo de fondo cuando permanezcan estáticos en la escena, asignando la Gaussiana correspondiente a fondo.

Para ello, cada píxel (i,j) de la imagen (donde i y j son los índices que representan la posición de fila y columna que ocupa el píxel dentro de la imagen) se modela como una combinación de distribuciones Gaussianas , relacionándose entre sí a partir de los factores de ponderación , que se modifican iterativamente en función de las veces que se da el valor que recogen, formando así el modelo probabilístico del píxel.

Los factores de ponderación se normalizan a fin de conseguir que el sumatorio total sea 1:



Consideramos que el fondo queda modelado por las B distribuciones Gaussianas de mayor peso y menor varianza



donde T es el umbral de decisión asignado (usualmente 0.6), y B es el número mínimo de distribuciones a incluir en el sumatorio , para que se cumpla la inecuación. Las distribuciones que ordenadas según el criterio del factor de ponderación entre la varianza. Este valor aumentará tanto si la evidencia de la distribución aumenta, como si su varianza disminuye.

El valor de T mide la mínima proporción de los datos que debe ser contemplada como background. Un valor bajo de T se usaría para fondos unimodales, y un valor elevado de T para distribuciones multimodales producidas por movimientos repetitivos en el fondo (arboles, banderas,…).

Las B primeras distribuciones Gaussianas serán las que modelarán la función de densidad de probabilidad del fondo, puesto que normalmente es más estático y aparece con más frecuencia, correspondiéndose con aquellas Gaussianas que han sido utilizadas más veces y que son más compactas.

Para comprobar si el valor del píxel de entrada encaja en alguna distribución Gaussiana del modelo probabilístico del píxel, se evalúa la siguiente inecuación:



Xt es el valor de un canal de color del píxel estudiado en el fotograma t, Ui,t es la media de la Gaussiana i-ésima y Oi,t la desviación estándar de la Gaussiana i-ésima.

Pueden darse dos casos, o que la inecuación de cumpla para todas las Gaussianas, o que no se cumple para alguna Gaussina. La forma de actuar sería la siguiente:

1- Si se cumple para todas las Gaussianas, se decide que el pixel es primer plano, puesto que no encaja con el modelo probabilístico del píxel aprendido hasta el momento. En este caso, se generará una nueva Gaussiana con el fin de permitir adaptar el modelo al fondo, eliminando la distribución con menor peso.

2- Si no se cumple para una Gaussiana, se supone que el valor encaja con el modelo probabilístico modelado mediante la misma (si la inecuación no se cumple para más de una Gaussiana, se supondrá que la función que mejor representa al píxel es la de menor varianza). En este caso, pueden darse dos casuísticas:

2.1.- si el valor del píxel encaja con una de las B primeras distribuciones Gaussianas se asignará a fondo, debido a que la frecuencia con la que ha aparecido es lo suficientemente elevada como para que sea considerado fondo.

2.2.- sino, se decidirá que pertenece al primer plano.


En cuanto a la actualización del modelo, se tendrán en cuenta las siguientes ecuaciones:

1- Actualización de la media y la varianza, que afecta sólo a la distribución Gaussiana que haya encajado




2- Actualización de los pesos , que afectará a todas las distribuciones que conforman el modelo

Siguiente método: Mixture of Gaussians ( I )

Este método supone una evolución notable del método anterior (Running Gaussian Average), ya que en lugar de utilizar una Gaussiana por canal, como hacía el anterior, en este método utilizamos hasta K Gaussianas por canal, para estimar el modelo probabilístico de cada pixel del background. Fue propuesto por Stauffer & Grimson en la publicación titulada Adaptive background mixture models for real-time tracking .

Aparece con la intención de mejorar y conseguir buenos resultados en condiciones de :

- Fondos Multimodales

- Escenas que contienen gran cantidad de pequeños objetos con movimientos lentos (por ejemplo banderas, hojas de los árboles), que suponen variaciones periodicas del fondo.

- Objetos rápidos en fame rates lentos.

- Escenas en las que haya cambios en las condiciones de iluminación.


Si tomamos con que cada pixel modela una superficie estática, con unas condiciones constantes de luz, una Gaussiana sería suficiente para modelar el modelo contra el ruido. Si solamente las condiciones de luz cambiaran en el tiempo, una sola Gaussiana adaptativa sería suficiente, como en el método anterior. Estaríamos hablando de entornos de interior (indoor).

En la práctica, aparecerán varias superficies o texturas en la misma región del background, bajo condiciones variables de iluminación. Será necesario múltiples Gaussianas adaptativas para afrontar esta situación.

Definimos el “pixel process” de un pixel X, como su histórico de valores desde el frame 1 al frame t. Lo representaríamos como:



En las siguientes dos figuras se representan dos “pixel processes” en una diagrama de los valores Red y Green del espacio de color:








En la primera se muestra la distribución multimodal valores de un pixel durante el parpadeo de un monitor, y en la segunda se muestra la distribución bimodal de los valores de un pixel durante los reflejos de la superficie del agua. En estos ejemplo queda patente la necesidad, por un lado de un sistema adaptativo con umbrales automáticos, y la necesidad de una representación multimodal.

martes, 22 de junio de 2010

Extracción de objetos de primer plano y actualización

1 - Extracción de objetos de Foreground:

Una vez que finaliza el periodo de entrenamiento, es decir que t>N, siendo N el número de frames de entrenamiento que hemos elegido, para cada uno de los píxeles de la imagen:

- Hayamos la distancia euclídea de cada pixel respecto a la media de la Gaussiana de referencia, mediante la siguiente formula:



Como podemos observar, habría que calcular la distancia de cada uno de los canales por separado.


- Comparamos la distancia calculada con el umbral. En este caso, el umbral consta de la varianza de la gaussiana en ese pixel multiplicada por el factor k.




La utilidad de k es aumentar el area de aceptación de un pixel de fondo. Un valor correcto suele variar entre 2 y 3, dependiendo del contexto.

Esta asociado al campo Umbral del interfaz, y se ha modificado para que acepte valores decimales.

Si la fórmula anterior se cumpliera, significaría que ese pixel ha variado lo suficiente como para considerarlo como pixel de Foreground, sino se consideraría como pixel de fondo, y se utilizaría para actualizar los parámetros de la Gaussiana.

2 - Actualización de valores de la Gaussiana.

Por cada pixel considerado como de fondo, habría que actualizar los valores de la Gaussiana asociada teniendo en cuenta las ecuaciones:


Se tiene en cuenta la casuística propuesta por D.Koller de solo actualizar los parámetros de las Gaussianas de los pixeles detectados como pertenecientes al Background.
Adjunto a continuación una muestra del funcionamiento del método implementado:

Como se puede observar existen falsas detecciones debidas al ruido del video, generado por la compresión. Sería planteable aplicar técnicas de post-procesado de imagenes, tanto para eliminar el ruido, como para eliminación de sombras.


lunes, 21 de junio de 2010

De vuelta a las estadística y las matemáticas ...

Como primer paso para implementar este método, hay que tratar la fase de Inicialización de los parámetros de la función de probabilidad, en este caso, la media y la varianza.

En primer lugar, señalar que al tomar como referencia que vamos a trabajar con frames representados mediate el espacio de color RGB, consideramos que cada canal es estadísticamente independiente, por lo tanto habra que estimar, para cada pixel, una pdf por separado para cada uno de los canales. Una vez estimada cada Gaussiana marginal, se obtendrá la pdf del pixel como producto de éstas. Esto se traducirá en que a cada pixel, habrá que asociarle una estructura de datos que contemple una media y una varianza por cada canal RGB:




El método requiere un periodo de inicialización, en el cual no se realizarán extracciones de objetos de primer plano, sino que se usará para inicializar los parámetros (las distribuciones Gaussianas que modelarán el fondo).

La inicialización es una de las ambigüedades que presenta el algoritmo. En muchos casos se limita a tomar como media el valor del pixel del primer frame. Esto podría resultar problemático, si el primer frame presentara elementos que no corresponden al fondo.

En nuestro caso, vamos a realizar el proceso de una forma adecuada, calculando los valores media y varianza a partir de los frames de entrenamiento.

En el caso de la media, la fórmula esta clara:



La varianza, mide la dispersión o desviación respecto de la media y es igual a la suma de los cuadrados de las desviaciones individuales, dividida por el número de observaciones:



Esto supone un problema, ya que habría que realizar una primera pasada por los frames de entrenamiento para estimar la media de las Gaussianas, y una segunda pasada para estimar las varianzas, ya que utilizan el valor de la media calculada anteriormente.

Esto presenta dos posibilidades:

1- Almacenar en una estructura en memoria (podríamos usar una cola como en el método anterior) los frames del periodo de entrenamiento, para poder hacer este segundo barrido. Esto sería poco eficiente.

2- Encontrar una manera para calcular todos los parámetros en un solo barrido.


Centrándome en la segunda solución, y después de intentar despejar las variables de la fórmula de la varianza para hacerlo en una iteración ( recordando que el cuadrado de la diferencia no es lo mismo que la diferencia de los cuadrados ;) ), en unos apuntes de estadística di con la fórmula de la varianza valida para estos propositos:



Asi pues haremos iterativamente, el sumatorio de los cuadrados de valores de cada pixel de los frames de entrenamiento, para finalmente dividirlo entre el numero de frames y restarle el cuadrado de la media.

Como muestra del resultado, adjunto un par de videos, donde se ha adaptado el interfaz para, dado un archivo de video, muestren en el primer caso , la imagen creada como imagen de media, y en el segundo caso la imagen con los valores de las varianzas. La imagen se mostrará una vez alcanzado el numero de frames de entrenamiento, en el ejemplo, el frame 60.




domingo, 20 de junio de 2010

Running Gaussian Average

En esta técnica se propone modelar el fondo de cada píxel mediante una función de densidad de probabilidad (pdf) conocida: la función Gaussiana. Esta función se determina mediante los parámetros media y varianza, como se observa en la siguiente imagen:





Habría, pues, que calcular estos parametros a partir de las muestras del periodo de entrenamiento. Tendriamos entonces una pdf estimada para cada uno de los pixeles del frame, que representa una Gaussiana asociada a cada uno.

Para decidir si un pixel corresponde o no a el modelo estimado, para cada frame en un tiempo t, el valor del pixel X se puede clasificar como pixel de primer plano si:



El método utilizado para realizar la actualización de los valores de la Gaussiana, seguiría las siguientes ecuaciones, que habría que aplicar por cada frame de entrada de la secuencia:




El nuevo parámetro que aparece en estas ecuaciones, se denomina parámetro de absorción, y determina la velocidad de actualización del modelo con cada nuevo frame. Esto permitiría compensar los cambios de luz o incluso el movimiento de objetos de fondo. Por ejemplo, si se modificará un libro de lugar, esto supondría un cambio en la textura del background, tanto en el lugar donde se encontrara el libro, como en su nuevo emplazamiento. Este cambio sería compensado recursivamente en pocos segundos. El valor de este parametro se escogera para conseguir un equilibrio entre rápida actualización y estabilidad.

Cabe la posibilidad, para mejorar el método, de solo actualizar el modelo, en caso de que se haya decidido que el pixel pertenece al background. Este apunte fue sugerido en un estudio publicado por D.Koller.


Este método es destacable por sus bajos requerimientos de memoria, y por su velocidad de procesado, pero sería aplicable unicamente a fondos casi estáticos, en los que el ruido introducido fuera el perteneciente al modelo de la cámara.


Esté método fue propuesto en un estudio realizado por C. Wren sobre un sistema de tracking de personas, denominado Pfinder.

Propuesta de siguientes métodos de estudio

Como consecución al método anterior, me centrare en analizar dos métodos muy utilizados en este sector. Podriamos considerarlos como métodos Recursivos, ya que, en referencia al uso de la memoría, éstos no requieren mantener un buffer en memoria para la estimación del fondo. Diriamos, por tanto que:

- Métodos recursivos: No requieren de un buffer de frames para la estimación, unicamente, actualizan recursivamente un unico modelo de background por cada frame entrante.

- Métodos no-recursivos: Utilizan un buffer para almacenar los N frames anteriores, y estimar el modelo de fondo en función de la variación temporal de cada pixel dentro de los frames de ese buffer.


Como digo, me centraré en dos famosos métodos recursivos, que se basan en crear un modelo estadístico del fondo, estimando una función de densidad de probabilidad (probability density function) para detectar los objetos de primer plano.

En primer lugar se analizara la técnica conocida como Running Gaussian Average, y después la famosa Mixture of Gaussians.

Error en el método de la media

Haciendo pruebas comparativas con diferentes videos, entre el metodo simple y el método de la media, me di cuenta que no observaba apenas diferencias. Repasando las fórmulas, y el código fuente me di cuenta de que había un error.

La idea que se plantea en el método de la media (Average), como mejora del método simple, consiste en una continua renovación del modelo de background, como la media aritmética de los N anteriores frames al frame actual.

En mi caso, estaba confundiendo el planteamiento, y me había limitado a generar la media de los N primeros frames (llamaremos a N, frames de entrenamiento), y a partir de ahi no actualizar el modelo de fondo.

A partir de este caso, había que plantearse una estructura de datos para almacenar el memoria en cada instante t, los N frames anteriores, y en cada iteración regenerar el modelo de fondo, calculando el average background a partir de los frames almacenados el memoria.

Volviendo a retomar manuales y referencias online de C++ , para refrescar un poco mi memoria de hace años, me plantee la posibilidad de implementar una estructura Cola, ya que el comportamiento del buffer de frames debía seguir una estructura FIFO.

Encontré que C++ provee de una libreria de plantillas (Standard Template Library), donde se proporcionan estructuras de datos genéricas, entre ellas una llamada QUEUE , que implementa una cola.

Después de hacer pruebas me percaté de que no me era de utilidad, ya que necesitaba tener acceso en cada instante, a todos los frames almacenados en la cola, y esta estructura solo permite acciones push() y pop(), pero no acceso aleatorio a la estructura.

La solución ha consistido en utilizar la estructura DEQUE (Double ended queue), que consiste en una cola de doble final, que además de las operaciones típicas de una cola, permite el acceso aleatorio mediante la instruccion at().

En el resultado práctico, se puede observar que, al ser el modelo de fondo actualizado en cada iteración (no es constante como en el caso anterior), las falsas detecciones disminuyen , pero se puede observar como los requerimientos de memoria aumentan, y afectan a la velocidad de proceso.

Para visualizar los videos de muestra aconsejo su reproducción en pantalla completa, para apreciar los detalles.

jueves, 17 de junio de 2010

Organización del código fuente

Se ha realizado una reorganización y recodificación de gran parte del código siguiente el paradigma de orientación a objetos, generando los correspondiente archivos cabecera .h y .cpp.

He separado la parte correspondiente a la contrucción y control de eventos del interfaz, aislándola en una clase denominada interfaz. Se ha creado otra clase para el control de los flujos de video, y una clase para cada una de las técnicas implementadas de sustracción de fondo (simple y media).

La colección de clases queda como se muestra a continuación:




En el método de ejecución principal se ha planteado de una forma estructurada que sigue el siguiente pseudocódigo:


Reestructuración del interfaz

Después de mucho pelearme con los Sizers, e investigar las posibilidades de adicción de nuevos componentes, y su correcto anidamiento dentro de la estructura, el resultado de la nueva interfaz cuenta con las siguientes características:




- Adicción de un nuevo area de video paralela a la anterior, donde se representará el video resultado del procesado de la técnica de sustracción elegida. Tanto este area como la anterior se adaptarán al tamaño del video seleccionado.

- Adicción de una GroupBox donde se enumerarán en forma de RadioButtons, una serie de métodos a aplicar. Actualmente solo hay dos. Se han añadido 4 más para futuras implementaciones.

- Adicción de un area donde aparecen las propiedades configurables de la técnica elegida en el GropBox anterior. Este área se comportará de forma dinámica, mostrando y ocultando las opciones apropiadas según el algoritmo seleccionado en los RadioButton.

- Todos los componentes del interfaz se autoorganizarán, en función del tamaño que adopten las áreas de video.


Por otro lado también se ha adaptado el funcionamiento de los algoritmos implementados, para que el resultado se muestre en el interfaz creado, y dejar de usar las ventanas de prueba de OpenCV.

El resultado es el siguiente:

Siguientes pasos en la linea de trabajo

Considero un buen momento este de pararse a plantearse por donde seguir para realizar un trabajo ordenado y con sentido. Se me ocurren 3 puntos interesantes y necesarios a encarar en este punto:

1- Teniendo en cuenta el trabajo que supusó la realización de la GUI a partir de las librerías multiplataforma WxWidgets y su costosa integración con OpenCV, sería el momento de reestructurar el aspecto del interfaz con idea de que englobe,tanto las funcionalidades que se están desarrollando, como las futuras implementaciones.

2- Debido a que la cantidad de código ya es importante, veo necesario una organización/estructuración del mismo, ya que ahora mismo toda la implementación de las operaciones relacionadas con las imagenes y los videos están en la misma función, que corresponde a una función de control del interfaz. Habría que separar la parte de control/contrucción del interfaz, de la parte de los algoritmos relacionados con la detección de movimiento.

3- Proponer los siguientes métodos de detección de movimiento, que resulten interesantes para este estudio.

Aproximación mejorada : Calculo de la Media

Como primera mejora se propone el cálculo del modelo de fondo como la media de los últimos N frames.


En este caso se hizo un amplio estudio de las operaciones que ofrece OpenCV sobre las imágenes (estructuras de datos, operaciones, calculo y metodos de acceso a matrices, ...), para intentar aplicarlas a la implementación de este algoritmo. Entre las más interesantes, mencionar:

- cvCreateImage , para crear las imagenes intermedias para realizar los cálculos, la imagen de fondo calculada como la media de las n imágenes, la imagen diferencia (foreground), etc ... Resaltar que esta función nos permite indicar el tamaño de la imagen, la profundidad del pixel y el numero de canales.

- Operaciones sobre imágenes interesantes como cvCvtScale para transfomaciones de tipos de datos en imágenes, cvAcc para acumular imágenes, cvCopy para hacer copias, cvSplit para separar los canales, cvInRangeS para comprobar si los valores de los pixeles están entre dos limites indicados, operaciones lógicas como cvOR ...

Existen un gran número de opciones disponibles que abarcan un gran campo en las operaciones sobre imágenes, estructuras para representación y manejo de matrices. En la investigación de esta parte de la librería se invirtió bastante tiempo y el resultado es el siguiente:




Recalcar que en este caso, además de la diferencia con el background, se realiza la umbralización que no se mostro en el video anterior (a los valores de background se les asigna un valor de 0 y a los del foreground de 255).

Con respecto al algoritmo, se siguen apreciando las mismas ventajas que el anterior:

- rapidez y relativa facilidad en el cálculo

y como desventajas

- dependiente de la rapidez del objeto y del frame rate
- tiene un uso alto de memoria del sistema, ya que es necesario almacenar los n frames anteriores para calcular la media.

Implementando una técnica simple de Backgroung Subtraction

Vamos a intentar una implementacion simple de esta técnica. Para ello tomaremos como modelo de Background el primer frame de la secuencia de video. La idea es ir generando imágenes binarias en las que los objetos del primer plano toman el valor 1 y se diferencian del fondo que toma valor 0.
La imagen de fondo If se comparará pixel a pixel con los frames consecutivos Ii, obteniendo una nueva imagen que representará el foreground con los siguientes valores en sus pixeles:


Teniendo en cuenta que la ecuación anterior, con condiciones reales no sería aplicable debido al ruido que aparece en las imágenes del video, se introduce el concepto del umbral, que discernirá entre fondo y primer plano:

El pseudocódigo del algoritmo quedaría entonces como :



En esta primera aproximación tendremos en cuenta dos cuestiones:

1- Conversión de los frames a escala de grises.

Para hacer está implementación, lo que se suele hacer es pasar la representación en RGB de los pixeles de los frames, a una representación en escala de grises. Un pixel con una representación RGB, contiene información sobre las 3 componentes de color: rojo , verde y azul. La idea es pasar esta información a escala de grises, donde por cada pixel solo almacenamos el valor del nivel de intensidad, que va de 0 a 255, asi la información a procesar sería menos. La fórmula para la transformación sería, para cada pixel :

2- Presentación de los resultados:

La librería OpenCV contiene una parte relacionada con el uso de GUI's (highgui) que vamos a usar para estas primeras pruebas. Como comenté en posta anteriores, básicamente te la la opción de crear una ventana, mediante la función cvNamedWindow, donde podrás mostrar una imagen usando la función cvShowImage .Estas funcionalidades son muy útiles para labores de investigación como la que nos ocupa, para así no preocuparte por la parte del interfaz. Más adelante, para complicarnos un poco más la vida, trataremos de integrar todo esto en la interfaz que generamos con WxWidgets.

En este caso mostraremos en nuestro interfaz el video original, y en las ventanas generadas con OpenCV, la imagen en escala de grises y la diferencia con el modelo de fondo.




Evidentemente la técnica anterior, al ser la más simple, el calculo computacional es más rápido, pero a la vez tiene un gran número de desventajas, como por ejemplo que depende enormemente de la elección del umbral, ya que con un umbral alto se pierde información y con uno bajo se introduce mucho ruido. También afecta la velocidad de los objetos en movimiento, ya que con objetos muy rápidos con respecto al frame rate, no funcionaría correctamente.

A continuación adjunto una comparativa donde podemos observar como afecta la elección del umbral en la detección de objetos en movimiento:

Imagen original



Umbral = 25



Umbral = 100




Background subtraction

La idea más general de este método consiste en construir un modelo para representar el fondo (background). Los objetos del primer plano (foreground), serán detectados calculando la diferencia entre el frame actual y el modelo del background. Lo normal es aplicar una máscara para los objetos de primer plano, clasificando el pixel con una diferencia absoluta, teniendo en cuenta un determinado umbral, que nos indica si el pixel pertenece al foregroung o al background.
















1- Estimar el background
2- Restar el fondo estimado al frame actual
3- Aplicar un umbral (Threshold) a la diferencia absoluta para obtener el foreground.
















El problema principal viene de la forma más eficiente de modelar el background y elegir un umbral que se comporte correctamente.

Por otro lado, hay que tener en cuenta que el fondo puede sufrir variaciones, por cuestiones como:

- Cambios de iluminacion en la imagen (nubes en el exterior, apagado de luces,...).

- Movimientos pequeños y frecuentes, como por ejemplo el movimiento de las hojas de los arboles.

- Capacidad de añadir o eliminar objetos al fondo (coche aparcado que abandona un parking)

Centrándonos en la detección de movimiento. Reflexión personal.

Para conseguir implementar un sistema de seguimiento de objetos, existen un extenso conjunto de técnicas. La diferencia entre cada una de ellas se centra principalmente en varias cuestiones básicas que entran en juego cuando hablamos de seguimiento de objetos, como son, la representación del objeto que vamos a seguir (puntos, formas geométricas,siluetas, ...), en que caracteristicas de la imagen vamos a centrarnos para llegar a este fin (brillo, color, textura, vértices, ...), como modelar el movimiento, etc ...

Se han propuesto muchos metodos, en función del contexto o entorno de tracking y el usuario al que van dirigidos. La mayoría de los métodos de tracking requieren de una fase primordial que consiste en la detección de objetos o detección de movimiento.Una vez localizado la región del objeto a seguir, sería labor del tracker representar las correspondencias de ese objeto de un frame al siguiente para generar el seguimiento.

Del mismo modo que comentaba antes, en el campo de los métodos de detección de movimiento, también existen multitud de propuestas como para poder hacer un estudio de cada unas de ellas. De las más usuales podriamos citar la Sustracción de fondo (Background Substraction), imagen diferencia, diferencias acumuladas, ajuste de bloques, cambios en el flujo optico, segmentación, detección de puntos ...

Con ánimo de centrar el objeto de estudio de este proyecto en algún area definida, he decidido poner el foco en la técnica de Background Substraction, ya que el hecho de ser capaz de separar objetos de interés de un determinado fondo en una secuencia de video supone un paso crítico en muchas aplicaciones de visión y la Background Substraction (BS) es un técnica usada frecuentemente para conseguirlo. La popularidad de la BS se debe principalmente a su eficiencia computacional, y se usan en aplicaciones de visión que necesitan resultados en tiempo real, como por ejemplo sistemas de videovigilancia, aplicaciones de interacción persona-ordenador o sistemas de monitorización de tráfico.

Existen una amplica variedad de algoritmos para implementar la BS , asi como técnicas de post-procesado para mejorar su rendimiento. La idea sería implementar los algotimos más usados dentro de este campo , aplicarlos a videos que contengan movimiento para ver como se comportan y poder sacar conclusiones de cada una de las técnicas. Evidentemente, la opción recomendable sería ser capaz de integrar todo esto en el interfaz que hasta ahora hemos generado, para hacer más eficiente y agradable el proceso de comparación de cada una de las técnicas.