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

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

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        混合高斯模型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
### 动态更新GMM用于背景建模 #### 背景建模的重要性 在计算机视觉领域,背景建模种常用技术,旨在区分场景中的静态背景和移动前景对象。高斯混合模型(GMM)由于其强大的表示能力和灵活性,在这任务中表现出色。 #### GMM的工作原理 GMM假设像素强度服从多个高斯分布的加权组合。对于每个像素位置,维护组权重、均值向量和协方差矩阵来描述这些分布[^1]。具体来说: - **权重**:反映各分量的概率大小; - **均值向量**:指示各个正态分布在特征空间的位置; - **协方差矩阵**:刻画数据沿不同方向上的散布程度。 #### 动态更新机制 为了使GMM能够适应随时间变化的环境条件,引入了套有效的在线学习策略来进行参数调整。主要涉及以下几个方面: - **样本匹配阶段** 对于新到来的帧图像中的每个像素点,计算它属于现有K个高斯组件的可能性,并选取最可能的那个作为当前观测的最佳解释者。如果最高得分低于预设阈值,则认为这是个新的模式并创建个新的高斯成分[^2]。 - **参数重估环节** 当某个高斯被选作最佳匹配后,利用贝叶斯定理对该高斯的相关统计量进行修正。例如,可以通过指数衰减的方式逐步融合最新观察到的信息至旧有的估计之中: ```python alpha = learning_rate # 学习率控制因子 mu_new = (1-alpha)*mu_old + alpha*x_t # 更新均值 sigma_sq_new = (1-alpha)*(sigma_sq_old+(alpha/(1-(1-alpha)**n))*(x_t-mu_old)**2) # 更新方差 ``` - **模型精简操作** 随着视频序列的增长,可能会积累过多不必要的高斯项。为此设置了个删除准则——当某分量长期未被激活或贡献度极低时将其移除;同时也可以考虑合并相似度过高的相邻簇以简化表达形式[^3]。 #### 应用实例分析 上述方法已在多种实际应用场景下得到了验证,比如监控摄像头下的行人检测、交通流量监测等。通过不断迭代优化,即使面对光照突变、天气状况改变等情况也能保持较高的鲁棒性和准确性。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值