these principles and algorithmic flow, transferred from other people's blog, the code is to achieve their own.
the relationship between Gaussian distribution and background modeling: The color value of each pixel in the image as a random process X, and assumes that the probability of the pixel value of the point appears to obey the Gaussian distribution. So I (x,y,t) represents the pixel value of the pixel point (x,y,t) at t time, then there are:
and the expected and standard deviation of the Gaussian distribution of the pixel at T-moment respectively.
Algorithm Flow:
1. Initialize the background model with the first frame image data, where std_init is typically set to 20.
2. Detect foreground and background pixels.
Background Pixel detection formula:
foreground pixel detection formula:
3. Update the background value, and update the formula as follows:
4. Return to 2 until stopped.
The following is the detailed implementation code:
Gaussian Background Modeling/*
#include #include <cv.h>
#include <math.h>
#include <cxcore.h>
int main (int argc, char* argv[])
{
New Window
Cvnamedwindow ("origin", cv_window_autosize);
Cvnamedwindow ("Background", cv_window_autosize);
Cvnamedwindow ("foreground", cv_window_autosize);
Double alpha = 0.05; Background Modeling alpha Value
Double std_init = 20; Initial standard deviation
Double var_init = std_init * STD_INIT; Initial variance
Double LAMDA = 2.5 * 1.2; Background update parameters
Video files
Cvcapture *capture = NULL;
Read in from a file
Capture = Cvcreatefilecapture ("e:\\ new Folder \\cs. AVI ");
Capture = Cvcreatefilecapture ("d:\\videodata\\sdc11945. AVI ");
Iplimage *frame = NULL; Original image
Iplimage *frame_u = NULL; Desired image
Iplimage *frame_d = NULL; Foreground image
Iplimage *frame_var = NULL; Variance image
Iplimage *frame_std = NULL; Standard deviation
Initialize Frame_u, frame_d, Frame_var, FRAME_STD
frame = Cvqueryframe (capture);
Frame_u = Cvcreateimage (Cvsize (Frame->width, Frame->height), ipl_depth_8u, 3);
Frame_d = Cvcreateimage (Cvsize (Frame->width, Frame->height), ipl_depth_8u, 3);
Frame_var = Cvcreateimage (Cvsize (Frame->width, Frame->height), ipl_depth_8u, 3);
FRAME_STD = Cvcreateimage (Cvsize (Frame->width, Frame->height), ipl_depth_8u, 3);
for (int j = 0; J < frame->height; ++j)
{
for (int i= 0; i< frame->width; ++i)
{
Frame_u->imagedata[j *frame->widthstep + i * 3 + 0] = (unsigned char) frame->imagedata[j *frame->widthstep + I * 3 + 0];
Frame_u->imagedata[j *frame->widthstep + i * 3 + 1] = (unsigned char) frame->imagedata[j *frame->widthstep + I * 3 + 1];
Frame_u->imagedata[j *frame->widthstep + i * 3 + 2] = (unsigned char) frame->imagedata[j *frame->widthstep + I * 3 + 2];
Frame_d->imagedata[j *frame->widthstep + i * 3 + 0] = 0;
Frame_d->imagedata[j *frame->widthstep + i * 3 + 1] = 0;
Frame_d->imagedata[j *frame->widthstep + i * 3 + 2] = 0;
Frame_var->imagedata[j *frame->widthstep + i * 3 + 0] = Var_init;
Frame_var->imagedata[j *frame->widthstep + i * 3 + 1] = Var_init;
Frame_var->imagedata[j *frame->widthstep + i * 3 + 2] = Var_init;
Frame_std->imagedata[j *frame->widthstep + i * 3 + 0] = Std_init;
Frame_std->imagedata[j *frame->widthstep + i * 3 + 1] = Std_init;
Frame_std->imagedata[j *frame->widthstep + i * 3 + 2] = Std_init;
}
}
while (Cvwaitkey (33)! = 27)//press ESC to exit, frame rate 33ms
{
frame = Cvqueryframe (capture);
End of video exit
if (!frame)
{
Break
}
Gaussian background update
for (int j= 0; j < frame->height; ++j)
{
for (int i = 0; i < frame->width; ++i)
{
//| i-u| < LAMDA*STD when considered as background, to be updated
if (ABS (unsigned char) frame->imagedata[j *frame->widthstep + i * 3 + 0]-(unsigned char) frame_u->imagedata[j *frame->widthstep + i * 3 + 0]) < LAMDA * Std_init &&
ABS ((unsigned char) frame->imagedata[j *frame->widthstep + i * 3 + 1]-(unsigned char) frame_u->imagedata[j *FR Ame->widthstep + i * 3 + 1]) < LAMDA * Std_init &&
ABS ((unsigned char) frame->imagedata[j *frame->widthstep + i * 3 + 2]-(unsigned char) frame_u->imagedata[j *fram E->widthstep + i * 3 + 2]) < LAMDA * Std_init)
{
Update expected U = (1-alpha) *u + alpha*i
Frame_u->imagedata[j *frame->widthstep + i * 3 + 0]= (1-alpha) * (unsigned char) frame_u->imagedata[j *frame-> ; Widthstep + i * 3 + 0] + Alpha * (unsigned char) frame->imagedata[j *frame->widthstep + i * 3 + 0];
Frame_u->imagedata[j *frame->widthstep + i * 3 + 1]= (1-alpha) * (unsigned char) frame_u->imagedata[j *frame-> ; Widthstep + i * 3 + 1] + Alpha * (unsigned char) frame->imagedata[j *frame->widthstep + i * 3 + 1];
Frame_u->imagedata[j *frame->widthstep + i * 3 + 2]= (1-alpha) * (unsigned char) frame_u->imagedata[j *frame-> Widthstep + i * 3 + 2]+ Alpha * (unsigned char) frame->imagedata[j *frame->widthstep + i * 3 + 2];
Update variance var = (1-alpha) *var + alpha* (i-u) ^2
Frame_var->imagedata[j *frame->widthstep + i * 3 + 0] = (1-alpha) * ((unsigned char) frame_var->imagedata[j *fram E->widthstep + i * 3 + 0]) +
alpha* ((unsigned char) frame->imagedata[j *frame->widthstep + i * 3 + 0]-(unsigned char) frame_u->imagedata[j *FR Ame->widthstep + i * 3 + 0])
* ((unsigned char) frame->imagedata[j *frame->widthstep + i * 3 + 0]-(unsigned char) frame_u->imagedata[j *frame-& Gt;widthstep + i * 3 + 0]);
Frame_var->imagedata[j *frame->widthstep + i * 3 + 1] = (1-alpha) * ((unsigned char) frame_var->imagedata[j *fram E->widthstep + i * 3 + 1]) +
alpha* ((unsigned char) frame->imagedata[j *frame->widthstep + i * 3 + 0]-(unsigned char) frame_u->imagedata[j *FR Ame->widthstep + i * 3 + 1])
* ((unsigned char) frame->imagedata[j *frame->widthstep + i * 3 + 0]-(unsigned char) frame_u->imagedata[j *frame-& Gt;widthstep + i * 3 + 1]);
Frame_var->imagedata[j *frame->widthstep + i * 3 + 2] = (1-alpha) * ((unsigned char) frame_var->imagedata[j *fram E->widthstep + i * 3 + 2]) +
alpha* ((unsigned char) frame->imagedata[j *frame->widthstep + i * 3 + 0]-(unsigned char) frame_u->imagedata[j *FR Ame->widthstep + i * 3 + 2])
* ((unsigned char) frame->imagedata[j *frame->widthstep + i * 3 + 0]-(unsigned char) frame_u->imagedata[j *frame-& Gt;widthstep + i * 3 + 2]);
Update Standard deviation
Frame_std->imagedata[j *frame->widthstep + i * 3 + 0]=sqrt (frame_var->imagedata[j *frame->widthStep + i * 3 + 0]*1.0);
Frame_std->imagedata[j *frame->widthstep + i * 3 + 1]=sqrt (frame_var->imagedata[j *frame->widthStep + i * 3 + 1]*1.0);
Frame_std->imagedata[j *frame->widthstep + i * 3 + 2]=sqrt (frame_var->imagedata[j *frame->widthStep + i * 3 + 2]*1.0);
}
Else
{
Frame_d->imagedata[j *frame->widthstep + i * 3 + 0]= (unsigned char) frame->imagedata[j *frame->widthstep + I * 3 + 0]-(unsigned char) frame_u->imagedata[j *frame->widthstep + i * 3 + 0];
Frame_d->imagedata[j *frame->widthstep + i * 3 + 1]= (unsigned char) frame->imagedata[j *frame->widthstep + I * 3 + 1]-(unsigned char) frame_u->imagedata[j *frame->widthstep + i * 3 + 1];
Frame_d->imagedata[j *frame->widthstep + i * 3 + 2]= (unsigned char) frame->imagedata[j *frame->widthstep + I * 3 + 2]-(unsigned char) frame_u->imagedata[j *frame->widthstep + i * 3 + 2];
}
}
}
Show results
Frame_u->origin = 0;
Frame_d->origin = 0;
Cvshowimage ("origin", frame);
Cvshowimage ("Background", Frame_u);
Cvshowimage ("foreground", frame_d);
}
Freeing memory
Cvreleasecapture (&capture);
Cvreleaseimage (&frame);
Cvreleaseimage (&frame_u);
Cvreleaseimage (&frame_var);
Cvreleaseimage (&FRAME_STD);
Cvdestroywindow ("origin");
Cvdestroywindow ("background");
Cvdestroywindow ("foreground");
return 0;
}
*/