详解OpenCV的视频背景/前景分割(背景建模/前景提取)类cv::BackgroundSubtractorMOG2,并利用它实现对道路监控视频前景/背景的提取

Posted 昊虹图像算法

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了详解OpenCV的视频背景/前景分割(背景建模/前景提取)类cv::BackgroundSubtractorMOG2,并利用它实现对道路监控视频前景/背景的提取相关的知识,希望对你有一定的参考价值。

cv::BackgroundSubtractorMOG2和cv::bgsegm::BackgroundSubtractorMOG一样,都是基于高斯混合模型的背景与前景分割算法。

cv::BackgroundSubtractorMOG2是对cv::bgsegm::BackgroundSubtractorMOG的改进,经过改进,它实现了自适应高斯混合模型参数的更新,增强了复杂场景背景检测的性能。

具体的算法原理可以参见下面两篇论文:
第一篇:
Zoran Zivkovic and Ferdinand van der Heijden. Efficient adaptive density estimation per image pixel for the task of background subtraction. Pattern recognition letters, 27(7):773–780, 2006.
第二篇:
Zoran Zivkovic. Improved adaptive gaussian mixture model for background subtraction. In Pattern Recognition, 2004. ICPR 2004. Proceedings of the 17th International Conference on, volume 2, pages 28–31. IEEE, 2004.

第一篇论文的摘要如下:

We analyze the computer vision task of pixel-level background subtraction. We present recursive equations that are used to constantly update the parameters of a Gaussian mixture model and to simultaneously select the appropriate number of components for each pixel. We also present a simple non-parametric adaptive density estimation method. The two methods are compared with each other and with some previously proposed algorithms.

翻译如下:
分析了像素级背景差分的计算机视觉任务。我们提出了递归方程,用于不断更新高斯混合模型的参数,同时为每个像素选择适当数量的组件。我们还提出了一种简单的非参数自适应密度估计方法。对这两种方法进行了比较,并与以前提出的一些算法进行了比较。

从第一篇论文的摘要可以看出,类cv::BackgroundSubtractorMOG2能够自动更新高斯混合模型的参数。

第二篇论文的摘要如下:

Background subtraction is a common computer vision task. We analyze the usual pixel-level approach. We develop an efficient adaptive algorithm using Gaussian mixture probability density. Recursive equations are used to constantly update the parameters and but also to simultaneously select the appropriate number of components for each pixel.

翻译如下:
背景减法是一种常见的计算机视觉任务。我们分析了常用的像素级方法。我们开发了一种利用高斯混合概率密度的高效自适应算法。递归方程用于不断更新参数,但也用于同时为每个像素选择适当数量的组件。

从第二篇论文的摘要可以看出,类cv::BackgroundSubtractorMOG2除了能够自动更新高斯混合模型的参数,而且可以为每个像素选择适当数量的组件,重点是在像素级尺度上进行处理。

继承于基类cv::BackgroundSubtractor的成员函数apply()和getBackgroundImage()的详细介绍见博文:https://blog.csdn.net/wenhao_ir/article/details/125007017

其特有的成员函数如下:

virtual double cv::BackgroundSubtractorMOG2::getBackgroundRatio( ) const

成员函数getBackgroundRatio()的介绍见博文 https://blog.csdn.net/wenhao_ir/article/details/125010301

virtual double cv::BackgroundSubtractorMOG2::getComplexityReductionThreshold( ) const

成员函数getComplexityReductionThreshold()用于返回复杂性降低阈值。此参数定义每一个样本中支持高斯混合模型某个分量存在需要的样本数量。CT=0.05是所有样本的默认值。通过将CT设置为0,可以得到与标准Stauffer&Grimson算法非常相似的算法。

virtual bool cv::BackgroundSubtractorMOG2::getDetectShadows( )	const

成员函数getDetectShadows()用于返回阴影检测标志。如果阴影检测标志的值为true,那么算法会检测阴影并对其进行标记。

virtual int cv::BackgroundSubtractorMOG2::getHistory( )	const

成员函数getHistory()用于返回影响背景模型的历史帧数。

virtual int cv::BackgroundSubtractorMOG2::getNMixtures(	) const

成员函数getNMixtures()用于返回高斯混合模型中高斯分量的个数。

virtual double cv::BackgroundSubtractorMOG2::getShadowThreshold	( )	const

成员函数getShadowThreshold()的介绍见博文 https://blog.csdn.net/wenhao_ir/article/details/125007017

virtual int cv::BackgroundSubtractorMOG2::getShadowValue( )	const

