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

cv::BackgroundSubtractorKNN是利用K近邻(K-nearest neigbours)思想实现的背景建模。

百度百科对KNN算法的概括如下:
邻近算法,或者说K最邻近(KNN,K-NearestNeighbor)分类算法是数据挖掘分类技术中最简单的方法之一。所谓K最近邻,就是K个最近的邻居的意思,说的是每个样本都可以用它最接近的K个邻近值来代表。近邻算法就是将数据集合中每一个记录进行分类的方法。
方法的思路非常简单直观:如果一个样本在特征空间中的K个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。该方法在定类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别 。

该模型是由Z.Zivkovic、F.van der Heijden在2006年发表的论文“Efficient Adaptive Density Estimation per Image Pixel for the Task of Background Subtraction”中提出的,该方法应用K近邻思想,实现前景目标变换到较小场景模型下的背景模型建立。

论文的完整信息: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.

具体的原理大家可以去查阅上面那篇论文。如果只需要了解其大概原理那么把这个类的成员函数逐个理解一遍,基本就清楚了。

下面介绍其成员函数。

继承于基类cv::BackgroundSubtractor的成员函数如下:

virtual void cv::BackgroundSubtractor::apply(InputArray image,
											 OutputArray fgmask,
											 double learningRate = -1)	

成员函数apply()用于计算得到前景掩码图像。
参数意义如下:
image—输入图像。
fgmask—输出的前景图像。
learningRate—表示背景模型的更新速度。即值范围为0到1之间的值,默认值为-1。负参数值的情况下算法使用一些自动选择的学习率。0表示背景模型建立之后就不用更新,1表示对于视频的每一帧背景模型都完全重新初始化。

virtual void cv::BackgroundSubtractor::getBackgroundImage(OutputArray backgroundImage) const

成员函数getBackgroundImage()用于计算得到背景图像。输出参数backgroundImage中存储的便是计算得到的背景图像。

其特有的成员函数如下:

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

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

virtual double cv::BackgroundSubtractorKNN::getDist2Threshold( ) const

成员函数getDist2Threshold()用于返回像素和样本之间平方距离的阈值。在KNN算法中,
像素和样本之间平方距离上的阈值,用于确定像素是否接近数据样本。

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

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

virtual int cv::BackgroundSubtractorKNN::getkNNSamples(	)const

成员函数getkNNSamples()用于返回KNN算法中的k值,在KNN算法中,k值表示邻居数量,在这个类中,k是需要在dist2Threshold内的采样数,以确定该像素是否与kNN背景模型匹配。

virtual int cv::BackgroundSubtractorKNN::getNSamples( )	const

成员函数getNSamples( )用于返回背景模型中的数据样本数。

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

成员函数getShadowThreshold( )用于返回阴影检测阈值。当某点比背景的亮度暗时,这一点被认为是阴影。阴影阈值(本文中的Tau)是定义阴影可以暗多少的阈值,超过这个阈值规定的暗度,则这一点被认为不是阴影。比如Tau=0.5意味着,如果一个点的亮度低于背影在这个点亮度的0.5,那么它就不是阴影,说得更具体点,如果背景在这点的亮度是100,那么当这点的亮底小于50时,它就不被认为是阴影。具体在开发视觉项目时,我们可以依次用1→0.9→0.8→0.7→0.1去试嘛,看哪个的阴影检测效果最好。

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

成员函数getShadowValue( )用于返回阴影值。即如果我们认为某个前景点是阴影,那么我们把它的值在前景掩码图像中置为这个阴影值,它的默认值为127,显然如果这个值为0时,则在前景图像中,这个点被当成背景处理;如果这个值为255,则这个点被当成是前景处理。

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

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

virtual void cv::BackgroundSubtractorKNN::setDist2Threshold(double _dist2Threshold)	

成员函数setDist2Threshold()用于设置平方距离的阈值。如果某点与样本的距离值大于阈值,我们就认为这一点不属于这个样本。

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

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

virtual void cv::BackgroundSubtractorKNN::setkNNSamples(int _nkNN)	

成员函数setkNNSamples()用于设置KNN算法中的k值,在KNN算法中,k值表示邻居数量,在这个类中,k是需要在dist2Threshold内的采样数,以确定该像素是否与kNN背景模型匹配。

virtual void cv::BackgroundSubtractorKNN::setNSamples(int _nN)	

成员函数setNSamples()用于设置背景模型中的数据样本数。

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

成员函数setShadowThreshold()用于设置阴影判断阈值。具体的含义上面在介绍成员函数getShadowThreshold()时就已经介绍了。

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

成员函数setShadowValue()用于设置阴影值。具体的含义上面在介绍成员函数getShadowValue( )时就已经介绍了。

接下来是示例代码。

因为示例代码是自己花时间和精力写的,所以我上传到了CSDN的付费下载区,需要源码的朋友麻烦花费1.9元购买,源码中有测试视频的下载链接。
代码下载链接:https://download.csdn.net/download/wenhao_ir/85475974

示例代码的运行效果截图如下:
在这里插入图片描述
因为是对视频的处理,所以博主还录了个视频供大家观看效果,视频观看和下载地址如下:
链接:https://pan.baidu.com/s/1uvkem9Fo67btXNBK6320WA?pwd=oxzu
提取码:oxzu

这里还需要对代码中用到的函数createBackgroundSubtractorKNN()进行一点说明。
函数createBackgroundSubtractorKNN()用于构建类BackgroundSubtractorKNN的实例化对象,并返回对象指针。
函数createBackgroundSubtractorKNN()的原型如下:

Ptr<BackgroundSubtractorKNN> cv::createBackgroundSubtractorKNN(int history = 500,
																double 	dist2Threshold = 400.0,
																bool 	detectShadows = true)	

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

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

猜你喜欢

转载自blog.csdn.net/wenhao_ir/article/details/125007017
今日推荐