GMM是网上到处可见且用得最多的背景建模算法,论文上很多相关概率公式,又看了很多博客对于GMM的解释,直到现在还总是觉得很难理解其中的真谛,从各方面整理一下目前自己所理解的内容,如果有理解偏差,欢迎指正。
Mog2用的是自适应的高斯混合模型(Adaptive GMM,Gaussian Mixture Model),在OpenCV中开源了的几种背景提取算法MOG,MOG2,GMG的测试程序结果中,MOG2确实在前景连续性及运算时间上都脱颖而出,后面会给出比较结果。下面就结合OpenCV2.4.9的mog2源码和源码文档中指出的04年Zoran Zivkovic的三篇论文,简要串一串GMM的理论基础,MOG2的大致原理,在代码实现上的结构及MOG2 API的用法。
在监控系统中,拍摄背景通常是变化较少的固定场景。通常我们假定没有入侵物体的静态场景具有一些常规特性,可以用一个统计模型描述。GMM就是用高斯模型,而且是多个高斯模型的加权和混合在一起来模拟背景的特性。这样一旦已知这个背景模型,入侵物体就能通过标出场景图像中不符合这一背景模型的部分来检测到。这一过程被称为背景减除(Backgroundsubtraction),我猜OpenCV中各种背景建模方法的基类称作“BackgroundSubtractor”也源于此吧。
上面说到GMM是用多个高斯模型的加权和来表示,假定是M个高斯分量,讨论M的取值是MOG2的作者研究的一个重点:在他之前Stauffer & Grimson取固定个数的高斯分量(M=4), Zoran则根据不同输入场景自动选择分量的个数。这样做的好处是在较简单的场景下,将只选出一个较重要的高斯分量,节省了后期更新背景时选属于哪一分量的时间,提高了速度。有两个测试结果为证:一是用OpenCV中测试程序对同一简单场景测试视频跑不同算法得到的运行时间如下表,明显mog2快很多;
mog | mog2 | gmg | |
电脑1 | 26904 | 14386 | 25533 |
电脑2 | 26947 | 14578 | 28834 |
对于整个图像的每个像素点都建立了一个GMM模型,建模过程中运用EM算法来求解参数组,一旦模型建立,后面每新来一帧都可以根据是否符合已建立的北京模型判断FG/BG,并会按论文中的参数更新公式更新GMM的所有参数。
OpenCV中,各背景建模方法类继承关系如下图,BackgroundSubtractor是基类。
也给出一个博客,OpenCV中MOG2的代码结构梳理。
在mog2的使用中,初始化后,operator()函数是执行背景更新的主要函数,operator()内部实现主要是OpenCV的一个并行框架parallel_for_(),再深入实际是MOG2Invoker类的operator()实现了背景更新的具体数学运算。具体实现可以查看MOG2Invoker API文档。
Mog2.operator()
Parallel_for_()
Invoker.operator()
Mog,mog2,gmg的整体框架都一样,用法也很简单,可以根据openCV官方的tutorial来看。
[i] Efficient adaptivedensity estimation per image pixel for the task of background subtraction.