成员函数getShadowThreshold()的介绍见博文 https://blog.csdn.net/wenhao_ir/article/details/125007017

virtual double cv::BackgroundSubtractorMOG2::getVarInit( )	const

成员函数getVarInit()用于返回每个高斯分量的初始方差。

virtual double cv::BackgroundSubtractorMOG2::getVarMax( ) const

成员函数getVarMax()用于返回所有高斯分量中的最大方差。

virtual double cv::BackgroundSubtractorMOG2::getVarMin(	) const

成员函数getVarMin()用于返回所有高斯分量中的最小方差。

virtual double cv::BackgroundSubtractorMOG2::getVarThreshold( )	const

成员函数getVarThreshold()用于返回返回像素模型匹配的方差阈值。这个参数是Mahalanobis距离(马氏距离)平方的主阈值,它用于判断样本是否被背景模型很好的描述。它相当于上面论文中的Cthr参数。

virtual double cv::BackgroundSubtractorMOG2::getVarThresholdGen	( )	const

成员函数getVarThresholdGen()用于返回是否要为像素新建高斯混合混型组件的方差阈值,对应于论文中的参数Tg 。如果根据参数VarThreshold,样本不能匹配现有背景模型的话,就得考虑是否要为其新建高斯混合混型组件了,那么什么情况下为其新建高斯混合混型组件呢,就根据值VarThresholdGe来判断,如果这个样本的标准差的3倍大于等VarThreshold,则为其新建高斯混合混型组件,否则,视为前景。显然,这个值越小,产生的组件越多。较高的VarThreshold虽然组件数量会较小,但也会导致这些组件过大。该参数默认值9,来历为当标准差取3时得到的,标准差为3,则其3倍为9。

virtual void cv::BackgroundSubtractorMOG2::setBackgroundRatio(double ratio)	

成员函数setBackgroundRatio()用于设置背景比率,详情见对成员函数getBackgroundRatio()的介绍。

virtual void cv::BackgroundSubtractorMOG2::setComplexityReductionThreshold(double ct)	

成员函数setComplexityReductionThreshold()用于设置值ComplexityReductionThreshold,详见对成员函数getComplexityReductionThreshold()的介绍。

virtual void cv::BackgroundSubtractorMOG2::setDetectShadows	(bool detectShadows)	

成员函数setDetectShadows()用于设置是否要进行阴影检测。

virtual void cv::BackgroundSubtractorMOG2::setHistory(int history)	

成员函数setHistory()用于设置影响背景模型的历史帧数。

virtual void cv::BackgroundSubtractorMOG2::setNMixtures	(int nmixtures)	

成员函数setNMixtures()用于设置高斯混合模型中高斯分量的个数。

virtual void cv::BackgroundSubtractorMOG2::setShadowThreshold(double threshold)	

成员函数setShadowThreshold()的详情见博文 https://blog.csdn.net/wenhao_ir/article/details/125007017

virtual void cv::BackgroundSubtractorMOG2::setShadowValue(int value)	

成员函数setShadowValue()的详情见博文 https://blog.csdn.net/wenhao_ir/article/details/125007017

virtual void cv::BackgroundSubtractorMOG2::setVarInit(double varInit)	

成员函数setVarInit()用于设置参数VarInit,详情见对成员函数getVarInit()的介绍。

virtual void cv::BackgroundSubtractorMOG2::setVarMax(double varMax)	

成员函数setVarMax()用于设置参数VarMax,详情见对成员函数getVarMax()的介绍。

virtual void cv::BackgroundSubtractorMOG2::setVarMin(double varMin)	

成员函数setVarMin()用于设置参数VarMin,详情见对成员函数getVarMin()的介绍。

virtual void cv::BackgroundSubtractorMOG2::setVarThreshold(double varThreshold)	

成员函数setVarThreshold()用于设置参数VarThreshold,详情见对成员函数getVarThreshold()的介绍。

virtual void cv::BackgroundSubtractorMOG2::setVarThresholdGen(double varThresholdGen)	

成员函数setVarThresholdGen()用于设置参数VarThresholdGen,详情见对成员函数getVarThresholdGen()的介绍。

在上示例代码前,还需要介绍下函数createBackgroundSubtractorMOG2(),

函数createBackgroundSubtractorMOG2()用于构建类BackgroundSubtractorMOG2的实例化对象,并返回对象指针。
函数createBackgroundSubtractorMOG2()的原型如下:

Ptr<BackgroundSubtractorMOG2> cv::createBackgroundSubtractorMOG2(
																 int history = 500,
																 double varThreshold = 16,
																 bool 	detectShadows = true )	

