您的位置:首页 > 其它

单高斯背景建模

2015-06-10 19:48 267 查看
这些原理和算法流程,转自别人的博客,代码是自己实现的。

高斯分布与背景建模的关系:图像中每一个像素点的颜色值作为一个随机过程X,并假设该点的像素值出现的概率服从高斯分布。令I(x,y,t)表示像素点(x,y,t)在t时刻的像素值,则有:






其中



分别为t时刻该像素高斯分布的期望值和标准差。


算法流程:

1.用第一帧图像数据初始化背景模型,其中std_init通常设置为20。
















2.检测前景与背景像素。

背景像素检测公式:



前景像素检测公式:



3.对





背景值进行更新,更新公式如下:

















4.返回到2直至停止。
下面是详细的实现代码:

//单高斯背景建模

/*

#include <highgui.h>

#include <cv.h>

#include <math.h>

#include <cxcore.h>

int main(int argc, char* argv[])

{

//新建窗口

cvNamedWindow("origin", CV_WINDOW_AUTOSIZE);

cvNamedWindow("background", CV_WINDOW_AUTOSIZE);

cvNamedWindow("foreground", CV_WINDOW_AUTOSIZE);

double alpha = 0.05; //背景建模alpha值

double std_init = 20; //初始标准差

double var_init = std_init * std_init; //初始方差

double lamda = 2.5 * 1.2; //背景更新参数

//视频文件

CvCapture *capture = NULL;

//从文件读入

// capture = cvCreateFileCapture("E:\\新建文件夹\\cs.AVI");

capture = cvCreateFileCapture("D:\\VideoData\\SDC11945.AVI");

IplImage *frame = NULL; //原始图像

IplImage *frame_u = NULL; //期望图像

IplImage *frame_d = NULL; //前景图像

IplImage *frame_var = NULL; //方差图像

IplImage *frame_std = NULL; //标准差

//初始化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) //按ESC键退出, 帧率33ms

{

frame = cvQueryFrame(capture);

//视频结束退出

if (!frame)

{

break;

}

//单高斯背景更新

for (int j= 0; j < frame->height; ++j)

{

for (int i = 0; i < frame->width; ++i)

{

//|I-u| < lamda*std 时认为是背景, 进行更新

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 *frame->widthStep + i * 3 + 1]) < lamda * std_init &&

abs( (unsigned char)frame->imageData[j *frame->widthStep + i * 3 + 2] -(unsigned char) frame_u->imageData[j *frame->widthStep + i * 3 + 2])< lamda * std_init)

{

//更新期望 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];

//更新方差 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 *frame->widthStep + i * 3 + 0])+

alpha*((unsigned char) frame->imageData[j *frame->widthStep + i * 3 + 0]-(unsigned char)frame_u->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_var->imageData[j *frame->widthStep + i * 3 + 1] =(1 - alpha) *( (unsigned char)frame_var->imageData[j *frame->widthStep + i * 3 + 1])+

alpha*((unsigned char) frame->imageData[j *frame->widthStep + i * 3 + 0]-(unsigned char)frame_u->imageData[j *frame->widthStep + i * 3 + 1] )

*((unsigned char) frame->imageData[j *frame->widthStep + i * 3 + 0]-(unsigned char)frame_u->imageData[j *frame->widthStep + i * 3 + 1] );

frame_var->imageData[j *frame->widthStep + i * 3 + 2] =(1 - alpha) *( (unsigned char)frame_var->imageData[j *frame->widthStep + i * 3 + 2])+

alpha*((unsigned char) frame->imageData[j *frame->widthStep + i * 3 + 0]-(unsigned char)frame_u->imageData[j *frame->widthStep + i * 3 + 2] )

*((unsigned char) frame->imageData[j *frame->widthStep + i * 3 + 0]-(unsigned char)frame_u->imageData[j *frame->widthStep + i * 3 + 2] );

//更新标准差

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];

}

}

}

//显示结果

frame_u->origin = 0;

frame_d->origin = 0;

cvShowImage("origin", frame);

cvShowImage("background", frame_u);

cvShowImage("foreground", frame_d);

}

//释放内存

cvReleaseCapture(&capture);

cvReleaseImage(&frame);

cvReleaseImage(&frame_u);

cvReleaseImage(&frame_var);

cvReleaseImage(&frame_std);

cvDestroyWindow("origin");

cvDestroyWindow("background");

cvDestroyWindow("foreground");

return 0;

}

*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: