应用过程:
1.首先采集第一幅图像,并且利用cvCreateGaussianBGModel来进行对混合模板进行复制,其中主要是模型的初始化,在此函数中并未对高斯函数的权重等进行赋值定义,而是在_icvUpdateGMM函数中,根据传入的数据从而不断的调整、更新、产生新的权重还有新的模型,就是这样高斯混合函数进行的产生。
2.之后对在传入的视频利用icvUpdateGaussianBGModel2,进行高斯模型的更新。
函数理解:
(1)首先确定进来的函数是否和之前的模板突袭那个是大小格式相同的并且也同时进行a的更新
if((curr_frame->height!=bg_model->params.nHeight)||(curr_frame->width!=bg_model->params.nWidth)||(curr_frame->nChannels!=bg_model->params.nND))
CV_Error( CV_StsBadSize, "the image not the same size as thereserved GMM background model");
3.之后对每个图像点进行确定即进行代入icvUpdatePixelBackgroundGMM2,对高斯函数进行更新。
在此函数中首先对图像进行了相关的矩阵话,
CvMat sstub, *src = cvGetMat(srcarr,&sstub); //有图得到矩阵
CvMat dstub, *dst = cvGetMat(dstarr,&dstub); //由图得到矩阵
其中有一块
//reshape if possible //重新定义形状
if( CV_IS_MAT_CONT(src->type & dst->type) )
{
size.width *= size.height;
size.height = 1;
} //将全部点转化为一维
不了解他的用途(如有了解,欢迎指教)
下一步对图像的每个点进行相应的模板匹配更新参数,其中:
for( y = 0; y < size.height; y++ )
{
uchar* sptr = src->data.ptr + src->step*y; //对每行每行的像素进行
uchar* pDataOutput =dst->data.ptr + dst->step*y;
是对每行每行的进行的,src->data.ptr是图像的开始点的指针,src->step*y是偏移量,对每个数据点利用_icvUpdateGMM函数进行匹配更新,之后利用_icvRemoveShadowGMM进行阴影的消除
4.对icvUpdateGMM的一些理解
当一个数据传入后,进行验证并且更新高斯模型:
(1)先定义一些参数;高斯模板的使用的以及定义的参数pGMM也传过来了;
(2)其中还有个重要的参数 nModes=*pModesUsed;//current number of modes in GMM (现在用的高斯混合中的高斯函数)
(3)进入模型中每个高斯函数逐次进行检验,其中:
dData[iD]=pGauss->mean[iD]-data[iD]; //data 为现有的一个数据点,因为有RGB不同的通道
dist2+=dData[iD]*dData[iD];
(这两句不太理解,如有理解的请多多指教)
(4)首先验证是不是背景,如果这只是给一个最终的返回值;
(5)验证是否符合那个高斯函数(dist2<m_fTg*var) 判断,如果符合,则参数进行更新,排序,并且将其中有的权重很小很小的进行删除并进行归一化:
//check prune //减小删除 //由于此权重太小了此次更新也还是小的为负的了
if (weight<-m_fPrune)
{
weight=0.0;
nModes--;
}
(6)如果没有符合的高斯函数可以进行相应的匹配,则产生一个新的高斯模板函数,在此如果现在函数的个数与开始定义的相同,则将权重最小的那个替换掉,否则直接产生一个新的高斯模板函数:
if (nModes==m_nM) //模板数
{
//replace theweakest //产生新的模板并且替换最小的那个
pGauss=pGMM+m_nM-1; //the newmodel point to not used .
}
else
{
//add a new one
pGauss=pGMM+nModes;
nModes++;
}
新的函数的权重与更新速率a相等,
pGauss->weight=m_fAlphaT; //the new is the rates of update
//renormalize all weights //重新归一化所有权重
for (iMode = 0; iMode < nModes-1;iMode++)
{
pGMM[iMode].weight*=m_fOneMinAlpha; //m_fOneMinAlpha =1 - m_fAlphaT
}
注意:此次归一化,后面的nModes为nModes-1, 所以只是前面的几个进行重新的权重分配,并排序。
5_icvRemoveShadowGMM函数一些记录与理解:
(1)首先定义一个判断是否是阴影的分数的构成(分子与分母),对于每个高斯模型下,我们都得到了一个阴影分数指数float a =numerator / denominator; 计算完后
(2)我们来检测颜色的失真情况, 对每一维dist2a += (dD*dD); //检测图像失真 对应(AnImprove Adaptive Background Mixture Model for Realtime Tracking with ShadowDetection)
Dist2a 即为那个a. ,并且返回2证明检测到了