单高斯背景建模opencv仿真
2014-09-13 20:03
316 查看
高斯分布与背景建模的关系:图像中每一个像素点的颜色值作为一个随机过程X,并假设该点的像素值出现的概率服从高斯分布。令I(x,y,t)表示像素点(x,y,t)在t时刻的像素值,则有:
其中
和
分别为t时刻该像素高斯分布的期望值和标准差。
算法流程:
1.用第一帧图像数据初始化背景模型,其中std_init通常设置为20。
2.检测前景与背景像素。
背景像素检测公式:
前景像素检测公式:
3.对
、
、
背景值进行更新,更新公式如下:
4.返回到2直至停止。
从左到右,图片一次为前景,背景,原图。
备注:opencv使用的是1.0
其中
和
分别为t时刻该像素高斯分布的期望值和标准差。
算法流程:
1.用第一帧图像数据初始化背景模型,其中std_init通常设置为20。
2.检测前景与背景像素。
背景像素检测公式:
前景像素检测公式:
3.对
、
、
背景值进行更新,更新公式如下:
4.返回到2直至停止。
#include <stdlib.h> #include <stdio.h> #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); cvMoveWindow("origin", 1100, 400); cvMoveWindow("background", 600, 400); cvMoveWindow("foreground", 100, 400); double alpha = 0.5;//背景建模alpha值 double std_int = 20;//初始化标准差 double var_int = std_int*std_int;//初始化方差 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_d=NULL;//前景图像 IplImage *frame_var=NULL;//方差图像 IplImage *frame_std=NULL;//标准差 CvScalar pixel={0};//像素原始值 CvScalar pixel_u={0};//像素期望值 CvScalar pixel_d={0};//像素前景 CvScalar pixel_var={0};//像素方差 CvScalar pixel_std={0};//像素标准差 //初始化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 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_d.val[0]=0; pixel_d.val[1]=0; pixel_d.val[2]=0; pixel_std.val[0]=std_int; pixel_std.val[1]=std_int; pixel_std.val[2]=std_int; pixel_var.val[0]=var_int; pixel_var.val[1]=var_int; pixel_var.val[2]=var_int; cvSet2D(frame_u,y,x,pixel_u); cvSet2D(frame_d,y,x,pixel_d); 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_d=cvGet2D(frame_d,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]+ alpha*(pixel.val[0]-pixel_u.val[0])*(pixel.val[0]-pixel_u.val[0]); pixel_var.val[1]=(1-alpha)*pixel_var.val[1]+ alpha*(pixel.val[1]-pixel_u.val[1])*(pixel.val[1]-pixel_u.val[1]); pixel_var.val[2]=(1-alpha)*pixel_var.val[2]+ alpha*(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); } else { pixel_d.val[0]=pixel.val[0]-pixel_u.val[0]; pixel_d.val[1]=pixel.val[1]-pixel_u.val[1]; pixel_d.val[2]=pixel.val[2]-pixel_u.val[2]; cvSet2D(frame_d,y,x,pixel_d); } } } //显示结果 frame_u->origin=1; frame_u->origin=1; 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; }
从左到右,图片一次为前景,背景,原图。
备注:opencv使用的是1.0
相关文章推荐
- 背景建模-均值法(Matlab)高斯背景建模(opencv)
- opencv高斯背景建模
- 【OpenCV】高斯混合背景建模
- opencv实践程序4——canny实现摄像头的边缘检测,高斯背景建模
- 【OpenCV】高斯混合背景建模
- OpenCV混合高斯背景建模
- 高斯背景建模程序分析(OpenCV)--转自 yimi (网易博客) .
- Qt之OpenCV高斯背景建模
- 运动目标的背景建模-混合高斯背景建模和KNN模型建模的OpenCV代码实现
- 单高斯背景建模MATLAB仿真
- 混合高斯背景建模——opencv
- 混合高斯背景建模的示例程序(VC6.0 + OpenCv 1.0)
- 【OpenCV】高斯混合背景建模
- OpenCV2.2 和 2.4.4 的 cvSetCaptureProperty 和 CvGaussBGModel (高斯背景建模)版本间差异
- opencv 高斯背景建模
- 高斯混合模型背景建模(BackgroundSubtractorMOG2)在opencv3.0与opencv2.4中的使用方法区别
- 目标检测——CodeBook背景建模(原理+Opencv实现代码)
- opencv背景去除建模(BSM)
- 运动目标检测_单高斯背景建模
- 混合高斯背景建模(opecv)