高斯模型Word格式.docx
《高斯模型Word格式.docx》由会员分享,可在线阅读,更多相关《高斯模型Word格式.docx(14页珍藏版)》请在冰豆网上搜索。
接下来再读取当前帧时,更新高斯模型
regioncount=icvUpdateGaussianBGModel(currframe,bg_model);
regioncount的含义我不确定,我理解是代表背景中不同颜色区域的个数,这个参数我没有用到,它只是icvUpdateGaussianBGModel函数的返回值。
3。
现在bg_model已经保存了经过高斯混合模型分类后的结果,bg_model->
background保存了背景图像,bg_model->
foreground保存了前景图像。
include<
stdio.h>
#include<
cv.h>
cxcore.h>
highgui.h>
cvaux.h>
//必须引此头文件
intmain(intargc,char**argv)
{
IplImage*pFrame=NULL;
IplImage*pFrImg=NULL;
IplImage*pBkImg=NULL;
CvCapture*pCapture=NULL;
intnFrmNum=0;
cvNamedWindow("
video"
1);
background"
1);
foreground"
cvMoveWindow("
30,0);
360,0);
690,0);
if(argc>
2)
fprintf(stderr,"
Usage:
bkgrd[video_file_name]\n"
);
return-1;
}
//打开视频文件
if(argc==2)
if(!
(pCapture=cvCaptureFromFile(argv[1])))
Cannotopenvideofile%s\n"
argv[1]);
return-2;
//打开摄像头
if(argc==1)
(pCapture=cvCaptureFromCAM(-1)))
Cannotopencamera.\n"
//初始化高斯混合模型参数
CvGaussBGModel*bg_model=NULL;
while(pFrame=cvQueryFrame(pCapture))
nFrmNum++;
if(nFrmNum==1)
pBkImg=cvCreateImage(cvSize(pFrame->
width,pFrame->
height),IPL_DEPTH_8U,3);
pFrImg=cvCreateImage(cvSize(pFrame->
height),IPL_DEPTH_8U,1);
//高斯背景建模,pFrame可以是多通道图像也可以是单通道图像
//cvCreateGaussianBGModel函数返回值为CvBGStatModel*,
//需要强制转换成CvGaussBGModel*
bg_model=(CvGaussBGModel*)cvCreateGaussianBGModel(pFrame,0);
else
//更新高斯模型
cvUpdateBGStatModel(pFrame,(CvBGStatModel*)bg_model);
//pFrImg为前景图像,只能为单通道
//pBkImg为背景图像,可以为单通道或与pFrame通道数相同
cvCopy(bg_model->
foreground,pFrImg,0);
background,pBkImg,0);
//把图像正过来
pBkImg->
origin=1;
pFrImg->
cvShowImage("
pFrame);
pBkImg);
pFrImg);
if(cvWaitKey
(2)>
=0)
break;
//释放高斯模型参数占用内存
cvReleaseBGStatModel((CvBGStatModel**)&
bg_model);
cvDestroyWindow("
cvReleaseImage(&
pFrImg);
pBkImg);
cvReleaseCapture(&
pCapture);
return0;
}
看高斯混合模型的论文的时候感觉一头雾水,主要是那些概率公式比较难懂,看了几遍论文和代码才有了一点感觉,以下是个人的对混合高斯背景模型代码的理解,后面会通过进一步理解不断对此贴修正.....
注:
本人对该代码的理解也有很多不到位的地方,希望以后会慢慢矫正。
程序中代码的实现与论文中公式有些出入,不过不影响对全局的把握和理解。
混合高斯背景模型理论的论文:
点击下载
////////////////////////cvCreateGaussianBGModel///////////////////////////////////////////
CV_IMPLCvBGStatModel*cvCreateGaussianBGModel(IplImage*first_frame,CvGaussBGStatModelParams*parameters)
{
CvGaussBGModel*bg_model=0;
CV_FUNCNAME("
cvCreateGaussianBGModel"
);
__BEGIN__;
doublevar_init;
CvGaussBGStatModelParamsparams;
inti,j,k,m,n;
//initparameters
if(parameters==NULL)
{
params.win_size
=CV_BGFG_MOG_WINDOW_SIZE;
//初始化阶段的帧数;
用户自定义模型学习率a=1/win_size;
params.bg_threshold=CV_BGFG_MOG_BACKGROUND_THRESHOLD;
params.std_threshold=CV_BGFG_MOG_STD_THRESHOLD;
params.weight_init
=CV_BGFG_MOG_WEIGHT_INIT;
params.variance_init=CV_BGFG_MOG_SIGMA_INIT*CV_BGFG_MOG_SIGMA_INIT;
//方差
params.minArea
=CV_BGFG_MOG_MINAREA;
params.n_gauss
=CV_BGFG_MOG_NGAUSSIANS;
//高斯分布函数的个数
}
else
{
params=*parameters;
//用户自定义参数
if(!
CV_IS_IMAGE(first_frame))
CV_ERROR(CV_StsBadArg,"
InvalidorNULLfirst_frameparameter"
CV_CALL(bg_model=(CvGaussBGModel*)cvAlloc(sizeof(*bg_model)));
memset(bg_model,0,sizeof(*bg_model));
bg_model->
type=CV_BG_MODEL_MOG;
//CV_BG_MODEL_MOG为高斯背景模型
release=(CvReleaseBGStatModel)icvReleaseGaussianBGModel;
update=(CvUpdateBGStatModel)icvUpdateGaussianBGModel;
params=params;
//preparestorages
CV_CALL(bg_model->
g_point=(CvGaussBGPoint*)cvAlloc(sizeof(CvGaussBGPoint)*
((first_frame->
width*first_frame->
height)+256)));
background=cvCreateImage(cvSize(first_frame->
width,
first_frame->
height),IPL_DEPTH_8U,first_frame->
nChannels));
foreground=cvCreateImage(cvSize(first_frame->
height),IPL_DEPTH_8U,1));
storage=cvCreateMemStorage());
//initializing
var_init=2*params.std_threshold*params.std_threshold;
//初始化方差
g_point[0].g_values=
(CvGaussBGValues*)cvAlloc(sizeof(CvGaussBGValues)*params.n_gauss*
(first_frame->
height+128)));
for(i=0,n=0;
i<
height;
i++)//行
for(j=0;
j<
width;
j++,n++)//列
{
constintp=i*first_frame->
widthStep+j*first_frame->
nChannels;
//以下几步是对第一个高斯函数做初始化
g_point[n].g_values=bg_model->
g_point[0].g_values+n*params.n_gauss;
g_point[n].g_values[0].weight=1;
//权值赋为1
g_point[n].g_values[0].match_sum=1;
//高斯函数被匹配的次数
for(m=0;
m<
m++)
g_point[n].g_values[0].variance[m]=var_init;
//均值赋为当前像素的值
g_point[n].g_values[0].mean[m]=(unsignedchar)first_frame->
imageData[p+m];
//除第一以外的高斯分布函数的初始化(均值、权值和匹配次数都置零)
for(k=1;
k<
params.n_gauss;
k++)
g_point[n].g_values[k].weight=0;
g_point[n].g_values[k].match_sum=0;
m++){
g_point[n].g_values[k].variance[m]=var_init;
g_point[n].g_values[k].mean[m]=0;
}//g_point[]:
像素,g_values[]:
高斯分布函数,mean[]:
通道
countFrames=0;
__END__;
if(cvGetErrStatus()<
0)
CvBGStatModel*base_ptr=(CvBGStatModel*)bg_model;
if(bg_model&
&
release)
release(&
base_ptr);
cvFree(&
bg_model);
bg_model=0;
return(CvBGStatModel*)bg_model;
cvUpdateBGStatModel(videoFrame,bgModel);
typedefint(CV_CDECL*CvUpdateBGStatModel)(IplImage*curr_frame,structCvBGStatModel*bg_model);
/////////////////////////cvUpdateBGStatModel//////////////////////////////////
//函数功能:
背景模型的更新,不仅要更新高斯分布函数的参数,还要更新各高斯函数的权重
staticintCV_CDECLicvUpdateGaussianBGModel(IplImage*curr_frame,CvGaussBGModel*bg_model)
inti,j,k,n;
intregion_count=0;
CvSeq*first_seq=NULL,*prev_seq=NULL,*seq=NULL;
countFrames++;
curr_frame->
i++)
j++,n++)
intmatch[CV_BGFG_MOG_MAX_NGAUSSIANS];
//对高斯函数做标记,match[m]=1表示函数m为匹配的高斯分布函数
doublesort_key[CV_BGFG_MOG_MAX_NGAUSSIANS];
//此数组存贮每个高斯函数的均值与方差比值
constintnChannels=curr_frame->
constintp=curr_frame->
widthStep*i+j*nChannels;
CvGaussBGPoint*g_point=&
bg_model->
g_point[n];
constCvGaussBGStatModelParamsbg_model_params=bg_model->
params;
doublepixel[4];
//pixel[]存贮当前像素的各通道RGB值
intno_match;
for(k=0;
nChannels;
k++)
pixel[k]=(uchar)curr_frame->
imageData[p+k];
no_match=icvMatchTest(pixel,nChannels,match,g_point,&
bg_model_params);
//检查是否有与当前像素匹配的高斯函数
if(bg_model->
countFrames>
=bg_model->
params.win_size)?
?
icvUpdateFullWindow(pixel,nChannels,match,g_point,&
params);
if(no_match==-1)
icvUpdateFullNoMatch(curr_frame,p,match,g_point,&