Motion

Segmentation and Tracking

with a

detection platform for vehicle and people

proyecto
Documentación: Documentación

¿Qué es la Segmentación de Movimiento?

La detección de movimiento es el proceso de detectar un cambio en la posición de un objeto con respecto a su entorno, o los cambios en el entorno en relación con un objeto. La detección de movimiento se puede lograr por métodos tanto mecánicos y electrónicos. Cuando la detección de movimiento se lleva a cabo por organismos naturales, se llama la percepción del movimiento.

Este proyecto presenta un enfoque para una segmentación de movimiento basado en regiones en tiempo real, utilizando un umbral adaptativo en una escena, con el foco en un sistema de videovigilancia. Para indicar las regiones de máscara de movimiento en una escena, en lugar de determinar el valor de umbral manualmente, utilizamos un método de umbral adaptativo para elegir automáticamente el valor de umbral.



Análisis del problema

Al analizar el problema, éste sugiere crear un sistema automatizado en tiempo real en que se pueda obtener una secuencia de imagenes para luego procesarla con una aplicacion mediante la programación orientada objeto; y por que Orientada objeto, dado a su proximidad a las entidades del mundo real que surgen del modelado, mejora enormemente la captura y validación de requisitos del problema mismo.

En qué consiste el método de umbral adaptativo?

Para segmentar la imagen, Supongamos que tenemos 2 imágenes, las imágenes son una subsecuencia lineal con cierto retraso t entre ellos. Si queremos comparar cada pixel de las 2 imágenes y nos damos cuenta de que todos son iguales, podemos concluir las 2 imágenes son idénticas. Pero si no lo hacen, podríamos decir que hay algo sucedió durante el tiempo de retardo t. Alguien podría colocar un objeto delante de la cámara, por lo que sería automatico el reconocimiento de aquel objeto. Y sí, esta es la idea que vamos a utilizar para la detección de movimiento.

El método que he descrito, es también llamado "diferencial de imágenes". Es el resultado de restar 2 imágenes.

f_{dif}(x,y) = f_{1}(x,y) - f_{2}(x,y)

En nuestro proyecto vamos a utilizar una secuencia de imágenes, por lo que iremos tomando 2 imágenes consecutivas y las procesaremos, las llamaremos la primera imagen anterior y la segunda, del frame actual. Primero restaremos las imágenes actual menos la anterior. Después de esto se obtiene una imagen binaria.

\delta I_{1} = I_{t+1} - I_{t}

Después se le aplicará un umbral, en el cual será como este, los cuales los puntos blancos indican los cambios. (Se puede jugar con la función umbral, para obtener mejores resultados).

    -         =    

A continuación vamos a colocar una ventana en el centro del software, con el resultado final (el resultado de umbral). Y vamos a ver los cambios, esto significa que vamos a buscar los píxeles con valores mayores que cero (esto indicará movimiento). Cuando se detecta movimiento (un píxel con un valor> 0), la búsqueda se detendrá y etiquetar la imagen con un cuadrado amarillo, indicará un objeto en movimiento.



Un caso de uso

Se considera a partir del programa ya compilado y funcionando correctamente.



1. Usuario inicia el programa.
2. Programa se ejecuta, mostrando su interfaz gráfica.
3. Usuario elige un video.
4. Programa recibe la fuente de video.
5. Programa muestra 3 pantallas: el video original, el video final (con los objetos identificados) y el resultado del threshold).
6. Usuario termina el programa.
7. Programa termina.

Main Code (procesos.cpp)

                    
                        1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101

#include "procesos.h"
// Slots para los procesos:
void MainWindow::processing()
{
    QByteArray byteArray = ruta.toUtf8();
    const char* cString = byteArray.constData();
    int threshold = 42.0;
    int dilate1 = 2;
    int erode1 = 4;
    int dilate2 = 2;
    int maxValue = 255.0;
    int thresholdType = CV_THRESH_BINARY;
    int key;


    IplImage *frame = NULL;
    IplImage *bg = NULL;
    IplImage *diff = NULL;
    IplImage *fg = NULL;
    IplImage *fg_aux = NULL;
    IplImage *fg_out = NULL;
    IplImage *final = NULL;

//First we get the video
CvCapture* capture;     //CvCapture is the structure used by openCv to handle with video

capture  = cvCreateFileCapture(cString);
    //capture = cvCaptureFromCAM(0);

while(cvGrabFrame(capture)) {

    frame = cvRetrieveFrame(capture);

    if(frame) {
            if(bg == NULL) { //Initial background
                bg = cvCloneImage(frame);
                diff = cvCloneImage(frame);
                fg_out = cvCloneImage(frame);
                fg = cvCreateImage(cvSize(frame->width,frame->height),frame->depth,1);
                final = cvCreateImage( cvSize(frame->width,frame->height), IPL_DEPTH_8U, 1 );
            }

            //Segmentation
            img=cvCloneImage(frame);
            emit imagenFinal();
            fg_aux = cvCreateImage(cvSize(frame->width,frame->height),frame->depth, frame->nChannels);
            cvAbsDiff(frame, bg, diff);
            cvThreshold(diff, fg_aux, threshold, maxValue, thresholdType);
            cvCvtColor(fg_aux, final, CV_RGB2GRAY);
            img2=cvCloneImage(final);
            emit segmentation(); 
            cvDilate(final, final, NULL, dilate1);
            cvErode(final, final, NULL,erode1);
            cvDilate(final, final, NULL, dilate2);
            bg=cvCloneImage(frame);
            int num=100;
            CvRect rectangles[100];
            temp2=temp1;
            cvconnectedComponents(final,1,14,&num,rectangles,NULL,0);
            
            temp1 = num;
            temp3 = temp1-temp2;
            if(temp3>=0) total += temp3;
            text = QString::number(num);
            text3 = QString::number(total);
            emit text2();
            emit texto();

            for (int i=0; icvRectangle(frame,
                    cvPoint(rectangles[i].x,rectangles[i].y),
                    cvPoint((rectangles[i].x+rectangles[i].width),(rectangles[i].y+rectangles[i].height)),
                    cvScalar(0,255,255),
                    1.5
                    );
            }



frame_original=cvCloneImage(frame);
emit frameOriginal();

}
delay(0.5);
key = cvWaitKey (0);
cvReleaseImage(&fg_aux);
}
cvReleaseImage(&fg);
    cvReleaseImage(&bg);
    cvReleaseCapture(&capture);
    cvReleaseImage(&frame);
    cvReleaseImage(&fg_out);
}


void MainWindow::delay( float seconds)
{
    clock_t temp;
    temp = clock () + seconds * CLOCKS_PER_SEC ;
    while (clock() < temp) {}
}

                

Dependencias



Demostración

      1. video.flv
    1. cv_yuv_codebook.cpp
    2. cv_yuv_codebook.h
    3. iplimageToQimage.cpp
    4. main.cpp
    5. mainwindow.cpp
    6. mainwindow.h
    7. mainwindow.ui
    8. procesos.cpp
    9. procesos.h
    10. proyecto.pro
    11. Makefile
    12. README

Installation

OpenCV:
$ sudo sh ./InstallOpenCV.sh
Download InstallOpenCV.sh

QtCreator:
$ sudo apt-get install qtcreator

Run:
$cd Project
$./proyecto