号码滚动随机抽取器:OpenCV编程案例:混合高斯模型(CvGaussBGModel)使用案例 - OpenC...

来源:百度文库 编辑:中财网 时间:2024/04/28 00:37:13


代码如下:
  1. #include
  2. #include
  3. #include
  4. #include
  5. #include //必须引此头文件
  6. int main( int argc, char** argv )
  7. {

  8.    IplImage* pFrame = NULL;   
  9.    IplImage* pFrImg = NULL;
  10.    IplImage* pBkImg = NULL;   
  11.    CvCapture* pCapture = NULL;   
  12.    int nFrmNum = 0;

  13.    cvNamedWindow("video", 1); //创建自动调节大小的窗口
  14.    cvNamedWindow("background",1);
  15.    cvNamedWindow("foreground",1);   
  16.    cvMoveWindow("video", 30, 0);
  17.    cvMoveWindow("background", 360, 0);
  18.    cvMoveWindow("foreground", 690, 0);
  19.    if( argc > 2 )   
  20.    {     
  21.       fprintf(stderr, "Usage: bkgrd [video_file_name]\n");     
  22.       return -1;   
  23.    }


  24.    //打开视频文件
  25.    if(argc == 2)   
  26.       if( !(pCapture = cvCaptureFromFile(argv[1])))     
  27.       {   
  28.          fprintf(stderr, "Can not open video file %s\n", argv[1]);   
  29.          return -2;     
  30.       }
  31.    //打开摄像头
  32.    if (argc == 1)   
  33.       if( !(pCapture = cvCaptureFromCAM(0)))     
  34.       {   
  35.          fprintf(stderr, "Can not open camera.\n");   
  36.          return -2;     
  37.       }   

  38.    //初始化高斯混合模型参数
  39.    CvGaussBGModel* bg_model=NULL;

  40.    while(pFrame = cvQueryFrame( pCapture ))   
  41.    {     
  42.       nFrmNum++;           
  43.       if(nFrmNum == 1)   
  44.       {   
  45.          pBkImg = cvCreateImage(cvSize(pFrame->width, pFrame->height),  IPL_DEPTH_8U,3);   
  46.          pFrImg = cvCreateImage(cvSize(pFrame->width, pFrame->height),  IPL_DEPTH_8U,1);     


  47.          //高斯背景建模,pFrame可以是多通道图像也可以是单通道图像
  48.          //cvCreateGaussianBGModel函数返回值为CvBGStatModel*,
  49.          //需要强制转换成CvGaussBGModel*
  50.          bg_model = (CvGaussBGModel*)cvCreateGaussianBGModel(pFrame, 0);
  51.       }     
  52.       else
  53.       {
  54.   //更新高斯模型
  55.   cvUpdateBGStatModel(pFrame, (CvBGStatModel *)bg_model );
  56.   //pFrImg为前景图像,只能为单通道
  57.   //pBkImg为背景图像,可以为单通道或与pFrame通道数相同
  58.   cvCopy(bg_model->foreground,pFrImg,0);
  59.   cvCopy(bg_model->background,pBkImg,0);
  60.          //把图像正过来
  61.          pBkImg->origin=1;
  62.          pFrImg->origin=1;

  63.          cvShowImage("video", pFrame);   
  64.          cvShowImage("background", pBkImg);   
  65.          cvShowImage("foreground", pFrImg);      
  66.          if( cvWaitKey(2) >= 0 )      
  67.             break;     
  68.       }     

  69.    }

  70.    //释放高斯模型参数占用内存   
  71.    cvReleaseBGStatModel((CvBGStatModel**)&bg_model);
  72.    cvDestroyWindow("video");
  73.    cvDestroyWindow("background");
  74.    cvDestroyWindow("foreground");   
  75.    cvReleaseImage(&pFrImg);
  76.    cvReleaseImage(&pBkImg);   
  77.    cvReleaseCapture(&pCapture);   
  78.    return 0;
  79. }
复制代码 程序运行情况如下:




窗口截图是有延时,所以,只能供参考。而且,我的机器运行结果是背景和前景图像都是倒立的。所以要对
  1.          //把图像正过来
  2.          pBkImg->origin=1;
  3.          pFrImg->origin=1;
复制代码 做修改。

算法分析:

  高斯混合模型是用于背景提取的方法,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保存了前景图像。