背景建模与前景检测(一)——混合高斯GMM

本文介绍了两种使用OpenCV实现混合高斯模型(GMM)进行背景建模和前景检测的方法。方法一是直接使用BackgroundSubtractorMOG2函数,简单快速;方法二是自编程序,灵活可调整。文章提供了详细代码实现,包括GMM参数的更新、排序和创建新高斯组件的过程。
摘要由CSDN通过智能技术生成

        混合高斯模型GMM

       混合高斯模型GMM我总结的有两种实现方法,一种是直接使用OPENCV中的MOG函数实现前景检测;另外一种是自己根据GMM的原理编写程序。两种方法对比,方法一比方法二简单,速度快。但是方法二后期可改动的空间大,可以结合其他算法。以下贴出两种方法的实现代码,我是在opencv2.4.10+vs2010中实验通过的。


方法一:


[cpp]  view plain   copy
  1. //  基于混合高斯模型的运动目标检测  
  2. //  Author: www.icvpr.com   
  3. //  Blog: http://blog.csdn.net/icvpr    
  4.   
  5. #include <iostream>  
  6. #include <string>  
  7.   
  8. #include <opencv2/opencv.hpp>  
  9.   
  10.   
  11. int main(int argc, char** argv)  
  12. {  
  13.     std::string videoFile = "../test.avi";  
  14.   
  15.     cv::VideoCapture capture;  
  16.     capture.open(videoFile);  
  17.   
  18.     if (!capture.isOpened())  
  19.     {  
  20.         std::cout<<"read video failure"<<std::endl;  
  21.         return -1;  
  22.     }  
  23.   
  24.   
  25.     cv::BackgroundSubtractorMOG2 mog;  
  26.   
  27.     cv::Mat foreground;  
  28.     cv::Mat background;  
  29.   
  30.     cv::Mat frame;  
  31.     long frameNo = 0;  
  32.     while (capture.read(frame))  
  33.     {  
  34.         ++frameNo;  
  35.   
  36.         std::cout<<frameNo<<std::endl;  
  37.   
  38.         // 运动前景检测,并更新背景  
  39.         mog(frame, foreground, 0.001);         
  40.           
  41.         // 腐蚀  
  42.         cv::erode(foreground, foreground, cv::Mat());  
  43.           
  44.         // 膨胀  
  45.         cv::dilate(foreground, foreground, cv::Mat());  
  46.   
  47.         mog.getBackgroundImage(background);   // 返回当前背景图像  
  48.   
  49.         cv::imshow("video", foreground);  
  50.         cv::imshow("background", background);  
  51.   
  52.   
  53.         if (cv::waitKey(25) > 0)  
  54.         {  
  55.             break;  
  56.         }  
  57.     }  
  58.       
  59.   
  60.   
  61.     return 0;  
  62. }  


实验结果:



当前帧图像





当前背景图像




前景图像




经过腐蚀和膨胀处理后的前景图像


(白色为运动目标区域;灰色为阴影区域;黑色为背景)


< 转载请注明:http://blog.csdn.net/icvpr>



方法二:



 

MOG_BGS.h

[cpp]  view plain   copy
  1. #pragma once  
  2. #include <iostream>  
  3. #include "opencv2/opencv.hpp"  
  4.   
  5. using namespace cv;  
  6. using namespace std;  
  7.   
  8. //定义gmm模型用到的变量  
  9.  #define GMM_MAX_COMPONT 6          //每个GMM最多的高斯模型个数  
  10.  #define GMM_LEARN_ALPHA 0.005    
  11.  #define GMM_THRESHOD_SUMW 0.7  
  12.  #define TRAIN_FRAMES 60    // 对前 TRAIN_FRAMES 帧建模  
  13.   
  14. class MOG_BGS  
  15. {  
  16. public:  
  17.     MOG_BGS(void);  
  18.     ~MOG_BGS(void);  
  19.   
  20.     void init(const Mat _image);  
  21.     void processFirstFrame(const Mat _image);  
  22.     void trainGMM(const Mat _image);  
  23.     void getFitNum(const Mat _image);  
  24.     void testGMM(const Mat _image);  
  25.     Mat getMask(void){ return m_mask;};  
  26.    
  27. private:  
  28.     Mat m_weight[GMM_MAX_COMPONT];  //权值  
  29.     Mat m_mean[GMM_MAX_COMPONT];    //均值  
  30.     Mat m_sigma[GMM_MAX_COMPONT];   //方差  
  31.   
  32.     Mat m_mask;  
  33.     Mat m_fit_num;  
  34. };  


MOG_BGS.cpp

[cpp]  view plain   copy
  1. #include "MOG_BGS.h"  
  2.   
  3. MOG_BGS::MOG_BGS(void)  
  4. {  
  5.   
  6. }  
  7.   
  8. MOG_BGS::~MOG_BGS(void)  
  9. {  
  10.   
  11. }  
  12.   
  13. // 全部初始化为0  
  14. void MOG_BGS::init(const Mat _image)  
  15. {  
  16.     /****initialization the three parameters ****/  
  17.      for(int i = 0; i < GMM_MAX_COMPONT; i++)  
  18.      {  
  19.          m_weight[i] = Mat::zeros(_image.size(), CV_32FC1);  
  20.          m_mean[i] = Mat::zeros(_image.size(), CV_8UC1);  
  21.          m_sigma[i] = Mat::zeros(_image.size(), CV_32FC1);  
  22.      }  
  23.      m_mask = Mat::zeros(_image.size(),CV_8UC1);  
  24.      m_fit_num = Mat::ones(_image.size(),CV_8UC1);  
  25. }  
  26.   
  27. //gmm第一帧初始化函数实现  
  28. //捕获到第一帧时对高斯分布进行初始化.主要包括对每个高斯分布的权值、期望和方差赋初值.  
  29. //其中第一个高斯分布的权值为1,期望为第一个像素数据.其余高斯分布权值为0,期望为0.  
  30. //每个高斯分布都被赋予适当的相等的初始方差 15  
  31. void MOG_BGS::processFirstFrame(const
  • 2
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值