分享

OpenCV混合高斯模型前景分离

 陈永正的图书馆 2017-06-08

OpenCV混合高斯模型前景分离

运动检测的一般方法

  目前,运动物体检测的问题主要分为两类,摄像机固定和摄像机运动。对于摄像机运动的运动物体检测问题,比较著名的解决方案是光流法,通过求解偏微分方程求的图像序列的光流场,从而预测摄像机的运动状态。对于摄像机固定的情形,当然也可以用光流法,但是由于光流法的复杂性,往往难以实时的计算,所以我采用高斯背景模型。因为,在摄像机固定的情况下,背景的变化是缓慢的,而且大都是光照,风等等的影响,通过对背景建模,对一幅给定图像分离前景和背景,一般来说,前景就是运动物体,从而达到运动物体检测的目的
单分布高斯背景模型
单分布高斯背景模型认为,对一个背景图像,特定像素亮度的分布满足高斯分布,即对背景图像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。在程序初始化部分定义高斯混合模型参数CvGaussBGModel* bg_model=NULL;在读取第一帧图像(背景图像)时,进行高斯背景建模bg_model = (CvGaussBGModel*)cvCreateGaussianBGModel(image, 0);image可以是灰度图象也可以是彩色图像。接下来再读取当前帧时,更新高斯模型
  regioncount=icvUpdateGaussianBGModel(currframe, bg_model );regioncount的含义我不确定,我理解是代表背景中不同颜色区域的个数,这个参数我没有用到,它只是icvUpdateGaussianBGModel函数的返回值。
  2。现在bg_model已经保存了经过高斯混合模型分类后的结果,bg_model->background保存了背景图像,bg_model->foreground保存了前景图像。
  1. #include <stdio.h>  
  2. #include <cv.h>  
  3. #include <cxcore.h>  
  4. #include <highgui.h>  
  5. #include <cvaux.h>//必须引此头文件  
  6. int main( int argc, char** argv )  
  7. {   
  8.   
  9.    IplImage* pFrame = NULL;     
  10.    IplImage* pFrImg = NULL;   
  11.    IplImage* pBkImg = NULL;     
  12.    CvCapture* pCapture = NULL;     
  13.    int nFrmNum = 0;  
  14.   
  15.    cvNamedWindow("video", 1);   
  16.    cvNamedWindow("background",1);   
  17.    cvNamedWindow("foreground",1);     
  18.    cvMoveWindow("video", 30, 0);   
  19.    cvMoveWindow("background", 360, 0);   
  20.    cvMoveWindow("foreground", 690, 0);  
  21.   
  22.    //打开视频文件   
  23.   
  24.    pCapture = cvCaptureFromFile("bike.avi");  
  25.    //pCapture = cvCaptureFromFile("20120726.avi");  
  26.    if( !pCapture )       
  27.    {     
  28.       fprintf(stderr, "Can not open video file %s\n", argv[1]);     
  29.       return -2;       
  30.    }  
  31.   
  32.   
  33.    //初始化高斯混合模型参数  
  34.    CvGaussBGModel* bg_model=NULL;  
  35.   
  36.    while(pFrame = cvQueryFrame( pCapture ))     
  37.    {       
  38.       nFrmNum++;             
  39.       if(nFrmNum == 1)     
  40.       {      
  41.          pBkImg = cvCreateImage(cvSize(pFrame->width, pFrame->height),  pFrame->depth, pFrame->nChannels /*IPL_DEPTH_8U,3*/);     
  42.          pFrImg = cvCreateImage(cvSize(pFrame->width, pFrame->height),  IPL_DEPTH_8U,1);       
  43.   
  44.   
  45.          //高斯背景建模,pFrame可以是多通道图像也可以是单通道图像  
  46.          //cvCreateGaussianBGModel函数返回值为CvBGStatModel*,  
  47.          //需要强制转换成CvGaussBGModel*  
  48.          bg_model = (CvGaussBGModel*)cvCreateGaussianBGModel(pFrame, 0);  
  49.       }       
  50.       else  
  51.       {      
  52.          //更新高斯模型  
  53.          cvUpdateBGStatModel(pFrame, (CvBGStatModel *)bg_model );  
  54.   
  55.          //pFrImg为前景图像,只能为单通道  
  56.          //pBkImg为背景图像,可以为单通道或与pFrame通道数相同  
  57.          cvCopy(bg_model->foreground,pFrImg,0);  
  58.          cvCopy(bg_model->background,pBkImg,0);  
  59.          cvThreshold(pFrImg, pFrImg, 128, 255, CV_THRESH_BINARY_INV);  
  60.   
  61.          //把图像正过来  
  62.       //   pBkImg->origin=1;  
  63.       //   pFrImg->origin=1;  
  64.   
  65.          cvShowImage("video", pFrame);      
  66.          cvShowImage("background", pBkImg);      
  67.          cvShowImage("foreground", pFrImg);         
  68.          if( cvWaitKey(100) >= 0 )        
  69.             break;       
  70.       }       
  71.   
  72.    }  
  73.   
  74.    //释放高斯模型参数占用内存     
  75.    cvReleaseBGStatModel((CvBGStatModel**)&bg_model);  
  76.    cvDestroyWindow("video");   
  77.    cvDestroyWindow("background");   
  78.    cvDestroyWindow("foreground");     
  79.    cvReleaseImage(&pFrImg);   
  80.    cvReleaseImage(&pBkImg);     
  81.    cvReleaseCapture(&pCapture);     
  82.    return 0;  
  83. }  

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多