单高斯背景建模opencv
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
*******************单高斯背景建模v1.0*************************
************************2010.01.22****************************/
#include
#include
#include
#include
#include
int main(int argc, char **argv)
{
//新建窗口
cvNamedWindow("origin", CV_WINDOW_AUTOSIZE);
cvNamedWindow("processing", 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;
//读取视频文件
if (argc == 1)
{
//从摄像头读入
capture = cvCreateCameraCapture(0);
}
else if (argc == 2)
{
//从文件读入
capture = cvCreateFileCapture(argv[1]);
}
else
{
//读入错误
printf("input error\n");
return -1;
}
IplImage *frame = NULL; //原始图像
IplImage *frame_u = NULL; //期望图像
IplImage *frame_var = NULL; //方差图像
IplImage *frame_std = NULL; //标准差
CvScalar pixel = {0}; //像素原始值
CvScalar pixel_u = {0}; //像素期望
CvScalar pixel_var = {0}; //像素方差
CvScalar pixel_std = {0}; //像素标准差
//初始化frame_u, frame_var, frame_std
frame = cvQueryFrame(capture);
frame_u = 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 y = 0; y < frame->height; ++y)
{
for (int x = 0; x < frame->width; ++x)
{
pixel = cvGet2D(frame, y, x);
pixel_u.val[0] = pixel.val[0];
pixel_u.val[1] = pixel.val[1];
pixel_u.val[2] = pixel.val[2];
pixel_std.val[0] = std_init;
pixel_std.val[1] = std_init;
pixel_std.val[2] = std_init;
pixel_var.val[0] = var_init;
pixel_var.val[1] = var_init;
pixel_var.val[2] = var_init;
cvSet2D(frame_u, y, x, pixel_u);
cvSet2D(frame_var, y, x, pixel_var);
cvSet2D(frame_std, y, x, pixel_std);
}
}
while (cvWaitKey(33) != 27) //按ESC键退出, 帧率33ms
{
frame = cvQueryFrame(capture);
//视频结束退出
if (!frame)
{
break;
}
//单高斯背景更新
for (int y = 0; y < frame->height; ++y)
{
for (int x = 0; x < frame->width; ++x)
{
pixel = cvGet2D(frame, y, x);
pixel_u = cvGet2D(frame_u, y, x);
pixel_std = cvGet2D
(frame_std, y, x);
pixel_var = cvGet2D(frame_var, y, x);
//|I-u| < lamda*std 时认为是背景, 进行更新
if (fabs(pixel.val[0] - pixel_u.val[0]) < lamda * pixel_std.val[0] &&
fabs(pixel.val[1] - pixel_u.val[1]) < lamda * pixel_std.val[1] &&
fabs(pixel.val[2] - pixel_u.val[2]) < lamda * pixel_std.val[2])
{
//更新期望 u = (1-alpha)*u + alpha*I
pixel_u.val[0] = (1 - alpha) * pixel_u.val[0] + alpha * pixel.val[0];
pixel_u.val[1] = (1 - alpha) * pixel_u.val[1] + alpha * pixel.val[1];
pixel_u.val[2] = (1 - alpha) * pixel_u.val[2] + alpha * pixel.val[2];
//更新方差 var = (1-alpha)*var + alpha*(I-u)^2
pixel_var.val[0] = (1 - alpha) * pixel_var.val[0] +
(pixel.val[0] - pixel_u.val[0]) * (pixel.val[0] - pixel_u.val[0]);
pixel_var.val[1] = (1 - alpha) * pixel_var.val[1] +
(pixel.val[1] - pixel_u.val[1]) * (pixel.val[1] - pixel_u.val[1]);
pixel_var.val[2] = (1 - alpha) * pixel_var.val[2] +
(pixel.val[2] - pixel_u.val[2]) * (pixel.val[2] - pixel_u.val[2]);
//更新标准差
pixel_std.val[0] = sqrt(pixel_var.val[0]);
pixel_std.val[1] = sqrt(pixel_var.val[1]);
pixel_std.val[2] = sqrt(pixel_var.val[2]);
//写入矩阵
cvSet2D(frame_u, y, x, pixel_u);
cvSet2D(frame_var, y, x, pixel_var);
cvSet2D(frame_std, y, x, pixel_std);
}
}
}
//显示结果
cvShowImage("origin", frame);
cvShowImage("processing", frame_u);
}
//释放内存
cvReleaseCapture(&capture);
cvReleaseImage(&frame);
cvReleaseImage(&frame_u);
cvReleaseImage(&frame_var);
cvReleaseImage(&frame_std);
cvDestroyWindow("origin");
cvDestroyWindow("processing");
return 0;
}