核心代码关于vibe算法的有用部分
运动检测ViBe算法python实现代码
运动检测ViBe算法python实现代码运动物体检测⼀般分为背景建模和运动物体分析两步。
即构建不包含运动物体的背景模型。
然后将新的视频帧和背景模型对⽐,找出其中的运动物体。
⽬前⽐较好的背景建模算法有两种:1)⽂章(Zivkovic Z. (2004) Improved adaptive Gausianmixture model for backgroundsubtraction, Proceedings of ICPR 2004, August 23-26, Cambridge, UK.)提出的⾼斯混合模型法。
在此算法中,背景的每⼀个像素都被拟合到⼀个⾼斯混合模型。
对于新的图⽚,只需要判断每个像素是否服从这个⾼斯混合模型就可以判断出这个像素是背景还是前景。
但混合⾼斯算法的缺点是计算量相对⽐较⼤,速度偏慢,对光照敏感。
2)⽂章(ViBe: A universal backgroundsubtraction algorithm for video sequences.)提出的ViBe算法。
该算法速度⾮常快,计算量⽐较⼩,⽽且对噪声有⼀定的鲁棒性,检测效果不错。
由于最近在做⼀些跟踪检查的研究,就⽤到了ViBe算法,根据⽹上的c++版本编写了这个python版的算法,在这分享给⼤家。
class ViBe:'''''classdocs'''__defaultNbSamples = 20 #每个像素点的样本个数__defaultReqMatches = 2 #min指数__defaultRadius = 20; #Sqthere半径__defaultSubsamplingFactor = 16#⼦采样概率__BG = 0 #背景像素__FG = 255 #前景像素__c_xoff=[-1,0,1,-1,1,-1,0,1,0] #x的邻居点 len=9__c_yoff=[-1,0,1,-1,1,-1,0,1,0] #y的邻居点 len=9__samples=[] #保存每个像素点的样本值,len defaultNbSamples+1__Height = 0__Width = 0def __init__(self, grayFrame):'''''Constructor'''self.__Height = grayFrame.shape[0]self.__Width = grayFrame.shape[1]for i in range(self.__defaultNbSamples+1):self.__samples.insert(i,np.zeros((grayFrame.shape[0],grayFrame.shape[1]),dtype=grayFrame.dtype));self.__init_params(grayFrame)def __init_params(self,grayFrame):#记录随机⽣成的⾏(r) 和列(c)rand=0r=0c=0#对每个像素样本进⾏初始化for y in range(self.__Height):for x in range(self.__Width):for k in range(self.__defaultNbSamples):#随机获取像素样本值rand=random.randint(0,8)r=y+self.__c_yoff[rand]if r<0:r=0if r>=self.__Height:r=self.__Height-1 #⾏c=x+self.__c_xoff[rand]if c<0:c=0if c>=self.__Width:c=self.__Width-1 #列#存储像素样本值self.__samples[k][y,x] = grayFrame[r,c]self.__samples[self.__defaultNbSamples][y,x] = 0def update(self,grayFrame,frameNo):foreground = np.zeros((self.__Height,self.__Width),dtype=np.uint8)for y in range(self.__Height): #Heightfor x in range(self.__Width): #Width#⽤于判断⼀个点是否是背景点,index记录已⽐较的样本个数,count表⽰匹配的样本个数count=0;index=0;dist=0.0;while (count<self.__defaultReqMatches) and (index<self.__defaultNbSamples):dist= float(grayFrame[y,x]) - float(self.__samples[index][y,x]);if dist<0: dist=-distif dist<self.__defaultRadius: count = count+1index = index+1if count>=self.__defaultReqMatches:#判断为背景像素,只有背景点才能被⽤来传播和更新存储样本值self.__samples[self.__defaultNbSamples][y,x]=0foreground[y,x] = self.__BGrand=random.randint(0,self.__defaultSubsamplingFactor)if rand==0:rand=random.randint(0,self.__defaultNbSamples)self.__samples[rand][y,x]=grayFrame[y,x]rand=random.randint(0,self.__defaultSubsamplingFactor)if rand==0:rand=random.randint(0,8)yN=y+self.__c_yoff[rand]if yN<0: yN=0if yN>=self.__Height: yN=self.__Height-1rand=random.randint(0,8)xN=x+self.__c_xoff[rand]if xN<0: xN=0if xN>=self.__Width: xN=self.__Width-1rand=random.randint(0,self.__defaultNbSamples)self.__samples[rand][yN,xN]=grayFrame[y,x]else:#判断为前景像素foreground[y,x] = self.__FG;self.__samples[self.__defaultNbSamples][y,x] += 1if self.__samples[self.__defaultNbSamples][y,x]>50:rand=random.randint(0,self.__defaultNbSamples)if rand==0:rand=random.randint(0,self.__defaultNbSamples)self.__samples[rand][y,x]=grayFrame[y,x]return foreground我做的鱼的跟踪效果图以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。
V i B e 算 法 原 理 详 解
目标检测之vibe---ViBe(Visual Background extractor)背景建模或前景检测ViBe算法:ViBe - a powerful technique for background detection and subtraction in video sequencesViBe是一种像素级视频背景建模或前景检测的算法,效果优于所熟知的几种算法,对硬件内存占用也少。
Windows and Linux users: a benchmarking program to evaluate the time needed by ViBe on your platform and on your own sequences!?Download an archive?zip archive [15 MB]?to evaluate the time needed by ViBe on your platform (Windows or Linux [Wine]), and on your own sequences.A program for Windows and Linux.?Download an archive?zip archive [16 MB]?to use ViBe on Windows (or under?Wine?in Linux).The program allows you to: (1) save the result for your own images, (2) change the few parameters of ViBe to experiment with, and (3) reproduce our results.Linux: link a C-C++ object file to your own code.?We provide the object (compiled) code of ViBe for non-commercial applications. Under Linux, download the32 bits zip file, or the?64 bits zip file. Details on?this page.当然,在使用ViBe算法时应该遵循算法官网的License。
[转]前景检测算法--ViBe算法
[转]前景检测算法--ViBe算法原⽂:转⾃:因为监控发展的需求,⽬前前景检测的研究还是很多的,也出现了很多新的⽅法和思路。
个⼈了解的⼤概概括为以下⼀些:帧差、背景减除(GMM、CodeBook、 SOBS、 SACON、 VIBE、 W4、多帧平均……)、光流(稀疏光流、稠密光流)、运动竞争(Motion Competition)、运动模版(运动历史图像)、时间熵……等等。
如果加上他们的改进版,那就是很⼤的⼀个家族了。
对于上⼀些⽅法的⼀点简单的对⽐分析可以参考下:⾄于哪个最好,看使⽤环境吧,各有千秋,有⼀些适⽤的情况更多,有⼀些在某些情况下表现更好。
这些都需要针对⾃⼰的使⽤情况作测试确定的。
呵呵。
推荐⼀个⽜逼的库:⾥⾯包含了各种背景减除的⽅法,可以让⾃⼰少做很多⼒⽓活。
还有王先荣博客上存在不少的分析:下⾯的博客上转载王先荣的上⾯⼏篇,然后加上⾃⼰分析了两篇:本⽂主要关注其中的⼀种背景减除⽅法:ViBe。
stellar0的博客上对ViBe进⾏了分析,我这⾥就不再啰嗦了,具体的理论可以参考:ViBe是⼀种像素级的背景建模、前景检测算法,该算法主要不同之处是背景模型的更新策略,随机选择需要替换的像素的样本,随机选择邻域像素进⾏更新。
在⽆法确定像素变化的模型时,随机的更新策略,在⼀定程度上可以模拟像素变化的不确定性。
背景模型的初始化 初始化是建⽴背景模型的过程,⼀般的检测算法需要⼀定长度的视频序列学习完成,影响了检测的实时性,⽽且当视频画⾯突然变化时,重新学习背景模型需要较长时间。
ViBe算法主要是利⽤单帧视频序列初始化背景模型,对于⼀个像素点,结合相邻像素点拥有相近像素值的空间分布特性,随机的选择它的邻域点的像素值作为它的模型样本值。
优点:不仅减少了背景模型建⽴的过程,还可以处理背景突然变化的情况,当检测到背景突然变化明显时,只需要舍弃原始的模型,重新利⽤变化后的⾸帧图像建⽴背景模型。
缺点:由于可能采⽤了运动物体的像素初始化样本集,容易引⼊拖影(Ghost)区域。
ViBe介绍
ViBe: A Universal Background Subtraction Algorithm for Video Sequences(一个视频序列通用的背景减法算法)ViBe是一种像素级视频背景建模或前景检测的算法,效果优于所熟知的几种算法,对硬件内存占用也少。
算法的主要优势:内存占用少,一个像素需要作一次比较,占用一个字节的内存;无参数法;可直接应用在产品中,软硬件兼容性好;性能优于混合高斯,参数化方法,SACON等;像素级算法,视频处理中的预处理关键步骤;背景模型及时初始化;具有较好的抗噪能力。
背景差方法实现运动物体检测面临的挑战主要有:必须适应环境的变化(比如光照的变化造成图像色度的变化);相机抖动引起画面的抖动(比如手持相机拍照时候的移动);图像中密集出现的物体(比如树叶或树干等密集出现的物体,要正确的检测出来);必须能够正确的检测出背景物体的改变(比如新停下的车必须及时的归为背景物体,而有静止开始移动的物体也需要及时的检测出来)。
物体检测中往往会出现Ghost区域,Ghost区域也就是指当一个原本静止的物体开始运动,背静差检测算法可能会将原来该物体所覆盖的区域错误的检测为运动的,这块区域就成为Ghost,当然原来运动的物体变为静止的也会引入Ghost区域,Ghost区域在检测中必须被尽快的消除。
一个Ghost区域的实例如图Fig.1,在图中可以发现相比于原图,检测的结果中错误的多出现了两个人的形状,这就是Ghost。
ViBe算法详解:ViBe检测方法ViBe是本篇论文中所提出的一个检测方法,相比于其他方法它有很多的不同和优点。
具体的思想就是为每个像素点存储了一个样本集,样本集中采样值就是该像素点过去的像素值和其邻居点的像素值,然后将每一个新的像素值和样本集进行比较来判断是否属于背景点。
该模型主要包括三个方面:模型的工作原理;模型的初始化方法;模型的更新策略。
模型的工作原理背景物体就是指静止的或是非常缓慢的移动的物体,而前景物体就对应移动的物体。
E n i g m a 算 法 详 解
成为专业程序员路上用到的各种优秀资料、神器及框架本文是鄙人工作这几年随手收集整理的一些自认为还不错的资料,成长的道理上需要积累,这么长时间了,是时候放出来分享下了,或许能帮助到你。
欢迎点赞,让更多人看到,让福利普照。
因为本文以后不会更新,但项目依旧会更新。
所以,更好的做法是,请到GitHub上Star:stanzhai-be-a-professional-programmer成为一名专业程序员的道路上,需要坚持练习、学习与积累,技术方面既要有一定的广度,更要有自己的深度。
笔者作为一位tool mad,将工作以来用到的各种优秀资料、神器及框架整理在此,毕竟好记性不如烂键盘,此项目可以作为自己的不时之需。
本人喜欢折腾,记录的东西也比较杂,各方面都会有一些,内容按重要等级排序,大家各取所需。
这里的东西会持续积累下去,欢迎Star,也欢迎发PR给我。
技术站点必看书籍大牛博客GitHub篇工具篇平台工具常用工具第三方服务爬虫相关(好玩的工具)安全相关Web服务器性能-压力测试工具-负载均衡器大数据处理-数据分析-分布式工具Web前端语言篇C游戏开发相关日志聚合,分布式日志收集RTP,实时传输协议与音视频技术站点在线学习:Coursera、edX、Udacity?-way to explore国内老牌技术社区:OSChina、博客园、CSDN、51CTO 免费的it电子书:ITeBooks - Free Download - Big Library在线学习:UdemyCrowd-sourced code mentorship. and Practicecoding with fun programming challenges - CodinGameDevStore:开发者服务商店MSDN:微软相关的官方技术集中地,主要是文档类必看书籍SICP(Structureand Interpretation of Computer Programs)深入理解计算机系统代码大全2人件人月神话软件随想录算法导论(麻省理工学院出版社)离散数学及其应用设计模式编程之美黑客与画家编程珠玑The Little SchemerSimply Scheme_Introducing_Computer_ScienceC++ PrimeEffective C++TCP-IP详解Unix 编程艺术技术的本质软件随想录计算机程序设计艺术职业篇:程序员的自我修养,程序员修炼之道,高效能程序员的修炼《精神分析引论》弗洛伊德《失控》《科技想要什么》《技术元素》凯文凯利程序开发心理学天地一沙鸥搞定:无压力工作的艺术大牛博客云风(游戏界大牛): 云风的Tian (binghe)R大【干货满满】RednaxelaFX写的文章-回答的导航帖陈皓-左耳朵耗子:酷壳 - CoolShellJeff Atwood(国外知名博主): CodingHorror阮一峰(黑客与画家译者,Web):RuanYiFeng’s Personal Website廖雪峰(他的Python、Git教-程不少人都看过):HomeGitHub篇Awesome:这是个Awesome合集,常见的资料这里面都能找到Awesome2:类似第一个Awesome杂七杂八、有用没用的Awesome合集非常不错的语言类学习资料集合:Awesomenessawesome-ios-uiawesome-android-uiAwesome-MaterialDesi gnawesome-public-datasetsawesome-AppSec(系统安全)awesome-datascience书籍资料free-programming-books中文版免费的编程中文书籍索引《程序员编程艺术—面试和算法心得》GoBooksPapersLearning)深入学习(Deep Learning)资料Docker资料合集学习使用StromHadoopInternalsSparkInternals大数据时代的数据分析与数据挖掘in DatabasesDataScience blogs日志:每个软件工程师都应该知道的有关实时数据的统一概念AndroidCode PathAndroidLearn NotesPHP类库框架,资料集合优秀项目Design开源项目Android开源项目分类汇总前端 Node.jsGuide的中文分支Angular2学习资料AngularJS应用的最佳实践和风格指南React-Native学习指南七天学会NodeJSnode.js中文资料导航Nodejs学习路线图如何学习nodejs工作,工具系统管理员工具集合ProGitNginx开发从入门到精通Google全球 IP 地址库收集整理远程工作相关的资料Colorschemes for hackers游戏开发工具集,MagicTools开发者工具箱, free-for-devGitHub秘籍Git风格指南Bast-App平台工具常用工具Mac下的神兵利器asciinema:- 免费在线作图,实时协作Origami: 次世代交互设计神器百度脑图:百度脑图第三方服务DnsPod:一个不错的只能DNS服务解析提供商DigitalOcean:海外的云主机提供商,价格便宜,磁盘是SSD的,用过一段时间整体上还可以,不过毕竟是海外的,网速比较慢。
基于改进VIBE算法的前景检测
基于改进VIBE算法的前景检测作者:徐文瀚程石磊来源:《电子技术与软件工程》2017年第16期摘要本文针对智能视频监控中的前景检测功能展开研究工作,研究内容主要包括核心的前景检测算法。
本文首先研究图像预、后处理对系统性能的提升。
在前景检测方面,本文对比多种主流算法,选择ViBe(Visual Background extractor)算法进行深入学习研究,从闪烁点判断、自适应阈值处理等方面进行了改进。
【关键词】改进VIBE算法前景检测 ViBe算法1 引言二十一世纪,世界范围内社会生产力和科学技术高速发展,而由此带来的安全隐患以及日益增长的人力成本需要无人值守的智能视频入侵检测技术的出现。
视频监控入侵检测系统能够在输入的一系列视频图像序列中分离出运动前景和场景背景,从而实现对场景中运动目标的检测,若运动目标进入禁区,则发出警报。
高实时性的检测系统能及时检测到入侵行为,替代监控人员的大部分工作,避免了监控人员因过度疲劳或注意力分散造成的漏报、误报等现象。
2 ViBe算法ViBe算法(Visual Background extractor)假设邻域像素具有相似的时空分布。
基于这个假设,算法可以选择像素点的空间邻域的像素值来作为该像素的背景模型样本。
换句话说,第一帧时,算法在像素点的邻域内随机取固定个数的像素点来组成背景样本集合。
这就实现了单帧初始化的实现,即只需一帧图像即可实现模型的初始化,这对于入侵检测的性能提升是有重大意义的。
经过大量实验,单帧初始化的策略被证明是成功的。
但是它也有缺陷,若初始帧中有运动物体,算法会持续地在运动物体初始的位置检测到一个前景,即使运动物体已经离开那个位置,即产生了鬼影。
但是随着背景模型的更新,鬼影会在一段时间后淡化消失,此问题将被大幅度改善。
设V(x)代表图像中像素x的欧式颜色距离;Vi代表索引i的背景样本值,每一个像素点的背景模型表示为一个有N个背景样本值的集合,表示为:。
一种自适应运动目标检测算法及其应用
2021年2月第2期Vol. 42 No. 2 2021小型微型计算机系统Journal of Chinese Computer Systems一种自适应运动目标检测算法及其应用李善超,车国霖,张果,杨晓洪(昆明理工大学信息工程与自动化学院,昆明650500)E-mail :991186428@ qq. com摘要:针对ViBe 算法在动态背景下存在鬼影消除时间长、算法适应性差、前景检测噪声多的问题,本文提出一种基于ViBe 算法框架的改进算法.该算法釆用鬼影检测法标记第1帧中的鬼影区域,并向位于鬼影区域的背景模型中强制引入背景样本,从而快速抑制鬼影;在像素分类过程中,引入自适应分类阈值,解决全局阈值易受动态噪声干扰的问题;在背景模型更新中,根 据像素分类的匹配值来动态决定更新因子,提高算法适应场景变化的能力.定性与定量的对比实验结果表明,本文算法相较于ViBe 算法能够有效地检测动态背景下的运动目标,应用于河流漂浮物检测场景中也有较好的效果.关键词:ViBe ;动态背景;运动目标检测;自适应方法;河流漂浮物检测中图分类号:TP391文献标识码:A 文章编号:1000-1220(2021)02-0381-06Adaptive Moving Target Detection Algorithm and Its ApplicationLI Shan-chao ,CHE Guo-lin ,ZHANG Guo,YANG Xiao-hong(Faculty of Information Engineering and Automation ,Kunming University of Science and Technology ,Kunming 650500,China)Abstract : Aiming at the problem that ViBe algorithm has long ghost elimination time , poor algorithm adaptability and high foreground detection noise in dynamic background , this paper proposes an improved algorithm based on ViBe algorithm framework. The algorithmuses the ghost detection method to mark the ghost region in the first frame , and forces the background sample into the background model in the ghost region to quickly suppress the ghost. In the pixel classification process , the adaptive classification threshold is intro ・ duced to solve the problem that the global threshold is susceptible by dynamic noise interference. In the background model update , theupdate factor is dynamically determined according to the matching number of the pixel classification to improve the algorithm's abilityto adapt to scene changes. The comparison experimental results of qualitative and quantitative shows that the algorithm in this paper can effectively detect moving targets in dynamic background compared to the ViBe algorithm , and it also has a better effect in the de tection of river floating objects.Key words : ViBe ; dynamic background ; moving target detection ; adaptive method ; river floating debris1引言运动目标检测在智能视频监控的应用中扮演着重要的角 色,是计算机视觉领域的一个研究热点⑴•运动目标检测的 实质是在视频序列中定位运动中的目标,而准确的前景检测 是目标分类、目标跟踪和行为识别研究的重要基石⑺叫运动目标检测算法按类别可分为帧差法⑴、光流法⑷、背景建模 法"向3种.帧差法原理简单且易于设计,然而其检测结果存 在空洞和鬼影的问题.光流法虽然精度高,但由于其计算量大,不适用于对实时性有较高要求的场景.背景建模法是在初 始化过程中构建出由背景样本组成的模型,并将当前帧与背 景模型进行差分,从而对像素进行分类,最后得到运动目标.其具有精度高实时性好的特点.背景模型的准确性决定了背景建模法的检测精度,主要影响检测精度的因素有鬼影问题、 动态背景、噪声干扰等⑴.高斯混合模型(GMM ,Gaussian mixture model)[8]是运动目标检测算法中最为经典的算法,其本质是基于像素样本统 计信息的背景建模方法,能够对复杂背景进行准确建模,然而 其计算复杂度较高GMG 算法切是统计背景模型的概率,采 用贝叶斯逐像素分割,但在动态场景中其检测精确度较低.核 密度估计算法(KDE,Kernel Density Estimation)[10]是一种非 参数背景建模方法,其通过大量的背景样本估算背景像素的概率密度函数,从而根据像素背景概率来分类像素,然而其内 存占用与计算复杂度都较高.Bamich 等人⑴•切于2009年提出一种非参数化视频背景提取算法(ViBe , Visual BackgroundExtractor),该算法是为每个像素设置一个样本集,并与新帧像素进行阈值比较,从而对像素进行分类,其具有实时性好、鲁棒性高和易于集成于嵌入式设备的特点.然而ViBe 算法仍 存在一些不足,限制了其在动态场景中的应用.例如:1)当初 始化图像中存在运动中的目标时,ViBe 算法会在后续帧中检 测到鬼影,降低了算法的检测精度且鬼影消除时间长;2)ViBe 算法在动态场景中检测精度低,容易受动态噪声干扰;3) ViBe 算法的背景模型更新策略无法适应背景动态的变化.针对ViBe 算法存在的问题,本文提出一种自适应运动目收稿日^:2020-03-06 收修改稿日期:202045-11基金项目:国家重点研发计划项目(2017YFB0306405)资助;国家自然科学基金项目 (61364008)资助.作者简介:李善超,男,1994年生,硕士研究生,研究方向为数字图像处理;车国霖,男,1975年生,硕士,副教授,研究方向为 智能控制;张 果,男,1976年生,博士,副教授,研究方向为智能測控;杨晓洪,女,1964年生,高级工程师,研究方向为综合自动化.382小型微型计算机系统2021年标检测算法.本文将从以下3个方面对ViBe算法进行改进.1)采用鬼影检测法标记鬼影区域并强制引入背景样本,加速鬼影的抑制;2)采用自适应匹配阈值的方法进行像素分类,提高算法抗干扰的能力;3)根据像素分类的匹配值动态调整更新因子,提高算法适应场景变化的能力.本文采用CDNET 数据集中dynamicBackground视频类中的5个视频序列和3组河流漂浮物的视频序列进行研究,以本文算法和其他5种算法为例,定性、定量对实验结果做出质量评价和分析.研究结果表明,本文算法相较于ViBe算法在召回率、精确率和F 度量值方面均有提高,错误分类比更低,达到了预期的目标.2ViBe算法原理ViBe算法是基于样本随机聚类的背景建模算法,具有运算效率高、易于设计、易于集成嵌入设备的特点,能够实现快速的背景建模和运动目标检测.算法的步骤包括背景模型初始化、像素分类过程和背景模型更新.2.1背景模型初始化1)背景模型定义:ViBe算法的背景模型是由N个背景样本组成的,v(x)是像素x的像素值,则背景模型M(x)定义如公式(1)所示:=|Vj(x),v2(x),v N(x)|(1)2)背景模型初始化:ViBe算法利用视频序列第1帧建立背景模型,从第2帧开始算法就可以有效地检测运动目标.背景模型初始化是在像素x的8邻域Nc(x)中选取一个像素值作为背景样本,重复N次,如公式(2)所示:(N g(x)=Ui,¾,--,¾IJ(2)〔M(x)=1v(ylyeN c(x))I3)随机选取策略:背景建模时,背景样本始终采用随机选取邻域像素的策略,以使背景模型更加稳定可靠.2.2像素分类过程ViBe算法采用计算欧氏距离来进行像素的分类. S”(v(x))是以像素值v(x)作中心,匹配阈值R为半径的二维欧氏空间,若v(x))与M(x)的交集H{•}中元素个数不小于最小匹配数则认为像素x是背景像素,如公式(3)所示:H{Sx(v(x))n I V,(x),v2(x),—,v w(x)I I(3) 2.3背景模型更新1)保守更新机制:ViBe算法通过保守更新机制进行背景模型更新,即如果像素被分类为背景像素,则以i/e(e是更新因子)的概率替代背景模型中的任一样本.假设时间是连续且选择过程是无记忆性的,在任一dt时间后,背景模型的样本随时间变化的概率如公式(4)所示:P(t,t+dt)=e-1"(^)d,(4)公式(4)表明,背景模型样本值的预期剩余寿命都呈指数衰减,背景模型的样本更新与时间无关.2)随机更新机制:ViBe算法通过随机更新机制进行样本替换,使得每个样本的存在时间成平滑指数衰减,提高了算法适应背景变化的能力,避免了旧像素长期不更新带来的模型劣化的问题.3)空间传播机制:ViBe算法也将背景像素引入邻域的背景模型中,保证了邻域像素空间的一致性.例如,用背景像素替换任一邻域(x)中的任一样本.ViBe算法首次将随机聚类技术应用于运动目标检测中,使得算法在背景模型初始化、像素分类过程、背景模型更新3个方面都比较简单,保证了算法的实时性,因此ViBe算法被广泛应用于现实生活中3提出的改进算法ViBe算法采用随机采样、非参数化和无记忆的更新策略,使得其具有较好的性能,但其在动态场景下仍然存在不能快速抑制鬼影、难以消除动态噪声以及无法适应场景动态变化的问题,本文将从以下3个方面对ViBe算法进行改进.3.1鬼影检测ViBe算法利用第1帧建立背景模型,但也不可避免的将第1帧中存在的运动目标前景像素引入到背景模型中,导致鬼影问题和彫响算法的检测精度.假设背景模型M(x)是由第1帧中的前景像素样本f(x)组成的,当运动目标离开时,ZU)不在背景像素值b(x)的S”(b(x))圆内,背景像素被错误的分类为前景,如公式(5)所示,则在第1帧中运动目标所在的区域就会出现虚拟的前景(鬼影).rM(x)=|/;(x)J2(x),―J N(x)}(s&(x))nM(x)=0本文针对这一问题,应用鬼影检测法标记出第1帧中的鬼影区域,并向位于鬼影区域的背景模型中强制引入背景样本,减少其中前景像素的数量,从而快速抑制鬼影.鬼影检测法借鉴了帧间差分法并对其进行改进,其原理是提取视频序列的前3帧图像,第1帧图像分别与后两帧图像做差分运算,设定差分阈值并对差分后的图像进行二值化分类,将二值化结果做逻辑或操作和形态学操作,即得到标记有第1帧运动目标的鬼影模板Ghost(x),在鬼影模板Ghost(x)中大于0的位置是第1帧中鬼影区域的.具体定义如公式(6)、公式(7)和公式(8)所示:if I厶(x)-厶+|(兀)I>Tif\IM一人+|(x)lwTM)={o-/“2(x)IWTGhost(x)=£>i(x)or D2(x)(6)(7)(8)式中:D(x)为二值化图像,人(x)为第R帧输入图像,一般A=1为图像差分阈值,。
基于CUDA加速的Vibe前景检测算法
2017年第12期 信息通信2017(总第 180 期)INFORMATION & COMMUNICATIONS(Sum . N o 180)基于CU DA 加速的Vibe 前景检测算法魏星,孟丽珍,张富生(三峡大学湖北省水电工程智能视觉检测重点实验室,湖北宜昌443002)摘要:为了更好地满足视频跟踪领域的实时性问题,文章提出一种基于CU D A 加速改进后的Vibe 前景检测算法。
首先 对Vibe 算法做前景分析,并对该算法进行G PU 并行优化处理。
然后,对优化后的算法与原始的Vibe 算法,在调节相应 的参数的同时,统计对比分析了漏检率和误检率等性能上的差异。
实验结果表明,在相同参数的情况下,优化后的算法 较原始的算法在速率上提高了近2-3倍。
关键词:Vibe ; GPU 并行;CUDA ;前景检测中图分类号:TP 393文献标识码:A文章编号= 1673-1131(2017)12-0010-03Vibe foreground detection algorithm based on CUDA accelerationWei Xing, Memg LiZheng,Zhang FuSheng(Huibei Key Laboratory of Intelligent Vision Based Monitoring for Hydroelectric Engineeing ,China Three Gorges University,Yichang 443002,China )Abstract: in order to better meet the real-time problems in video tracking field , this paper proposes an accelerated Vibe fore -ground detection algorithm based on CUDA , Firstly,the foreground of V ibe algorithm is analyzed,and the algorithm is optimi - zed by GPU parallel processing . Then , after optimizing the algorithm and the original Vibe algorithm , we adjust the correspon ding parameters at the same time , compare and analyze the performance differences of t ime consuming , missed detection rate and false detection rate . The experiment results show that the optimized algoritto is nearly 2-3 times faster than the orig ^ algorithm under the same parameters .Key words: Vibe ; GPU parallel ; CUDA ; foreground detection〇引言目前视频监控领域运用的目标检测方法主要有帧差法、 混合高斯法以及光流法[1]等。
融合时域信息的自适应ViBe算法
2019年3月第40卷第3期计算机工程与设计COM P UTER ENG I NEER I NG AND DE S I GNMar.2019Vol.40 No.3融合时域信息的自适应ViBe算法瞿中,刘帅,刘妍(重庆邮电大学计算机科学与技术学院,重庆400065)摘要:针对V i B e算法采用第一帧初始化背景模型没有考虑像素值在时域上变化的情况,提出一种融合时域信息的自适 应V i B e算法。
提出一个历史像素值队列反映像素值在时域上的变化情况;提出一种结合自适应思想的阈值分割方法对前 景像素和背景像素进行分割,使ViBe算法适应场景中不同动态区域;提出一种自适应的更新因子,通过自适应更新机制 使背景模型能够在不同背景下更加可靠。
实验结果表明,改进后的V B e算法能够快速适应动态背景!使检测结果更为准确。
关键词$V_e目标检测;自适应阈值;背景模型&动态更新中图法分类号:TP391.41 文献标识号:A文章编号$1000-7024 (2019)03-0782-06d o i: 10.16208/.. issnl000-7024. 2019. 03. 031Sel--adaptive ViBe algorithm with time domain informationQU Zhong&LIU Shuai&LIU Yan(College of Computer Science and Technology,Chongqing University of Posts andTelecommunications,Chongqing400065,China)A b s tra c t:The initialization of background model in the first frame neglects the pixel values change the problem,a self-adaptive ViBe algorithm with time domain information was proposed A historical pixel value queue to reflect the pixel changes in t he time domain was proposed.A segmentation method based on the self-adaptive idea was proposed,which ensured ViBe adapting to different dynamic regions in scene.A self-adaptive updating factor was proposed,which made the background modll reliable in different backgrounds.Experimentll results show that the improv dynamic background and make the detection results more accurate.K e y w o rd s:ViBe;object detection;sel--adaptive threshold;background model;dynamic update/引言目前常用的运动目标检测[1,2]方法主要有:光流法[3]、帧差法[4]和背景减除法[5]。
改进的车流量估计ViBe算法
ViBe算法是一种非参数化背景建模方法[7],内存占用少, 计算效率高,易于实现,检测结果优于光流法和帧差法等方法。 算法的原理是:
a)背景模 型 初 始 化。 采 用 单 帧 图 像 初 始 化 背 景 模 型,对 像素 x随机选取其邻域内像素值填充样本模型,M(x)={x1, x2,…,xn},n为样本集容量,xi(1≤i≤n)为 8邻域像素。
本文对于 ViBe方法存在的问题进行了深入分析,提出了 经过改进的 ViBe算法,从以下三个方面对其进行改善:a)采用 多帧图像的平均背景建模方法初始化背景模型,加速鬼影目标
的消除;b)若某区域连续 n帧被判断为前景,比较该区域和邻 域背景直方图相似度,从而检测出静止目标;c)对前景车辆建 立阴影检测器模型,消除车辆阴影,使车辆外形更加清晰。实 验结果表明,本文算法与原始 ViBe算法在准确率和实时效果 方面都有所增加,能够较准确得出道路车流量情况。
第 35卷第 10期ຫໍສະໝຸດ 2018年 10月 计算机应用研究 ApplicationResearchofComputers
Vol35No10 Oct.2018
改进的车流量估计 ViBe算法
黄 鑫,肖世德
(西南交通大学 机械工程学院,成都 610036)
摘 要:针对视觉背景提取(visualbackgroundextractor,ViBe)算法中出现的鬼影、阴影前景和漏检静止目标等 问题,提出了经过改善的 ViBe算法。首先在背景模型初始化阶段,利用改善的平均背景建模法建立初始化背景 模型以消除鬼影。在前景检测阶段,通过计算运动目标与背景像素间的差值消除由于光照所造成的阴影,同时 利用直方图相似度检测静止目标。最终在车道设置虚拟线圈检测区以检测各个车道的占用比,从而得出道路的 交通情况。实验表明,经过改善后的 ViBe算法在抑制鬼影出现、检测静止目标和消除阴影三个方面有较好的效 果,能够准确检测出道路车流量。 关键词:背景差法;车辆检测;鬼影抑制;静止目标;阴影消除 中图分类号:TP391;TP301.6 文献标志码:A 文章编号:10013695(2018)10317603 doi:10.3969/j.issn.10013695.2018.10.069
一种ViBe算法性能提升方法[发明专利]
(19)中华人民共和国国家知识产权局(12)发明专利申请(10)申请公布号 (43)申请公布日 (21)申请号 202010691046.8(22)申请日 2020.07.17(71)申请人 浙江工业大学地址 310006 浙江省杭州市下城区朝晖六区潮王路18号(72)发明人 高飞 李云阳 王金超 葛一粟 卢书芳 翁立波 (74)专利代理机构 杭州浙科专利事务所(普通合伙) 33213代理人 周红芳(51)Int.Cl.G06T 7/277(2017.01)G06T 7/254(2017.01)G06F 17/16(2006.01)(54)发明名称一种ViBe算法性能提升方法(57)摘要本发明提出了一种ViBe算法性能提升方法。
所述方法包括:步骤1:创建与ViBe输入图像相同大小的两个布尔矩阵M 1,M 2;步骤2:修改ViBe算法中的判定当前像素为(x ,y)为背景点时所做的操作;步骤3:在ViBe扫描完成当前图像后,更新ViBe的样本点,并再次执行步骤2。
本发明通过修改ViBe更新背景模型的更新逻辑,使ViBe能够在高分辨率的视频序列中,极大的减少ViBe算法调用随机数函数的次数,提升ViBe算法对背景模型的更新速度,减少了计算冗余,极大的提升了计算效率,同时,本发明对ViBe算法的前景和背景的分割质量影响极低。
权利要求书1页 说明书3页CN 111798495 A 2020.10.20C N 111798495A1.一种ViBe算法性能提升方法,其特征在于包括如下步骤:步骤1:创建与ViBe输入图像相同大小的两个布尔矩阵M 1,M 2,其大小均为width ×height,将两个矩阵均初始化为逻辑假矩阵,即将其中的每个元素均设置为False;步骤2:修改ViBe算法中的判定当前像素为(x ,y)为背景点时所做的操作;步骤3:在ViBe扫描完成当前图像后,更新ViBe的样本点。
2.根据权利要求1所述的一种ViBe算法性能提升方法,其特征在于步骤2的具体步骤如下:步骤2.1:当需要更新(x ,y)位置的一个随机邻域的样本点时,放弃对应位置的随机领域样本点更新,并做如下式(1)所示的记录:M 1(x ,y)=True (1)其中,M 1(x ,y)表示矩阵M 1在(x ,y)位置的值,且True为逻辑真;步骤2.2:当需要更新(x ,y)位置的样本点时,放弃对应位置的样本点更新,并做如下式(2)所示的记录:M 2(x ,y)=True (2)其中,M 2(x ,y)表示矩阵M 2在(x ,y)位置的值,且True为逻辑真。
改进的ViBe算法及在复杂背景下的应用
改进的ViBe算法及在复杂背景下的应用肖义涵;赵群飞【摘要】前景分割取作为运动检测和对象识别的预处理程序,在基于视频序列的应用中起到重要的作用.基于视觉背景提取子提出了一种在彩色空间下的改进型前景分割算法.视觉背景提取子在当前背景提取算法中具有最高的处理效率,但在复杂背景和人物前景面积较大等情况下提取效果会明显下降.提出了一种新的彩色空间下的像素距离模型,并改进了像素信息的传播更新机制.实验表明在并未牺牲计算效率的前提下,算法在复杂背景的环境中获得了很好的效果,对光照干扰和动态背景纹理都具有良好的鲁棒性.【期刊名称】《微型电脑应用》【年(卷),期】2014(030)004【总页数】4页(P53-55,64)【关键词】ViBe;前景分割;背景提取;视频处理【作者】肖义涵;赵群飞【作者单位】上海交通大学自动化系,上海,200240;上海交通大学自动化系,上海,200240【正文语种】中文【中图分类】TP311作为视频处理中的重要组成部分,前景检测一直是计算机视觉的研究热点。
在现在的前景检测算法中,背景差分型方法有着相对较好的噪声抑制能力和较低的计算复杂度,因此成为实际应用中前景检测的首选,但如何提高背景模型的有效更新效率是该法的难点,因而围绕背景差分法的研究主要集中于背景模型的选择和更新机制的设计上。
混合高斯模型Gaussian Mixture Model (GMM)[1]是应用最广泛的背景模型,GMM通过对每个像素建立多个高斯模型(一般3到5个)来计算当前像素和背景的隶属概率。
但是混合高斯模型的计算复杂度较高,而且并未考虑前景和背景的区分程度,对于每个像素的更新速度是一样的,导致在很多情况下,如光照变化,前景停留或背景移出等都会出现持续的大量误分割。
Kyungnam Kim等人提出了码本算法(Codebook)[2],通过长时间的采样对每个像素不同值的出现频率进行统计,以此区分背景和前景,同时对于一些动态的环境干扰具有一定的抑制能力,但是其计算开销较大,实现复杂。
一种基于改进三帧差分和ViBe算法的运动目标检测算法
一种基于改进三帧差分和ViBe算法的运动目标检测算法谢红;原博;解武【摘要】近几年提出的ViBe算法具有运算速度快,目标提取准确率高的特点,但是它对光照的突然变化也非常敏感,而且由于它的模型初始化的方式,也容易形成“拖影”现象。
文中先通过引入传统三帧差分算法难以提取出完整的目标轮廓这一问题,提出一种结合边缘检测的改进三帧差分算法。
该算法在提取出完整的运动目标的同时不会附加冗余的边缘信息。
然后将该算法引入到ViBe算法中,使2种方法结合,一方面消除“拖影”现象,另一方面可以自适应地选择检测的方法,以消除光照突变造成的影响。
试验结果表明,该改进算法是一种适应性强、鲁棒性高的运动目标检测算法。
%The ViBe algorithm proposed in recent years has the characteristics of high computing speed and high accuracy of object extraction. But it is sensitive to the light mutation. And it is also easy to form the"smear" phe⁃nomenon because of its model initialization modes. Firstly, this article proposed the improved three⁃frame difference algorithm combined with edge detection by introducing the problem that the traditional three⁃frame difference algo⁃rithm is difficult to extract the complete contours of the targets. This algorithm can extract the complete moving tar⁃gets without additional redundancy edge information. Then this algorithm is introduced into the ViBe algorithm and is combined with it. The improved algorithm can eliminate the"smear" phenomenon. and it can select the suitable detection method adaptively to eliminate the impact caused by the light mutation. The experimental results show that, this method is an effective moving target detection method.【期刊名称】《应用科技》【年(卷),期】2016(043)006【总页数】7页(P46-52)【关键词】视觉背景提取算法;三帧差分法;边缘检测;“拖影”现象;光照突变【作者】谢红;原博;解武【作者单位】哈尔滨工程大学信息与通信工程学院,黑龙江哈尔滨150001;哈尔滨工程大学信息与通信工程学院,黑龙江哈尔滨150001;哈尔滨工程大学信息与通信工程学院,黑龙江哈尔滨150001【正文语种】中文【中图分类】TN911.73运动目标检测就是将视频序列中的运动目标与所在的背景图像相分离,从而可以获得目标的前景,也就是确切的运动目标。
一种改进的融合帧差法的ViBe算法
一种改进的融合帧差法的ViBe算法史瑞环;吴斌;李务军;范风兵【摘要】ViBe运动目标检测算法速度快,能有效抑制噪声,但在光照强度突然改变的情况下,该算法会造成大面积的背景像素被误判为前景像素,针对此问题提出一种改进的融合帧差法的ViBe算法.实验结果表明,改进的算法能在光照有变化时依然能检测到完整的运动目标.【期刊名称】《微型机与应用》【年(卷),期】2016(035)004【总页数】3页(P44-45,49)【关键词】ViBe;目标检测;帧差法【作者】史瑞环;吴斌;李务军;范风兵【作者单位】西南科技大学信息工程学院,四川绵阳621010;西南科技大学信息工程学院,四川绵阳621010;西南科技大学信息工程学院,四川绵阳621010;西南科技大学信息工程学院,四川绵阳621010【正文语种】中文【中图分类】TP391.4随着互联网和物联网的飞速发展,近年来智能安防监控得到了广泛的关注和应用。
前景目标的提取是运动视频分析的关键步骤,提取的目标是否准确完整将直接影响到后续的目标分类、目标跟踪和识别的准确率。
目前,常用的运动检测方法有:帧差法、背景差法、光流法[1]。
其中,背景差法应用最为广泛,核心原理是为每一个像素点建立一个背景模型,然后用模型与当前像素相比,以确定是否为背景像素。
经典的背景差法是GMM[2],它将单一像素点所呈现的颜色用M(一般取 3~5)个高斯分布来近似,能处理多模型背景场景,但是它的计算量非常大,需要估计分布的参数,而且更新参数难调试。
2009年,BARNICH O等人[3]提出了一种全新的背景差算法——ViBe算法,只通过在每个像素领域内随机选取若干个采样点对各像素建立一个样本模型,采用随机的方法更新背景模型。
对比其他一些前沿的背景提取方法,ViBe算法简单,有效地简化了程序,加快了对于帧的处理速度的同时,可以达到较高的准确度,增强了抗噪能力并减少了计算负载[4]。
但是该算法在背景光照突然发生变化时会将大面积的背景误判为运动前景[5],导致检测出的目标无法识别。
一种能快速抑制鬼影及静止目标的ViBe改进算法
一种能快速抑制鬼影及静止目标的ViBe改进算法吴尔杰;杨艳芳;田中贺;蒋建国【摘要】Ghost and stay object may be detected by visual background extractor (ViBe) algorithm , which bring some errors when detecting objects ,so these problems need to be restrained effectively . In this paper ,based on the original ViBe algorithm ,whether a foreground is stay object or ghost is judged by comparing the variance of gray value of a regional background model and the variance of gray value of the same region of next frame ,and then different measures are adopted to limit the ghost and stay object and update the background model .The experimental results show that the improved algorithm can restrain ghost completely in only 15 frames ,and restrain stay object completely in only 20 frames ,but the original ViBe algorithm restrains ghost completely in 108 frames and it can not re-strain stay object effectively .The experimental results indicate that when the monitoring scene is ordi-nary or relatively complex ,this improved algorithm is feasible andeffective .%ViBe算法存在鬼影和静止目标问题 ,这些问题给目标检测带来误差 ,需要快速有效地抑制 . 文章在原始 ViBe 算法基础上 ,先通过比较局部区域的背景模型像素值方差和新来帧该区域的像素值方差的大小来判断该区域存在鬼影还是静止目标 ,存在则进行抑制 ,然后采用不同的策略更新鬼影区域和静止目标区域的背景 . 实验结果中 ,改进算法仅用 15 帧就可以完全抑制鬼影 ,仅用 20 帧就能完全抑制静止目标 ,而原始ViBe 算法完全抑制鬼影需要 108 帧且抑制静止目标能力有限 . 实验结果表明 ,对于普通的以及背景较为复杂的监控场景 ,文中改进算法可行、有效 .【期刊名称】《合肥工业大学学报(自然科学版)》【年(卷),期】2016(039)001【总页数】6页(P56-61)【关键词】目标检测;背景模型;ViBe算法;鬼影;静止目标【作者】吴尔杰;杨艳芳;田中贺;蒋建国【作者单位】合肥工业大学计算机与信息学院 ,安徽合肥 230009;合肥工业大学电子科学与应用物理学院 ,安徽合肥 230009;合肥工业大学计算机与信息学院 ,安徽合肥 230009;合肥工业大学计算机与信息学院 ,安徽合肥 230009【正文语种】中文【中图分类】TP301.6蒋建国(1955-),男,安徽宁国人,合肥工业大学教授,博士生导师.在智能视频监控系统中,目标检测效果的优劣直接影响目标分类、跟踪等后期处理的效果,准确、实时的运动检测算法是智能视频监控技术的迫切需要。
多维数组的动态分配(二三维)
多维数组的动态分配(⼆三维)三天之内把伟⼤的Vibe算法搞懂了,今天⽤了⼀上午的时间把Vibe写了出来,结果⼀运⾏提⽰了⼀个“stack overflow”的错误,当时我那个⼼⼒憔悴呀。
各种查找,各种百度,最后还是找到了相应的答案,在此记录⼀下,以作以后使⽤,对于我对伟⼤的Vibe算法的理解,稍后将会奉上://////////////c⽤malloc和free//////////////////////////////#i nclude "stdio.h"#i nclude "stdlib.h"void main(){int **p;int i,j; //p[4][8]//开始分配4⾏8列的⼆维数据p = (int**)malloc(sizeof(int*)*4);for(i=0; i<4; i++)p[i] = (int*)malloc(sizeof(int)*8);for(i=0; i<4; i++)for(j=0; j<8; j++)p[i][j] = j*i;//打印数据for(i=0; i<4; i++)for(j=0; j<8; j++){if(j==0) printf("\n");printf("%3d",p[i][j]);}//开始释放申请的堆for(i=0; i<4; i++)free(p[i]);free(p);}/////////////////////////////////////////////////////////////////////////c++⽤new和delete/////////////////////////////#i nclude <iostream>using namespace std;void main(){int **p;int i,j; //p[4][8]//开始分配4⾏8列的⼆维数据p = new int *[4];for(i=0;i<4;i++)p[i]=new int [8];for(i=0; i<4; i++)for(j=0; j<8; j++)p[i][j] = j*i;//打印数据for(i=0; i<4; i++)for(j=0; j<8; j++){if(j==0) cout<<endl;cout<<p[i][j]<<"\t";}//开始释放申请的堆for(i=0; i<4; i++)delete [] p[i];delete [] p;}///////////////////////////////////////////////////////////动态分配三维数组的程序//////////////c⽤malloc和free//////////////////////////////#i nclude "stdlib.h"#i nclude "stdio.h"void main(){int i,j,k; //p[2][3][4]char ***p = (char***)malloc(2* sizeof(char**)); for(i=0; i<2; i++){p[i] = (char**)malloc(3*sizeof(char*));for(j=0; j<3; j++){p[i][j] = (char*)malloc(4*sizeof(char)); }}//finish creating use p[i][j][k] to access the data for(i=0; i<2; i++){for(j=0; j<3; j++){for(k=0;k<4;k++){p[i][j][k]=i+j+k;printf("%d ",p[i][j][k]);}printf("\n");}printf("\n");}//free the memoryfor(i=0; i<2; i++){for(j=0; j<3; j++){free(p[i][j]);}}for(i=0; i<2; i++){free(p[i]);}free(p);}/////////////////////////////////////////////////////////////////////////c++⽤new和delete/////////////////////////////#i nclude <iostream>using namespace std;void main(){int i,j,k; // p[2][3][4]int ***p;p = new int **[2];for(i=0; i<2; i++){p[i]=new int *[3];for(j=0; j<3; j++)p[i][j]=new int[4];}//finish creating use p[i][j][k] to access the data for(i=0; i<2; i++){for(j=0; j<3; j++){for(k=0;k<4;k++){p[i][j][k]=i+j+k;cout<<p[i][j][k]<<" ";}cout<<endl;}cout<<endl;}//free the memoryfor(i=0; i<2; i++){for(j=0; j<3; j++){delete [] p[i][j];}}for(i=0; i<2; i++){delete [] p[i];}delete [] p;}。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一vibe.cpp// vibe.cpp : Defines the entry point for the console application.//// lx_Picture.cpp : Defines the entry point for the console application. //#include"stdafx.h"#include"cv.h"//#include <opencv2/opencv.hpp>#include"highgui.h"#include"hanshu.h"#include<iostream>using namespace std;using namespace cv;int nFrmNum = 0;//记录帧数int Width;//记录帧的宽度int Height;//记录帧的高度int FrameRate;//记录视频帧率#define zero 1e-12#define DIS(a,b) sqrt(double((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y))) #define SGN(x) (fabs((double) x)<zero?0:(x>0?1:-1))#define CROSS(a,b,c) ((b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x))//叉积,用来判断旋转方向#define CMP(a,b) (a.x<b.x||SGN(a.x-b.x)==0 &&a.y<b.y)//坐标的比较#define RAND (rand()%100000/100000.0)//产生-1之间的浮点数IplImage *img;//IplImage *imgRGB;IplImage *imggray;IplImage *imgmat;IplImage* pFrameb;int hull_size = 0;//CvPoint* hull_p;void draw_hull(CvPoint *pm,int pointnum);inline void swap(CvPoint p[],int x,int y);inline void push(CvPoint*S,CvPoint pt);inline CvPoint pop(CvPoint*S);void sort(CvPoint p[],int l,int r);void Resultprocess(IplImage *pimg);int main(int argc, char* argv[]){IplImage* pFrame=NULL;CvMat* pFrameMat = NULL;//pFrame对象IplImage* pAfter=NULL;CvMat* pAfterMat=NULL;//保存pFrame对应的灰度图像IplImage* segMap=NULL;CvMat* segMat=NULL;//保存处理后的信息IplImage* pFrameSeg;//2013.8.24IplImage* redImage=NULL;IplImage* greenImage=NULL;IplImage* blueImage=NULL;pFrameb=NULL;IplImage* pFrMatImg=NULL;////2013.8.24IplImage *segMapbg=NULL; //保存图像和后处理用IplImage *segMapdif=NULL; //保存图像和后处理用IplImage* pFramec;//要读取的视频文件和保存的视频文件路径char* openfile="F:\\Users\\win\\Desktop\\west5_2.avi";char* outfile="F:\\Users\\win\\Desktop\\vibe.avi";char filename[100];//保存的图像位置和名称//打开视频文件CvCapture* pCapture=cvCreateFileCapture(openfile);if(pCapture==NULL) {cout<<"video file open error!"<<endl;return -1;}//获取视频相关信息,帧率和大小double fps=cvGetCaptureProperty(pCapture,CV_CAP_PROP_FPS);CvSize size=cvSize((int)cvGetCaptureProperty(pCapture,CV_CAP_PROP_FRAME_WIDTH)*2, (int)cvGetCaptureProperty(pCapture,CV_CAP_PROP_FRAME_HEIGHT));//创建输出视频文件CvVideoWriter* Save_result=NULL;Save_result=cvCreateVideoWriter(outfile,CV_FOURCC('X','V','I','D'),fps,size,1);IplImage* dstImg=cvCreateImage(size,IPL_DEPTH_8U,3);//创建要保存的图像//创建窗口cvNamedWindow("video",CV_WINDOW_AUTOSIZE);//0.25//cvNamedWindow("debug",1);//2013.8.28//创建一个随机数生成器RNG rng(0xFFFFFFFF);//定义字体CvFont font;cvInitFont( &font, CV_FONT_HERSHEY_COMPLEX_SMALL ,1, 1, 0, 1, 8);//逐帧读取视频并进行处理while(pFrame = cvQueryFrame( pCapture )){nFrmNum++;//如果是第一帧,申请内存并进行初始化if(nFrmNum==1){segMap = cvCreateImage(cvSize(pFrame->width, pFrame->height),IPL_DEPTH_8U,1);segMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);pAfter=cvCreateImage(cvSize(pFrame->width, pFrame->height),IPL_DEPTH_8U,1);pAfterMat=cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);//2013.8.24redImage=cvCreateImage(cvSize(pFrame->width,pFrame->height),IPL_DEPTH_8U,1);//用于存储输入图像的红色分量图像greenImage=cvCreateImage(cvSize(pFrame->width,pFrame->height),IPL_DEPTH_8U,1);//用于存储输入图像的绿色分量图像blueImage=cvCreateImage(cvSize(pFrame->width,pFrame->height),IPL_DEPTH_8U,1);//用于存储输入图像的蓝色分量图像pFrameb = cvCreateImage(cvSize(pFrame->width, pFrame->height),IPL_DEPTH_8U,3);pFramec = cvCreateImage(cvSize(pFrame->width, pFrame->height),IPL_DEPTH_8U,3);//保存图像用pFrMatImg = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,1);//空洞填充img=cvCreateImage(cvSize(pFrame->width,pFrame->height),IPL_DEPTH_8U,3);imggray=cvCreateImage(cvSize(pFrame->width,pFrame->height),IPL_DEPTH_8U,1);imgmat=cvCreateImage(cvSize(pFrame->width,pFrame->height),IPL_DEPTH_8U,1);cvCopy(pFrame, pFrameb,0);//2013.9.13cvCopy(pFrame, pFramec,0);//2013.9.23//滤波//中值滤波,去掉噪声//cvSmooth(pFrame, pFrameb, CV_MEDIAN, 3, 0, 0,0);////均衡化处理,克服亮度影响.2.11//cvSplit(pFrameb,blueImage,greenImage,redImage,NULL);//将彩色图像pFrame 的蓝色分量图像blueImage﹑绿色分量图像greenImage和红色分量图像redImage提取出来//cvEqualizeHist(redImage,redImage);//对红色分量图像进行直方图均衡化处理//cvEqualizeHist(greenImage,greenImage); //对绿色分量图像进行直方图均衡化处理//cvEqualizeHist(blueImage,blueImage); //对蓝色分量图像进行直方图均衡化处理//cvMerge(blueImage,greenImage,redImage,NULL,pFrameb);//将经过直方图均衡化的蓝色﹑绿色﹑红色图像合并成彩色图像,存储在pFrameb中//cvCopy(pFrameb,pFrame,0);////2013.8.24segMapbg = cvCreateImage(cvSize(pFrame->width, pFrame->height),IPL_DEPTH_8U,1); //2013.8.28segMapdif = cvCreateImage(cvSize(pFrame->width, pFrame->height),IPL_DEPTH_8U,1); //2013.8.28pFrameSeg=cvCreateImage(cvSize(pFrame->width, pFrame->height),IPL_DEPTH_8U,3);//转化成单通道图像再处理cvCvtColor(pFrame, pAfter, CV_BGR2GRAY);cvConvert(pAfter, pAfterMat);Initialize(pAfterMat,rng);}else {//2013.8.24//滤波//中值滤波,去掉噪声//cvSmooth(pFrame, pFrameb, CV_MEDIAN, 3, 0, 0,0);////均衡化处理,克服亮度影响.2.11//cvSplit(pFrameb,blueImage,greenImage,redImage,NULL);//将彩色图像pFrame 的蓝色分量图像blueImage﹑绿色分量图像greenImage和红色分量图像redImage提取出来//cvEqualizeHist(redImage,redImage);//对红色分量图像进行直方图均衡化处理////cvEqualizeHist(greenImage,greenImage); //对绿色分量图像进行直方图均衡化处理////cvShowImage("debug",greenImage);//cvEqualizeHist(blueImage,blueImage); //对蓝色分量图像进行直方图均衡化处理////cvMerge(blueImage,greenImage,redImage,NULL,pFrameb);//将经过直方图均衡化的蓝色﹑绿色﹑红色图像合并成彩色图像,存储在pFrameb中//cvCopy(pFrameb,pFrame,0);////2013.8.24cvCopy(pFrame, pFrameb,0);//2013.9.13cvCopy(pFrame, pFramec,0);//2013.9.23cvCvtColor(pFrame,pAfter,CV_BGR2GRAY);cvConvert(pAfter,pAfterMat);update(pAfterMat,segMat,rng,nFrmNum);//更新背景cvConvert(segMat,segMap);//进行形态学滤波,去掉噪音2013.8.24cvErode(segMap, segMap, 0, 1);cvDilate(segMap, segMap, 0, 1);//cvSmooth(segMap, segMap, CV_MEDIAN, 3, 0, 0,0);//掩膜空洞填充//将大背景全部用前景色(白色)填充cvCopy(segMap,pFrMatImg,0);CvPoint seedPoint=cvPoint(0,0);cvFloodFill(pFrMatImg,seedPoint,cvScalarAll(255),cvScalarAll(0),cvScalarAll(0),NULL,8,NU LL);//取反.2.1cvNot(pFrMatImg,pFrMatImg);//与原二值图像相加cvAdd(segMap,pFrMatImg,segMap,0);//cvShowImage("debug",segMap);cvCvtColor(segMap,pFrameSeg,CV_GRAY2BGR);// 下面的程序段用来找到轮廓去除小块CvSeq *cont;CvMemStorage *stor;// Create dynamic structure and sequence.stor = cvCreateMemStorage(0);cont = cvCreateSeq(CV_SEQ_ELTYPE_POINT, sizeof(CvSeq), sizeof(CvPoint) , stor);//找到所有轮廓cvFindContours( segMap, stor, &cont, sizeof(CvContour),CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0));// 直接使用CONTOUR中的矩形来处理for(;cont;cont = cont->h_next){CvRect r = ((CvContour*)cont)->rect;// if(r.height * r.width >16) // 面积大的方形保留// {// //对轮廓连通域进行颜色填充://// cvRectangle( imggray, cvPoint(r.x,r.y), cvPoint(r.x + r.width, r.y + r.height),CV_RGB(255,255,255), CV_FILLED, 8,0);// }if(r.height * r.width < 16) // 面积小的方形抛弃掉{//对轮廓连通域进行颜色填充:cvRectangle( segMap, cvPoint(r.x,r.y), cvPoint(r.x +r.width, r.y + r.height),CV_RGB(0,0,0), CV_FILLED, 8,0);}}//2013.8.24if (nFrmNum==2){cvCopy(segMap,segMapbg);}//2013.8.28//将segMap转换成三通道图像存在pFrame中cvCvtColor(segMap,pFrame,CV_GRAY2BGR);//去掉时间显示数字变化的影响2013.9.9int i;int j;for (i=pFrame->height/18;i<pFrame->height/8;i++ ){for (j=pFrame->width/7;j<pFrame->width/4;j++){(pFrame->imageData+i*pFrame->widthStep)[3*j]=0;(pFrame->imageData+i*pFrame->widthStep)[3*j+1]=0;(pFrame->imageData+i*pFrame->widthStep)[3*j+2]=0;}}//后处理,只有有运动物体才需要//当前帧跟背景图相减cvAbsDiff(segMap, segMapbg, segMapdif);//二值化前景图cvThreshold(segMapdif,segMapdif, 25, 255.0, CV_THRESH_BINARY);/*cvShowImage("debug",segMapbg);*/CvScalar avgsum;avgsum=cvAvg(segMapdif,NULL);double avgvalue=avgsum.val[0]+avgsum.val[1]+avgsum.val[2]+avgsum.val[3];double pixelnum=pFrame->width*pFrame->height;if (avgvalue >= 4000/pixelnum){Resultprocess(pFrame);cvCvtColor(imggray,pFrame,CV_GRAY2BGR);// 找到所有轮廓cvFindContours( imggray, stor, &cont, sizeof(CvContour),CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE,cvPoint(0,0));// 直接使用CONTOUR中的矩形来画轮廓for(;cont;cont = cont->h_next){CvRect r = ((CvContour*)cont)->rect;cvRectangle( pFrameb, cvPoint(r.x,r.y), cvPoint(r.x + r.width, r.y + r.height),CV_RGB(255,255,255), 1, 8,0);}}// free memorycvReleaseMemStorage(&stor);//载入原图像到目标图像cvSetImageROI(dstImg, cvRect(0, 0, pFrame->width, pFrame->height));cvCopy(pFrameb, dstImg);cvResetImageROI(dstImg);//载入检测后的图像到目标图像cvSetImageROI(dstImg, cvRect(pFrame->width, 0, pFrame->width*2, pFrame->height));// cvCopy(pFrame, dstImg);cvCopy(pFrameSeg, dstImg);cvResetImageROI(dstImg);//显示提示文字cvPutText(dstImg, "Origin Video", cvPoint(0,pFrame->height-8),&font,CV_RGB(255,255,0));cvPutText(dstImg, "Foreground Video",cvPoint(pFrame->width,pFrame->height-8),&font,CV_RGB(255,255,0));//保存视频和输出cvWriteFrame(Save_result,dstImg);//输出图片,有物体才保存//当前帧跟背景图相减//cvAbsDiff(segMap, segMapbg, segMapdif);////二值化前景图//cvThreshold(segMapdif,segMapdif, 25, 255.0, CV_THRESH_BINARY);///*cvShowImage("debug",segMapbg);*/// CvScalar avgsum;//avgsum=cvAvg(segMapdif,NULL);//doubleavgvalue=avgsum.val[0]+avgsum.val[1]+avgsum.val[2]+avgsum.val[3];//double pixelnum=pFrame->width*pFrame->height;// if (avgvalue >= 4000/pixelnum)// {//if(nFrmNum<11)//sprintf(filename,"E:\\cjr\\Programs\\programs\\Vibe_zx\\pictureRGB\\000%d_Vibe.jpg",nFrm Num-1); //pictureRGB//else if(nFrmNum<101)//sprintf(filename,"E:\\cjr\\Programs\\programs\\Vibe_zx\\pictureRGB\\00%d_Vibe.jpg",nFrmN um-1);//else if(nFrmNum<1001)//sprintf(filename,"E:\\cjr\\Programs\\programs\\Vibe_zx\\pictureRGB\\0%d_Vibe.jpg",nFrmNu m-1);//else if(nFrmNum<10001)//sprintf(filename,"E:\\cjr\\Programs\\programs\\Vibe_zx\\pictureRGB\\%d_Vibe.jpg",nFrmNum -1);//cvSaveImage(filename,pFramec);//pFrameSeg// }cvShowImage("video",dstImg);if(cvWaitKey(5)>=0) break;}}cvReleaseImage(&pFrame);cvReleaseMat(&pFrameMat);cvReleaseImage(&pAfter);cvReleaseMat(&pAfterMat);cvReleaseImage(&segMap);cvReleaseMat(&segMat);cvReleaseVideoWriter(&Save_result);cvReleaseImage(&dstImg);cvDestroyWindow("video");//2013.8.24cvReleaseImage(&redImage);cvReleaseImage(&greenImage);cvReleaseImage(&blueImage);cvReleaseImage(&pFrameb);cvReleaseImage(&pFramec);cvReleaseImage(&pFrMatImg);//2013.8.24cvReleaseImage(&img);cvReleaseImage(&imggray);cvReleaseImage(&imgmat);cvDestroyWindow("Image");return 0;}void Resultprocess(IplImage *pimg){int fgpixelnum=0;uchar *fgimagdata;// cvNamedWindow("ImageProcess");// cvNamedWindow("Image");cvCopy(pimg,img);cvCvtColor(img,imggray,CV_RGB2GRAY);//提取轮廓cvCanny(imggray,imggray,5,40,3);// cvShowImage("Image",imggray);// cvWaitKey(0);CvPoint *pz = NULL;pz=new CvPoint[img->width*img->height];CvPoint *ptmp= pz;//统计前景像素数fgimagdata=(uchar*)imggray->imageData;int step=(imggray->widthStep/(sizeof(uchar)));double fgimgvalue =0;for (int i=0; i<imggray->height; i++){for (int j=0; j<imggray->width;j++){fgimgvalue=fgimagdata[step*i+j];if (fgimgvalue>10){fgpixelnum++;pz->x=j;pz->y=i;pz++;}}}pz=ptmp;draw_hull(pz,fgpixelnum);pz=ptmp;//free(pz);delete pz;return;}void draw_hull( CvPoint *pm,int pointnum){int min=-1;CvPoint* hull_p = new CvPoint[ pointnum];//用来储存凸包上的点CvPoint *p;//=(CvPoint*)malloc(sizeof(CvPoint)*(img->width*img->height));/* CvPoint *ptp;ptp=p;*/p=pm;//找出x坐标最小的,作为起始点//for(int j=0;j<pointnum;j++){if ( min == -1 || CMP( p[j],p[min])){min = j;}}if(min!=0)swap(p,0,min);sort(p,1,pointnum-1);//其他点排序push(hull_p,p[0]);push(hull_p,p[1]);push(hull_p,p[2]);for(int i=3;i<pointnum-1;i++) //pointnum-1?{while(CROSS(hull_p[hull_size-2],hull_p[hull_size-1],p[i])<0)//非左转{pop(hull_p);//cvLine(imggray,hull_p[hull_size-1],p[i],cvScalar(255,0,255));//为了看清运行过程而加的//cvShowImage("ImageProcess",imggray);//cvWaitKey(100);}//cvLine(imggray,hull_p[hull_size-1],p[i],cvScalar(255,0,255));push(hull_p,p[i]);}cvPolyLine(imggray,&hull_p,&hull_size,1,1,cvScalar(255,255,255),2);//最终画出凸包//填充//掩膜空洞填充//将大背景全部用前景色(白色)填充cvCopy(imggray,imgmat,0);CvPoint seedPoint=cvPoint(0,0);cvFloodFill(imgmat,seedPoint,cvScalarAll(255),cvScalarAll(0),cvScalarAll(0),NULL,8,NULL) ;//取反.2.1cvNot(imgmat,imgmat);//与原二值图像相加cvAdd(imggray,imgmat,imggray,0);free(hull_p);hull_size=0;/*p=ptp;free(p);*/}//下面简单实现了栈操作inline void push(CvPoint*S,CvPoint pt){S[hull_size++]=pt;}inline CvPoint pop(CvPoint*S){return S[--hull_size];}inline void swap(CvPoint p[],int x,int y){CvPoint pt = p[x];p[x] = p[y];p[y]=pt;}inline bool compare(CvPoint a,CvPoint b,CvPoint c) {//int tmp = SGN(double( CROSS(a,b,c)));if(tmp!=0)return tmp>0;//如果两点共线的话,就需要比较远近了//elsereturn DIS(a,b)< DIS(a,b);}//快排,极角的排序void sort(CvPoint p[],int l,int r){CvPoint tmp = p[(l+r)/2];int i = l;int j = r;do{while(compare(p[0],p[i],tmp))i++;while(compare(p[0],tmp,p[j]))j--;if(i <= j){swap(p,i,j);i++;j--;}}while(i<=j);if(i<r)sort(p,i,r);if(j>l)sort(p,l,j);}二huangshu.cpp#include"stdafx.h"#include"hanshu.h"#include"cv.h"//#include <opencv2/opencv.hpp>#include"highgui.h"#include<math.h>#include<iostream>using namespace std;using namespace cv;static int c_xoff[9] = {-1, 0, 1, -1, 1, -1, 0, 1, 0};//x的邻居点static int c_yoff[9] = {-1, 0, 1, -1, 1, -1, 0, 1, 0};//y的邻居点float samples[1024][1024][defaultNbSamples+1];//保存每个像素点的样本值//初始化void Initialize(CvMat* pFrameMat,RNG rng){//记录随机生成的行(r) 和列(c)int rand,r,c;//对每个像素样本进行初始化for(int y=0;y<pFrameMat->rows;y++){//Heightfor(int x=0;x<pFrameMat->cols; x++){//Widthfor(int k=0;k<defaultNbSamples;k++){//随机获取像素样本值rand=rng.uniform( 0, 9 );r=y+c_yoff[rand]; if(r<0) r=0; if(r>=pFrameMat->rows) r=pFrameMat->rows-1; //行c=x+c_xoff[rand]; if(c<0) c=0; if(c>=pFrameMat->cols) c=pFrameMat->cols-1; //列//存储像素样本值samples[y][x][k]=CV_MAT_ELEM(*pFrameMat,float,r,c); //CV_MAT_ELEM opencv中用来访问矩阵每个元素的宏,这个宏只对单通道矩阵有效}samples[y][x][defaultNbSamples]=0;}}}//更新函数void update(CvMat* pFrameMat,CvMat* segMat,RNG rng,int nFrmNum){for(int y=0;y<pFrameMat->rows;y++){ //Heightfor(int x=0;x<pFrameMat->cols;x++){ //Width//用于判断一个点是否是背景点,index记录已比较的样本个数,count表示匹配的样本个数int count=0,index=0;float dist=0;//while((count<defaultReqMatches) && (index<defaultNbSamples)){dist=CV_MAT_ELEM(*pFrameMat,float,y,x)-samples[y][x][index];if(dist<0) dist=-dist;if(dist<defaultRadius) count++;index++;}if(count>=defaultReqMatches){//判断为背景像素,只有背景点才能被用来传播和更新存储样本值samples[y][x][defaultNbSamples]=0;*((float *)CV_MAT_ELEM_PTR(*segMat,y,x))=background;int rand=rng.uniform(0,defaultSubsamplingFactor);if(rand==0){rand=rng.uniform(0,defaultNbSamples);samples[y][x][rand]=CV_MAT_ELEM(*pFrameMat,float,y,x);}rand=rng.uniform(0,defaultSubsamplingFactor);if(rand==0){int xN,yN;rand=rng.uniform(0,9);yN=y+c_yoff[rand];if(yN<0) yN=0; if(yN>=pFrameMat->rows) yN=pFrameMat->rows-1;rand=rng.uniform(0,9);xN=x+c_xoff[rand];if(xN<0) xN=0; if(xN>=pFrameMat->cols) xN=pFrameMat->cols-1;rand=rng.uniform(0,defaultNbSamples);samples[yN][xN][rand]=CV_MAT_ELEM(*pFrameMat,float,y,x);}}else {//判断为前景像素*((float *)CV_MAT_ELEM_PTR(*segMat,y,x))=foreground;samples[y][x][defaultNbSamples]++;if(samples[y][x][defaultNbSamples]>50){int rand=rng.uniform(0,defaultNbSamples);if(rand==0){rand=rng.uniform(0,defaultNbSamples);samples[y][x][rand]=CV_MAT_ELEM(*pFrameMat,float,y,x);}}}}}}。