草庐IT

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

昊虹AI笔记 2023-04-03 原文

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中有哪些视频背景/前景分割(背景建模/前景提取)算法的类,它们各自的算法原理、特点是什么,并附示例代码

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

  1. ruby-on-rails - 使用 Sublime Text 3 突出显示 HTML 背景语法中的 ERB? - 2

    所以我在关注Railscast,我注意到在html.erb文件中,ruby代码有一个微弱的背景高亮效果,以区别于其他代码HTML文档。我知道Ryan使用TextMate。我正在使用SublimeText3。我怎样才能达到同样的效果?谢谢! 最佳答案 为SublimeText安装ERB包。假设您安装了SublimeText包管理器*,只需点击cmd+shift+P即可获得命令菜单,然后键入installpackage并选择PackageControl:InstallPackage获取包管理器菜单。在该菜单中,键入ERB并在看到包时选择

  2. ruby-on-rails - 使用 Rmagick 或 ImageMagick 在背景上放置标题 - 2

    我有一张背景图片,我想在其中添加一个文本框。我想弄清楚如何将标题放置在其顶部的正确位置。(我使用标题是因为我需要自动换行功能)。现在,我只能让文本显示在左上角,但我需要能够手动定位它的开始位置。require'RMagick'require'Pry'includeMagicktext="Loremipsumdolorsitamet"img=ImageList.new('template001.jpg')img 最佳答案 这是使用convert的ImageMagick命令行的答案。如果你想在Rmagick中使用这个方法,你必须自己移植

  3. Vscode+Cmake配置并运行opencv环境(Windows和Ubuntu大同小异) - 2

    之前在培训新生的时候,windows环境下配置opencv环境一直教的都是网上主流的vsstudio配置属性表,但是这个似乎对新生来说难度略高(虽然个人觉得完全是他们自己的问题),加之暑假之后对cmake实在是爱不释手,且这样配置确实十分简单(其实都不需要配置),故斗胆妄言vscode下配置CV之法。其实极为简单,图比较多所以很长。如果你看此文还配不好,你应该思考一下是不是自己的问题。闲话少说,直接开始。0.CMkae简介有的人到大二了都不知道cmake是什么,我不说是谁。CMake是一个开源免费并且跨平台的构建工具,可以用简单的语句来描述所有平台的编译过程。它能够根据当前所在平台输出对应的m

  4. 动漫制作技巧如何制作动漫视频 - 2

    动漫制作技巧是很多新人想了解的问题,今天小编就来解答与大家分享一下动漫制作流程,为了帮助有兴趣的同学理解,大多数人会选择动漫培训机构,那么今天小编就带大家来看看动漫制作要掌握哪些技巧?一、动漫作品首先完成草图设计和原型制作。设计草图要有目的、有对象、有步骤、要形象、要简单、符合实际。设计图要一致性,以保证制作的顺利进行。二、原型制作是根据设计图纸和制作材料,可以是手绘也可以是3d软件创建。在此步骤中,要注意的问题是色彩和平面布局。三、动漫制作制作完成后,加工成型。完成不同的表现形式后,就要对设计稿进行加工处理,使加工的难易度降低,并得到一些基本准确的概念,以便于后续的大样、准确的尺寸制定。四、

  5. python ffmpeg 使用 pyav 转换 一组图像 到 视频 - 2

    2022/8/4更新支持加入水印水印必须包含透明图像,并且水印图像大小要等于原图像的大小pythonconvert_image_to_video.py-f30-mwatermark.pngim_dirout.mkv2022/6/21更新让命令行参数更加易用新的命令行使用方法pythonconvert_image_to_video.py-f30im_dirout.mkvFFMPEG命令行转换一组JPG图像到视频时,是将这组图像视为MJPG流。我需要转换一组PNG图像到视频,FFMPEG就不认了。pyav内置了ffmpeg库,不需要系统带有ffmpeg工具因此我使用ffmpeg的python包装p

  6. TimeSformer:抛弃CNN的Transformer视频理解框架 - 2

    Transformers开始在视频识别领域的“猪突猛进”,各种改进和魔改层出不穷。由此作者将开启VideoTransformer系列的讲解,本篇主要介绍了FBAI团队的TimeSformer,这也是第一篇使用纯Transformer结构在视频识别上的文章。如果觉得有用,就请点赞、收藏、关注!paper:https://arxiv.org/abs/2102.05095code(offical):https://github.com/facebookresearch/TimeSformeraccept:ICML2021author:FacebookAI一、前言Transformers(VIT)在图

  7. ruby-on-rails - Rails - 从命名路由中提取 HTTP 动词 - 2

    Rails中有没有一种方法可以提取与路由关联的HTTP动词?例如,给定这样的路线:将“users”匹配到:“users#show”,通过:[:get,:post]我能实现这样的目标吗?users_path.respond_to?(:get)(显然#respond_to不是正确的方法)我最接近的是通过执行以下操作,但它似乎并不令人满意。Rails.application.routes.routes.named_routes["users"].constraints[:request_method]#=>/^GET$/对于上下文,我有一个设置cookie然后执行redirect_to:ba

  8. ruby-on-rails - Ruby - 如何从 ruby​​ 上的 .pfx 文件中提取公钥、rsa 私钥和 CA key - 2

    我有一个.pfx格式的证书,我需要使用ruby​​提取公共(public)、私有(private)和CA证书。使用shell我可以这样做:#ExtractPublicKey(askforpassword)opensslpkcs12-infile.pfx-outfile_public.pem-clcerts-nokeys#ExtractCertificateAuthorityKey(askforpassword)opensslpkcs12-infile.pfx-outfile_ca.pem-cacerts-nokeys#ExtractPrivateKey(askforpassword)o

  9. ruby - 如何在ruby中提取方括号内的内容 - 2

    我正在尝试提取方括号内的内容。到目前为止,我一直在使用它,它有效,但我想知道我是否可以直接在正则表达式中使用某些东西,而不是使用这个删除功能。a="Thisissuchagreatday[coolawesome]"a[/\[.*?\]/].delete('[]')#=>"coolawesome" 最佳答案 差不多。a="Thisissuchagreatday[coolawesome]"a[/\[(.*?)\]/,1]#=>"coolawesome"a[/(?"coolawesome"第一个依赖于提取组而不是完全匹配;第二个利用前瞻和

  10. ruby - 如何更改此正则表达式以从未指定 v 参数的 Youtube URL 获取 Youtube 视频 ID? - 2

    目前我正在使用这个正则表达式从YoutubeURL中提取视频ID:url.match(/v=([^&]*)/)[1]我怎样才能改变它,以便它也可以从这个没有v参数的YoutubeURL获取视频ID:http://www.youtube.com/user/SHAYTARDS#p/u/9/Xc81AajGUMU感谢阅读。编辑:我正在使用ruby​​1.8.7 最佳答案 对于Ruby1.8.7,这就可以了。url_1='http://www.youtube.com/watch?v=8WVTOUh53QY&feature=feedf'url

随机推荐