参数history和varThreshold已经在上面介绍过了,所以只说下detectShadows这个参数,这个参数表示是否对前景进行阴影检测,默认值为ture,表示启用前景阴影检测。

下面上示例代码:
示例代码中用到的视频下载链接:https://pan.baidu.com/s/1X08cwwSE4DUvzT0XvHvpvw?pwd=9yyq

//博主微信/QQ 2487872782
//有问题可以联系博主交流
//有图像处理开发需求也请联系博主
//图像处理技术交流QQ群 271891601

//OpenCV版本:3.0
//VS版本:2013

#include <opencv2/opencv.hpp>

#include <iostream>
#include <sstream>

using namespace cv;
using namespace std;

void processVideo(Ptr<BackgroundSubtractorMOG2> pBackgroundMOG2, string videoFilename)

	cv::Mat frame, FGMask, BGimgae;
	int keyboard = 0;
	// 视频获取
	VideoCapture capture(videoFilename);
	if (!capture.isOpened())
		exit(EXIT_FAILURE);

	// 按下q键或esc键退出
	while ((char)keyboard != 'q' && (char)keyboard != 27)
	
		// 读取当前帧
		if (!capture.read(frame))
			exit(EXIT_FAILURE);
		// 图像尺寸缩小
		cv::resize(frame, frame, cv::Size(), 0.3, 0.3);
		// 背景建模参数设定
		//pBackgroundMOG2->setHistory(200);
		//pBackgroundMOG2->setDist2Threshold(600);

		
		pBackgroundMOG2->setShadowThreshold(0.5);
		pBackgroundMOG2->setShadowValue(10);

		// 计算得到前景掩码图像
		double learningRate = -1;
		pBackgroundMOG2->apply(frame, FGMask, learningRate);

		// 计算得到背景图像
		pBackgroundMOG2->getBackgroundImage(BGimgae);

		// 输出当前帧号
		stringstream ss;
		rectangle(frame, cv::Point(10, 2), cv::Point(100, 20), cv::Scalar(255, 255, 255), -1);
		ss << capture.get(CAP_PROP_POS_FRAMES);
		string frameNumberString = ss.str();
		// 左上角显示帧号
		putText(frame, frameNumberString.c_str(), cv::Point(15, 15), FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 0));

		// 输出结果
		imshow("当前视频帧", frame);
		imshow("背景图像", BGimgae);
		imshow("前景掩码图像", FGMask);
		keyboard = waitKey(30);
	
	capture.release();

int main(int argc, char* argv[])

	// 实例化背景建模算法类
	Ptr<BackgroundSubtractorMOG2> pBackgroundMOG2 = createBackgroundSubtractorMOG2();
	string inputPath = "car1.avi";
	processVideo(pBackgroundMOG2, inputPath);
	return 0;

运行结果如下图所示:

因为是视频处理,录了个视频,以便大家可以更好观察结果,视频在线观看和下载链接如下:
链接:https://pan.baidu.com/s/1bmDpp0wS_gtIGXA-g2Nt4w?pwd=uaz0

延伸阅读:
OpenCV3.0中有哪些视频背景/前景分割(背景建模/前景提取)算法的类,它们各自的算法原理、特点是什么,并附示例代码
OpenCV4中有哪些视频背景/前景分割(背景建模/前景提取)算法的类,它们各自的算法原理、特点是什么,并附示例代码

以上是关于详解OpenCV的视频背景/前景分割(背景建模/前景提取)类cv::BackgroundSubtractorMOG2,并利用它实现对道路监控视频前景/背景的提取的主要内容,如果未能解决你的问题,请参考以下文章

详解OpenCV的视频背景/前景分割(背景建模/前景提取)类cv::BackgroundSubtractorKNN,并利用它实现对道路监控视频前景/背景的提取

详解OpenCV的视频背景/前景分割(背景建模/前景提取)类cv::bgsegm::BackgroundSubtractorGMG,并利用它实现对道路监控视频前景的提取

OpenCV4中有哪些视频背景/前景分割(背景建模/前景提取)算法的类,它们各自的算法原理和特点是什么。

OpenCV3中有哪些视频背景/前景分割(背景建模/前景提取)算法的类,它们各自的算法原理和特点是什么。

OpenCV的视频背景/前景分割(背景建模/前景提取)类cv::bgsegm::BackgroundSubtractorLSBP的使用示例代码及运行效果

OpenCV的视频背景/前景分割(背景建模/前景提取)类cv::bgsegm::BackgroundSubtractorGSOC的使用示例代码及运行效果