标题：混合高斯模型
定义
混合高斯模型使用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，效果变化不大）。
高斯混合模型是用于背景提取的方法，OpenCV的cvaux中cvbgfg_gaussmix.cpp文件根据文献An improved adaptive background mixture model for real-time tracking with shadow中提供的方法编写了高斯混合模型函数。其中定义了CvGaussBGModel类用于存放高斯混合模型的各个参数。我用OpenCV使用高斯混合模型函数分以下几步：
1。需要用到icvUpdateGaussianBGModel，icvReleaseGaussianBGModel两个函数，但是源程序中将这两个函数定义为内部函数，需要做一些修改，首先将cvbgfg_gaussmix.cpp中前面两个函数的声明static void CV_CDECL icvReleaseGaussianBGModel( CvGaussBGModel** bg_model );
static int CV_CDECL icvUpdateGaussianBGModel( IplImage* curr_frame, CvGaussBGModel* bg_model );两行代码注释掉。然后在cvbgfg_gaussmix.cpp中间部分两个函数的定义部分，函数头static int和static void改成CV_IMPL int 和CV_IMPL void。最后在cvaux.h文件中CVAPI(CvBGStatModel*) cvCreateGaussianBGModel( IplImage* first_frame,
CvGaussBGStatModelParams* parameters CV_DEFAULT(NULL));这句后面加上以下两句CVAPI(void) icvReleaseGaussianBGModel( CvGaussBGModel** bg_model );
CVAPI(int) icvUpdateGaussianBGModel( IplImage* curr_frame, CvGaussBGModel* bg_model );
程序修改完毕，点rebuild all，全部重新编译。
2。在程序初始化部分定义高斯混合模型参数CvGaussBGModel* bg_model=NULL;在读取第一帧图像（背景图像）时，进行高斯背景建模bg_model = (CvGaussBGModel*)cvCreateGaussianBGModel(image, 0);image可以是灰度图象也可以是彩色图像。接下来再读取当前帧时，更新高斯模型
regioncount=icvUpdateGaussianBGModel(currframe, bg_model );regioncount的含义我不确定，我理解是代表背景中不同颜色区域的个数，这个参数我没有用到，它只是icvUpdateGaussianBGModel函数的返回值。
3。现在bg_model已经保存了经过高斯混合模型分类后的结果，bg_model->background保存了背景图像，bg_model->foreground保存了前景图像。
include <stdio.h>
#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
#include <cvaux.h>//必须引此头文件
int main( int argc, char** argv )
{
IplImage* pFrame = NULL; 
IplImage* pFrImg = NULL;
IplImage* pBkImg = NULL; 
CvCapture* pCapture = NULL; 
int nFrmNum = 0;
cvNamedWindow("video", 1);
cvNamedWindow("background",1);
cvNamedWindow("foreground",1); 
cvMoveWindow("video", 30, 0);
cvMoveWindow("background", 360, 0);
cvMoveWindow("foreground", 690, 0);
if( argc > 2 ) 
{ 
fprintf(stderr, "Usage: bkgrd [video_file_name]\n"); 
return -1; 
}
//打开视频文件
if(argc == 2) 
if( !(pCapture = cvCaptureFromFile(argv[1]))) 
{ 
fprintf(stderr, "Can not open video file %s\n", argv[1]); 
return -2; 
}
//打开摄像头
if (argc == 1) 
if( !(pCapture = cvCaptureFromCAM(-1))) 
{ 
fprintf(stderr, "Can not open camera.\n"); 
return -2; 
} 
//初始化高斯混合模型参数
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->width, 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);
cvCopy(bg_model->background,pBkImg,0);
//把图像正过来
pBkImg->origin=1;
pFrImg->origin=1;
cvShowImage("video", pFrame); 
cvShowImage("background", pBkImg); 
cvShowImage("foreground", pFrImg); 
if( cvWaitKey(2) >= 0 ) 
break; 
} 
}
//释放高斯模型参数占用内存 
cvReleaseBGStatModel((CvBGStatModel**)&bg_model);
cvDestroyWindow("video");
cvDestroyWindow("background");
cvDestroyWindow("foreground"); 
cvReleaseImage(&pFrImg);
cvReleaseImage(&pBkImg); 
cvReleaseCapture(&pCapture); 
return 0;
}