opencv高斯混合模型

发布时间:2014-10-22 14:36:40编辑:www.fx114.net 分享查询网我要评论
本篇文章主要介绍了"opencv高斯混合模型",主要涉及到opencv高斯混合模型方面的内容,对于opencv高斯混合模型感兴趣的同学可以参考一下。

高斯背景模型在 运动检测中的应用 原理 : 高斯模型就是用高斯概率密度函数(正态分布曲线)精确地量化事物,将一个事物分解为若干的基于高斯概率密度函数(正态分布曲线)形成的模型。 对图像背景建立高斯模型的原理及过程:图像灰度直方图反映的是图像中某个灰度值出现的频次,也可以认为是图像灰度概率密度的估计。如果图像所包含的目标区域和背景区域相比比较大,且背景区域和目标区域在灰度上有一定的差异,那么该图像的灰度直方图呈现双峰-谷形状,其中一个峰对应于目标,另一个峰对应于背景的中心灰度。对于复杂的图像,尤其是医学图像,一般是多峰的。通过将直方图的多峰特性看作是多个高斯分布的叠加,可以解决图像的分割问题。 在智能监控系统中,对于运动目标的检测是中心内容,而在运动目标检测提取中,背景目标对于目标的识别和跟踪至关重要。而建模正是背景目标提取的一个重要环节。 我们首先要提起背景和前景的概念,前景是指在假设背景为静止的情况下,任何有意义的运动物体即为前景。建模的基本思想是从当前帧中提取前景,其目的是使背景更接近当前视频帧的背景。即利用当前帧和视频序列中的当前背景帧进行加权平均来更新背景,但是由于光照突变以及其他外界环境的影响,一般的建模后的背景并非十分干净清晰,而高斯混合模型是是建模最为成功的方法之一。 混合高斯模型使用K(基本为3到5个)个高斯模型来表征图像中各个像素点的特征,在新一帧图像获得后更新混合高斯模型, 用当前图像中的每个像素点与混合高斯模型匹配,如果成功则判定该点为背景点, 否则为前景点。 通观整个高斯模型,主要是有方差和均值两个参数决定,对均值和方差的学习,采取不同的学习机制,将直接影响到模型的稳定性、精确性和收敛性 。由于我们是对运动目标的背景提取建模,因此需要对高斯模型中方差和均值两个参数实时更新。为提高模型的学习能力,改进方法对均值和方差的更新采用不同的学习率;为提高在繁忙的场景下,大而慢的运动目标的检测效果,引入权值均值的概念,建立背景图像并实时更新,然后结合权值、权值均值和背景图像对像素点进行前景和背景的分类。 到这里为止,混合高斯模型的建模基本完成,我在归纳一下其中的流程,首先初始化预先定义的几个高斯模型,对高斯模型中的参数进行初始化,并求出之后将要用到的参数。其次,对于每一帧中的每一个像素进行处理,看其是否匹配某个模型,若匹配,则将其归入该模型中,并对该模型根据新的像素值进行更新,若不匹配,则以该像素建立一个高斯模型,初始化参数,代理原有模型中最不可能的模型。最后选择前面几个最有可能的模型作为背景模型,为背景目标提取做铺垫。 方法: 目前,运动物体检测的问题主要分为两类,摄像机固定和摄像机运动。对于摄像机运动的运动物体检测问题,比较著名的解决方案是光流法,通过求解偏微分方程求的图像序列的光流场,从而预测摄像机的运动状态。对于摄像机固定的情形,当然也可以用光流法,但是由于光流法的复杂性,往往难以实时的计算,所以我采用高斯背景模型。因为,在摄像机固定的情况下,背景的变化是缓慢的,而且大都是光照,风等等的影响,通过对背景建模,对一幅给定图像分离前景和背景,一般来说,前景就是运动物体,从而达到运动物体检测的目的。   单分布高斯背景模型   单分布高斯背景模型认为,对一个背景图像,特定像素亮度的分布满足高斯分布,即对背景图像B, (x,y)点的亮度满足:   IB (x,y) ~ N(u,d)   这样我们的背景模型的每个象素属性包括两个参数:平均值u 和 方差d。   对于一幅给定的图像G,如果 Exp(-(IG (x,y)-u(x,y))^2/(2*d^2)) > T,认为(x,y)是背景点,反之是前景点。   同时,随着时间的变化,背景图像也会发生缓慢的变化,这时我们要不断更新每个象素点的参数   u(t+1,x,y) = a*u(t,x,y) + (1-a)*I(x,y)   这里,a称为更新参数,表示背景变化的速度,一般情况下,我们不更新d(实验中发现更不更新 d,效果变化不大)。   具体原理: 单高斯分布模型GSM 多维变量X服从高斯分布时,它的概率密度函数PDF为: x是维度为d的列向量,u是模型期望,Σ是模型方差。在实际应用中u通常用样本均值来代替,Σ通常用样本方差来代替。很容易判断一个样x本是否属于类别C。因为每个类别都有自己的u和Σ,把x代入(1)式,当概率大于一定阈值时我们就认为x属于C类。 从几何上讲,单高斯分布模型在二维空间应该近似于椭圆,在三维空间上近似于椭球。遗憾的是在很多分类问题中,属于同一类别的样本点并不满足“椭圆”分布的特性。这就引入了高斯混合模型。 高斯混合模型GMM GMM认为数据是从几个GSM中生成出来的,即 K需要事先确定好,就像K-means中的K一样。πk是权值因子。其中的任意一个高斯分布N(x;uk,Σk)叫作这个模型的一个component。这里有个问题,为什么我们要假设数据是由若干个高斯分布组合而成的,而不假设是其他分布呢?实际上不管是什么分布,只K取得足够大,这个XX Mixture Model就会变得足够复杂,就可以用来逼近任意连续的概率密度分布。只是因为高斯函数具有良好的计算性能,所GMM被广泛地应用。 GMM是一种聚类算法,每个component就是一个聚类中心。即在只有样本点,不知道样本分类(含有隐含变量)的情况下,计算出模型参数(π,u和Σ)----这显然可以用EM算法来求解。再用训练好的模型去差别样本所属的分类,方法是:step1随机选择K个component中的一个(被选中的概率是πk);step2把样本代入刚选好的component,判断是否属于这个类别,如果不属于则回到step1。 样本分类已知情况下的GMM 当每个样本所属分类已知时,GMM的参数非常好确定,直接利用Maximum Likelihood。设样本容量为N,属于K个分类的样本数量分别是N1,N2,...,Nk,属于第k个分类的样本集合是L(k)。 样本分类未知情况下的GMM 有N个数据点,服从某种分布Pr(x;θ),我们想找到一组参数θ,使得生成这些数据点的概率最大,这个概率就是 称为似然函数(Lilelihood Function)。通常单个点的概率很小,连乘之后数据会更小,容易造成浮点数下溢,所以一般取其对数,变成 称为log-likelihood function。 GMM的log-likelihood function就是: 这里每个样本xi所属的类别zk是不知道的。Z是隐含变量。 我们就是要找到最佳的模型参数,使得(6)式所示的期望最大,“期望最大化算法”名字由此而来。 EM法求解 EM要求解的问题一般形式是 Y是隐含变量。 我们已经知道如果数据点的分类标签Y是已知的,那么求解模型参数直接利用Maximum Likelihood就可以了。EM算法的基本思路是:随机初始化一组参数θ(0),根据后验概率Pr(Y|X;θ)来更新Y的期望E(Y),然后用E(Y)代替Y求出新的模型参数θ(1)。如此迭代直到θ趋于稳定。 E-Step E就是Expectation的意思,就是假设模型参数已知的情况下求隐含变量Z分别取z1,z2,...的期望,亦即Z分别取z1,z2,...的概率。在GMM中就是求数据点由各个 component生成的概率。 注意到我们在Z的后验概率前面乘以了一个权值因子αk,它表示在训练集中数据点属于类别zk的频率,在GMM中它就是πk。  M-Step M就是Maximization的意思,就是用最大似然的方法求出模型参数。现在我们认为上一步求出的r(i,k)就是“数据点xi由component k生成的概率”。根据公式(3),(4),(5)可以推出: 与K-means比较 相同点:都是可用于聚类的算法;都需要指定K值。 不同点:GMM可以给出一个样本属于某类的概率是多少。     代码如下: #include<stdio.h> #include<cv.h> #include<cxcore.h> #include<highgui.h> #include<cvaux.h> typedef struct MyCvGaussBGValues { float match_sum; float weight; float mean[3]; float variance[3]; } MyCvGaussBGValues; static void updateBackground(CvGaussBGModel* bg_model){ int K = bg_model->params.n_gauss; int nchannels = bg_model->background->nChannels; int height = bg_model->background->height; int width = bg_model->background->width; MyCvGaussBGValues *g_point = (MyCvGaussBGValues *) ((CvMat*)(bg_model->g_point))->data.ptr; MyCvGaussBGValues *mptr = g_point; for(int y=0; y<height; y++){ for (int x=0; x<width; x++, mptr+=K){ int pos = bg_model->background->widthStep*y + x*nchannels; float mean[3] = {0.0, 0.0, 0.0}; for(int k=0; k<K; k++){ for(int m=0; m<nchannels; m++){ mean[m] += mptr[k].weight * mptr[k].mean[m]; } } for(int m=0; m<nchannels; m++){ bg_model->background->imageData[pos+m] = (uchar) (mean[m]+0.5); } } } } int main(int argc,char **argv){ IplImage *pFrame=NULL; IplImage *pFrImg=NULL; IplImage *pBkImg=NULL; CvCapture *pCapture=NULL; CvBGStatModel *bg_model=NULL; int nFrmNum=0; //int region_count=0; cvNamedWindow("video",1); cvNamedWindow("background",1); cvNamedWindow("foreground",1); cvMoveWindow("video",30,0); cvMoveWindow("background",450,0); cvMoveWindow("foreground",900,0); pCapture=cvCaptureFromFile("F:\\1.avi"); while(pFrame=cvQueryFrame(pCapture)){ nFrmNum++; if(nFrmNum==1){ pBkImg=cvCreateImage(cvGetSize(pFrame),IPL_DEPTH_8U,3); pFrImg=cvCreateImage(cvGetSize(pFrame),IPL_DEPTH_8U,1); bg_model=(CvBGStatModel*)cvCreateGaussianBGModel(pFrame,0); } else{ cvUpdateBGStatModel(pFrame,(CvBGStatModel*)bg_model); updateBackground((CvGaussBGModel*)bg_model); cvClearMemStorage(bg_model->storage); cvCopy(bg_model->foreground,pFrImg,0); cvCopy(bg_model->background,pBkImg,0); } cvShowImage("video",pFrame); cvShowImage("background",pBkImg); cvShowImage("foreground",pFrImg); if(cvWaitKey(22)>=0) break; } cvReleaseBGStatModel((CvBGStatModel**)&bg_model); cvDestroyAllWindows(); cvReleaseImage(&pFrImg); cvReleaseImage(&pBkImg); cvReleaseCapture(&pCapture); return 0; }


上一篇:在Windows下不使用密码远程登陆Linux
下一篇:HadoopHbaseZookeeper集群

相关文章

相关评论

本站评论功能暂时取消,后续此功能例行通知。

一、不得利用本站危害国家安全、泄露国家秘密,不得侵犯国家社会集体的和公民的合法权益,不得利用本站制作、复制和传播不法有害信息!

二、互相尊重,对自己的言论和行为负责。

好贷网好贷款