资源描述
装订线目 录1绪论12OpenCV的编程环境32.1 OpenCV简介32.2 OpenCV环境介绍52.2.1 OpenCV的基本结构52.2.2 OpenCV的特征62.3安装OpenCV72.3.1安装OpenCV1.072.3.2配置Windows环境变量92.3.3配置VC+6.0环境与全局设置112.3.4项目设置113OpenCV的体系结构133.1 OpenCV中的常用数据结构体系133.2 OpenCV中常用类体系143.3 OpenCV处理图像常用的函数144视频处理174.1对视频进行读写处理174.1.1获取摄像头并显示视频图像174.1.2对获取的视频进行保存194.1.3读取AVI视频204.2小结205运动目标监控系统的研究与实现215.1运动目标监控系统215.2基于背景建模的图像处理235.2.1背景生成算法235.2.2对捕获的图像帧的处理265.3运动物体监控的实现30结束语34致 谢35参考文献36附录(源代码)37第 III 页1绪论20多年来,视频监控系统经历了从第一代百分之百的模拟系统(VCR),到第二代部分数字化的系统(DVR/NVR),再到第三代完全数字化的系统(网络摄像机和视频服务器)三个阶段的发展演变。在这一过程中,视频监控系统与设备虽然在功能和性能上得到了极大的提高,但是仍然受到了一些固有因素的限制,其中既包含人类作为监控者自身在生理上的弱点,也包含视频监控系统配置和以及视频监控设备在功能和性能上的局限性。这些限制因素使各类视频监控系统均或多或少的存在报警精确度差、误报和漏报现象多、报警响应时间长、录像数据分析困难等缺陷,从而导致整个系统在安全性和实用性的降低。 近年来,随着网络带宽、计算机处理能力和存储容量的迅速提高,以及各种视频信息处理技术的出现,全程数字化、网络化的视频监控系统优势愈发明显,其高度的开放性、集成性和灵活性为视频监控系统和设备的整体性能提升创造了必要的条件,同时也为整个安防产业的发展提供了更加广阔的发展空间,崭新的应用模式和市场机遇不断涌现,而智能视频监控则是网络化视频监控领域最前沿的应用模式之一。智能视频监控技术能够对场地进行智能的监控,与传统的视频监控技术相比具有许多优点。首先,传统的视频监控系统虽然已经可以满足人们“眼见为实的要求,但这种监视系统要求监控人员不停地监视屏幕以获得视频信息,通过人为的理解和判断得到结论,并做出相应决策,监控人员长期盯着众多的电视监视器成了一项非常繁重的任务。智能视频监控技术的应用则完全改变了这一模式。其通过前端功能强大的分析模块,自动对视频图像进行分析,得到处理结果。此外,运用智能视频监控技术还能大大提高系统响应速度,降低事件误报的概率。智能视频监控具有强大的视频分析处理能力,能够有效地降低无用信息对监控人员的千扰,精确地分析异常事件类型特征,在最短的时间内分析出结果。正是由于智能视频监控技术具有使用方便、监测面积广、设备简单、响应速度快等优点,其取代传统监控技术的趋势越来越明显。智能视频监控技术是计算机视觉领域一个新兴的研究课题。它是指对监控点某个范围内场景的监控,是一种新的侵入探测技术。智能视频监控采用计算机对视频监控信号进行分析,提取目标检测区域内运动物体的活动特征与活动信息,将这些内容与设定的报警规则相比较。当满足报警条件时(即发现异常行为,如不允许侵入的区域出现了侵入行为等),自动产生报警信号。视频智能监控系统是一个庞大、复杂的系统,其关键技术包括了多视频融合和运动检测等方面,涉及计算机视觉、图像处理、模式识别和人工智能等许多学科的内容。其中,运动检测、属于图像处理的范畴,是初级层次的处理,是视频监控系统中研究较多的问题;图像分析和理解属于人工智能的范畴,是高层次的处理,是近年来被广泛关注的研究热点。自上个世纪末期开始,国外科研工作者在视频监控领域进行了大量的研究探索工作,取得了很多成果,并多次召开与此相关的国际会议和研讨会。欧美等发达国家还在这一领域内展开了一些大型项目的研究,如美国国防高级研究计划局资助研制的视频监视与监控系统VSAM,该系统以卡内基梅隆大学为首,麻省理工学院等高校参与,目标是开发自动视频理解技术,用于实现未来战争中那些人力监控费用昂贵、具有高度危险或者人力无法到达的场所的监控;欧盟也资助研发了PRISMATICA系统,该系统融合了多种智能监控检测设备,主要应用于地铁站的安全监控。国内在这一方面起步较晚。目前国内使用的视频监控系统大部分均侧重于对视频数据的压缩、存储和传输,视频终端接收到数据后需要由人来实时监测分析,耗费了大量的人力物力,远远无法满足人们对监控系统日益增长的智能化要求。直到2004年,一种基于视频运动分析检测技术的入侵探测器开始在我国出现,但核心技术仍然是从国外引进,国内技术还不足以转化成产品。不过可喜的是国内有很多研究单位或机构都对此技术进行了研究,并取得了很好的研究成果。中国南京新奕天科技有限公司(Topsky)与香港大学合作开发出了一款高性能智能视频监控设备inkSman,该设备不仅能精确检测出多个移动目标,还能满足禁区、入侵检测等特定的安全需求。2OpenCV的编程环境本章将介绍OpenCV及其环境还有帮助工具的使用,说明Visual C+下的安装与配置,介绍基于OpenCV编程时常用的基本类和基本函数,初步了解OpenCV应用程序的开发过程,最后通过实例来说明如何在Visual C+集成环境下快速建立应用程序框架。2.1 OpenCV简介OpenCV是Intel公司资助的开源计算机视觉库。它由一系列C函数和少量C+类构成,实现了图像处理和计算机视觉方面的很多通用算法。 其重要重要特性包括: 拥有包括300多个C函数的跨平台的中、高层API。它不依赖于其它的外部库尽管也可以使用某些外部库。 对非商业应用和商业应用都是免费(FREE)的。 为Intel Intergrated Perfomance Primitives(IPP)提供了透明接口。这意味着如果有为特定处理器优化的的IPP库,OpenCV将在运行时自动加载这些库。 在过去的十年,随着处理器速度和内存容量以摩尔定律增长,计算机视觉的研究和应用也得到了迅速的发展。以往传统的开发方法要求工程人员在完成的硬件设计的同时,自己编码实现所有底层的算法,所有的图像处理函数都要从头编写,既造成时间和精力上的浪费,又难以保证稳定性、实用性和通用性,越来越难以满足现实的需求。为了解决理论到应用的难题,出现了众多的计算机视觉和图像处理软件包。大多数软件包是用C/C+编写的。例如,TargetJr及其后续版本VXL(the Vision something LIbrarise)就是这样一个C+库的集合,在满足的小型、快速和稳固的系统的开发要求的同时提供了多平台移植性。Gandalf提供了计算机视觉和数值计算库,适合于可移植平台的视觉应用软件的开发。Delft科学图像处理库DIPlib是另一个科学图像处理C程序库.包含了许多图像数据多维分析和处理函数。同时许多商用图像处理和计算机视觉软件包也得到相应开发。MVTec公司开发的HALCON是其中之一,它包含了C/C+代码的图像处理库。LabView在Nl图像处理硬件的支持下能加速图像处理。由微软公司开发的SDK是一个底层的图像操作分析的C+库。在Matlab中的图像处理工具包以及在Mathematica中的数字图像处理软件包都是较为强大的图像处理工具,同时这两个软件包兼有许多高级数学计算功能。由Aurora公司开发的LEADTOOLS是一套商用化计算机视觉包,它包括了图像处理服务器开发工具。允许用户创建各种基于网络的图像处理服务程序。 这些软件包为计算机图像分析和机器视觉提供了极大的便利,但也存在不足之处。大多数软件包没有高级数学计算函数。并且这些软件包都不包括如目标跟踪、摄像机标定、姿态识别、脸谱识别和三维重建等高层函数。 Matlab是功能较为强大的科学计算和分析平台,它提供了图像处理工具包,也提供了较为丰富的数学计算函数,但在Matlab环境下的运行速度令人担忧。虽然Matlab可以通过编译器将m文件转化为C代码。但是转换后的C代码的执行效率和可读性存在较大问题。 除Matlab和LEADTOOLS。大部分软件包不支持网络服务器结构的应用程序的开发;Matlab的网络接口机制较为复杂,且同样存在运行效率的问题。 绝大多数软件包不支持可嵌人性。 本文选取OpenCV进行视频序列图像运动分析,与上述软件包相比,OpenCV的优势在于:纯C代码,源代码开放。开放源代码(open source)是信息技术界从20世纪80年代开始兴起的新名词。源代码是由软件命令电脑执行指定动作的程序语句,是一个软件的核心所在,最著名的开源软件当属芬兰人林努斯托尔瓦兹提出的Linux。开源软件之所以能够风靡世界,首先是其开源的免费特性;此外,由于有全球众多编程者的参与,开源软件一般具有简约精炼、资源占用少、功能集中和安全性好的优点。不同于以往各种由业余爱好者凭兴趣或是根据自己的项目要求而制作的源代码开发包,OpenCV是由Intel资助的开源项目,其代码规范而且具备良好的后继开发和改进能力。 丰富的函数功能,强大的图像和矩阵运算能力: OpenCV提供了数组、序列、矩阵、树等基本结构,也包含了差分方程求解、傅立叶分析、积分运算、特殊函数等众多高级数学计算函数,以及各种图像处理操作和目标跟踪、摄像机校准、三维重建等高级视觉函数。 平台无关性:基于OpenCV开发的程序可以直接在Windows、Unix、Linux、MacOSX、solaris、HP等平台之间相互移植,无需对代码进行任何修改。 程序运行的实时性:完成调试的代码可以编译连接成二进制可执行文件。从而得到较快的运算速度,满足实时性运算的要求。 方便灵活的用户接口。OpenCV作为一个开放的计算机视觉函数库在使用上必然没有Matlab那样解释执行来得方便,而softhitegration将CH和OpenCV绑定起来推出的CH OpenCV,解决了这一使用上的瓶颈。CH本身是一种嵌入式跨平台的C/C一脚本解释器,有自己的外壳程序,可以应用于2D/3D绘图、数值计算、分布式网络运算。CH OpenCV具有以下特性: 1.交互性:如同Matlab,CH OpenCV是交互式的。代码不需要编译就能解释执行。适合于快速建模和应用程序开发。同时为游动代码的计算机视觉提供了可能。2.强大的扩展功能:通过Ch SDK。可以使现在所有的C/C+动态库、静态库和模块成为Ch函数库的一部分.因此Ch函数库的扩充潜能几乎是无限的。先前提及的所有计算机视觉软件包都能成为CH OpenCV补充部分。 3.Web实现性:类似于ASP和Java服务程序。Ch提供了CGI通用网关接口。为CH OpenCV提供了基于web的计算机视觉服务器的开发手段。 4.可嵌入性:与C/C+一编译器不同。Ch能嵌在C/C+应用程序和硬件的机器脚本中。它为用户减轻了开发维护应用程序庞大机器代码的沉重负担。 统一的结构和功能定义,基于Intel处理器指令集开发的优化代码。 可见,作为一个基本的图像处理、计算机视觉和模式识别的开源项目OpenCV可以直接应用于很多领域,作为二次开发的理想工具。本设计用OpenCV的版本为OpenCV1.0。2.2 OpenCV环境介绍 Visual C+是Microsoft 公司开发的基于Windows操作系统的编程工具。像其他的可视化开发环境一样,VC+集程序的代码编辑、编译、链接和调试于一体,给编程人员提供了一个完整而又方便的开发环境,和许多有效的辅助开发工具。同时,因为VC+是微软的产品,用它来编写Windows程序有强大的程序接口和丰富的开发资源的支持,加之VC+严谨的内存管理,在堆栈上良好的分配处理,生成代码的体积小,稳定性高的优点,Visual C+就成为目前主流开发工具。由于OpenCV 的代码是用C和C+所编写而且完全开放,因此可以在Microsoft Visual Studio 环境下很方便地使用OpenCV所提供的库来进行图像处理。在介绍OpenCV编程环境之前,首先要来了解如何安装OpenCV和基本的编程软件,下面的说明假设已经安装完成Microsoft Visual C+ 6.0. 2.2.1 OpenCV的基本结构纷飞 OpenCV主体分为五个模块,其中四个模块如图2-1所示。OpenCV的CV模块包含基本的图像处理函数和高级的计算机视觉算法。ML是机器学习库,包含一些基于统计的分类和聚类工具。HighGUI包含图像和视频输入/输出的函数。CXCore包含OpenCV的一些基本数据结构和相关函数。MLL统计分类器CV图像处理和视觉算法HighGUIGUI图像和视频输入/输出CXCORE基本结构和算法、XML支持、绘图函数图2.1 OpenCV的基本结构图2-1中并没有包含CvAux模块,该模块中一般存放一些即将被淘汰的算法和函数(如基于嵌入式隐马尔可夫模型的人脸识别算法),同时还有一些新出现的实验性的算法和函数(如背景和前景的分割)。2.2.2 OpenCV的特征OpenCV的主要特征有以下几个方面:(1)图像数据的操作 ( 分配、释放、复制、设置和转换)。 (2)图像是视频的输入输出I/O (文件与摄像头的输入、图像和视频文件输出)。(3)矩阵和向量的操作以及线性代数的算法程序(矩阵积、解方程、特征值以及奇异值等)。 (4)各种动态数据结构(列表、队列、集合、树、图等)。 (5)基本的数字图像处理(滤波、边缘检测、角点检测、采样与差值、色彩转换、形态操作、直方图、图像金字塔等)。 (6)结构分析(连接部件、轮廓处理、距离变换、各自距计算、模板匹配、Hough变换、多边形逼近、直线拟合、椭圆拟合、Delaunay 三角划分等)。 (7)摄像头定标(发现与跟踪定标模式、定标、基本矩阵估计、齐次矩阵估计、立体对应)。(8)运动分析(光流、运动分割、跟踪)。 (9)目标识别(特征法、隐马尔可夫模型:HMM)。 (10)基本的GUI (图像与视频显示、键盘和鼠标事件处理、滚动条)。(11)图像标注(线、二次曲线、多边形、画文字) 2.3安装OpenCV本节介绍OpenCV的安装与环境配置。2.3.1安装OpenCV1.0要将OpenCV安装到C:Program FilesOpenCV。在安装时选择将OpenCVbin加入系统变量(AddOpenCVbin to the systerm PATH)。 图2.2 安装界面图2.3 选择安装目录 图2.4 选择附加任务 图2.5 安装进度2.3.2配置Windows环境变量检查C:Program FilesOpenCVbin是否已经被加入到环境变量PATH,如果没有,请加入。加入后需要注销当前Windows用户(或重启)后重新登陆才生效。(可以在任务管理器里重启explorer.exe) 图2.6 系统属性图2.7 查看环境变量2.3.3配置VC+6.0环境与全局设置在菜单Tools-Options-Directories:先设置lib路径,选择Library files,在下方填入路径: C:Program FilesOpenCVlib然后选择include files,在下方填入路径: C:Program FilesOpenCVcxcoreincludeC:Program FilesOpenCVcvincludeC:Program FilesOpenCVcvauxincludeC:Program FilesOpenCVmlincludeC:Program FilesOpenCVotherlibshighguiC:Program FilesOpenCVotherlibscvcaminclude然后选择source files,在下方填入路径: C:Program FilesOpenCVcvsrcC:Program FilesOpenCVcxcoresrcC:Program FilesOpenCVcvauxsrcC:Program FilesOpenCVotherlibshighguiC:Program FilesOpenCVotherlibscvcamsrcwindows最后点击“ok”,完成设置。图2.8 全局设置 2.3.4项目设置(这项配置在每次新建工程时都要配置)每创建一个将要使用OpenCV的VC Project,都需要给它指定需要的lib。菜单:Project-Settings,然后将Setting for选为All Configurations,然后选择右边的link标签,在Object/library modules附加上(cxcore.lib cv.lib ml.lib cvaux.lib highgui.lib cvcam.lib)这些文件。 图2.9 项目设置3OpenCV的体系结构OpenCV本身就具有简单方便的特点,其中的大部分类和库函数在实际应用中都有着特定的背景和现实意义,因此整个库的体系结构显得十分简单明了。 3.1 OpenCV中的常用数据结构体系 OpenCV设计了一些基础的数据类型和一些帮助数据类型,在运用OpeCV函数库进行编程的过程中,常常会需要用到这些结构类型,只有正真了解这些结构才能够很好地利用OpenCV函数库来解决问题。 基础的数据类型包括:图像类的IplImage,矩阵类的CvMat,可变集合类的CvSeq、CvSet、CvGraph以及用于多维柱状图的混合类CvHistogram。帮助数据类型包括:用于表示二维点坐标的CvPoint,用于表示图像宽和高的CvSize,用于表示迭代过程结束条件的CvTermCriteria,用于表示图像转换内核的IplConvKernel和用于表示空间力矩的CvMoments。 下面对CvSize和和IplImage两个比较常用的简单结构进行介绍。 1. CvSize结构CvSize结构用来表示矩形尺寸的结构,结构体中分别定义了矩形的宽高和高度。 定义如下: Typedef struct Cvsize int width; /*矩形宽度,单位为像素*/ int height; /*矩形高度,单位为像素*/ CvSize; 2. Iplmage 结构 通常情况下,使用DIB格式来处理图像,而OpenCV库则是使用“IplImage”结构体来创造和处理图像。由于OpenCV主要针对的是计算机视觉方面的处理,因此在函数库中,最重要的结构体就是IplImage结构。IplImage结构来源于Inter的另外一个函数库IPL,该函数库主要是针对图像处理。使用这种格式的优点是可以比DIB格式表示更多的图像性质,而且可以很方便地存取图像中的像素值,IplImage结构的具体定义如下: Typedef struct IplImage int nSize; /*IplImage大小*/ int ID; /*版本(=0)*/ int nChannels; /*大多数opencv函数支持14个信道*/ int depth; /*像素的位深度*/ int dataOrder; /*0:交叉存取颜色信道。1:分开的颜色信道。只有cvCreateImage可以创建交叉存取图像*/ int origin; /*0:顶左结构,1:底左结构*/ int width; /* 图像宽像素 */ int heighet; /*图像高像素*/ struct_IplROI *roi; /*图像感兴趣区域*/ int imageSize; /*图像数据大小*/ int widthStep; /*排列的图像大小,以字节为单位*/ 3.2 OpenCV中常用类体系 OpenCV1.0版本,包含以下五个部分. (1)CxCore:一些基本函数(各种数据类型的基本类型的基本运算等)。 (2)CV:图像处理和计算机视觉功能(图像处理、结构分析、运动分析、物体跟踪、模式识别、摄像机定标)。 (3)CvAux:一些实验性的函数。 (4)HighGUI:用户交互部分(GUI,图像视频I/O、系统调用函数)。 (5)CvCam:linux版本中已经抛弃,Windows版本中将directx支持加入HighGUI后,CVCam将彻底去掉。 3.3 OpenCV处理图像常用的函数 下面介绍一下OpenCV中常用的一些函数,下面就这些函数分别做说明。 1cvLoadImage 从文件中读取图像IplImage* cvLoadImage(const char* filename, int flags=CV_LOAD_IMAGE_COLOR ); filename :要被读入的文件的文件名。flags :指定读入图像的颜色和深度;指定的颜色可以将输入的图片转为3信道(CV_LOAD_IMAGE_COLOR), 单信道 (CV_LOAD_IMAGE_GRAYSCALE), 或者保持不变(CV_LOAD_IMAGE_ANYCOLOR)。深度指定输入的图像是否转为每个颜色信道每象素8位,(OpenCV的早期版本一样),或者同输入的图像一样保持不变。选中CV_LOAD_IMAGE_ANYDEPTH,则输入图像格式可以为8位无符号,16位无符号,32位有符号或者32位浮点型。如果输入有冲突的标志,将采用较小的数字值。比如CV_LOAD_IMAGE_COLOR CV_LOAD_IMAGE_ANYCOLOR 将载入3信道图。CV_LOAD_IMAGE_ANYCOLOR和CV_LOAD_IMAGE_UNCHANGED是等值的。但是,CV_LOAD_IMAGE_ANYCOLOR有着可以和CV_LOAD_IMAGE_ANYDEPTH同时使用的优点,所以CV_LOAD_IMAGE_UNCHANGED不再使用了。如果想要载入最真实的图像,选择CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR。 函数cvLoadImage从指定文件读入图像,返回读入图像的指针。目前支持如下文件格式:Windows位图文件 - BMP, DIB;JPEG文件 - JPEG, JPG, JPE; 便携式网络图片 - PNG; 便携式图像格式 - PBM,PGM,PPM; Sun rasters - SR,RAS; TIFF文件 - TIFF,TIF; OpenEXR HDR 图片 - EXR; JPEG 2000 图片- jp2。2cvNamedWindow 创建窗口int cvNamedWindow( const char* name, int flags=CV_WINDOW_AUTOSIZE );name :窗口的名字,它被用来区分不同的窗口,并被显示为窗口标题。 flags :窗口属性标志。目前唯一支持的标志是CV_WINDOW_AUTOSIZE。当这个标志被设置后,用户不能手动改变窗口大小,窗口大小会自动调整以适合被显示图像(参考cvShowImage)。 函数cvNamedWindow创建一个可以放置图像和trackbar的窗口。被创建的窗口可以通过它们的名字被引用。 如果已经存在这个名字的窗口,这个函数将不做任何事情。 3cvShowImage 在指定窗口中显示图像 void cvShowImage( const char* name, const CvArr* image );name :窗口的名字。 image :被显示的图像。 函数cvShowImage 在指定窗口中显示图像。如果窗口创建的时候被设定标志CV_WINDOW_AUTOSIZE,那么图像将以原始尺寸显示;否则,图像将被伸缩以适合窗口大小。 4cvWaitKey 等待按键事件 int cvWaitKey( int delay=0 );delay :延迟的毫秒数。 函数cvWaitKey无限制的等待按键事件(delay=0时);或者延迟delay毫秒。返回值为被按键的值,如果超过指定时间则返回-1。 注释:这个函数是HighGUI中唯一能够获取和操作事件的函数,所以在一般的事件处理中,它需要周期地被调用,除非HighGUI被用在某些能够处理事件的环境中。 注:比如在MFC环境下,这个函数不起作用。 5cvSaveImage 保存图像到文件 int cvSaveImage( const char* filename, const CvArr* image );filename :文件名(注明格式)。 image :要保存的图像。 函数cvSaveImage保存图像到指定文件。图像格式的的选择依赖于filename的扩展名,请参考cvLoadImage。只有8位单通道或者3通道(通道顺序为BGR )可以使用这个函数保存。如果格式,深度或者通道不符合要求,请先用cvCvtScale 和cvCvtColor转换;或者使用通用的cvSave保存图像为XML或者YAML格式。 6cvDestroyWindow 销毁一个窗口 void cvDestroyWindow( const char* name );name :要被销毁的窗口的名字。 函数cvDestroyWindow销毁指定名字的窗口。如果没有指定名字的窗口则函数不做任何事情。 返回值:无。 7cvReleaseImage:图像销毁函数 语法:void cvReleaseImage销毁已定义的IplImage指针变量,释放占有的内存空间。 返回值:无。4视频处理在OpenCV的CVcam库中封装了很多针对视频流的处理函数。本章主要介绍使用HighGUI对视屏进行读写处理以及使用CvCam对摄像头和视频流进行处理。使用CvCam库时,要设置预编译的头文件目录*OpenCVotherlibscvcaminclude,并在工程设置加入链接库cvcam.lib. 4.1对视频进行读写处理 此小节介绍视频的读写与保存,还有如何读取硬盘中的AVI文件。4.1.1获取摄像头并显示视频图像 (1)获取摄像头之前先来熟悉以下OpenCV中视频获取的数据结构的管理方式。 1.CVCapture:视频获取结构 说明:OpenCV中的视频获取结构。结构CVCapture没有公共接口,他只能被用来作视频获取函数中使用的一个参数。 2.cvCreateFileCapture:初始化文件中获取视频 语法:CvCapture * cvCreateFileCapture(const char*filename); Filename : const char* 使用视频文件名; 说明:该函数给指定文件的视频流分配和初始化CvCapture。 返回值:分配的CvCapture 3.cvCaptureFromCAM:从摄像头中获取视频 语法:CvCapture * cvCaptureFromCAM(int index); Index : int index指的是摄像头的索引,当只有一个摄像头时,index设为-1。 4.cvQueryFrame:从摄像头或者文件中抓取并返回一帧 语法: IplImage * cvQueryFrame(CvCapture * capture); Capture : CvCapture * 视频获取结构; 说明:函数cvQueryFrame从摄像头或者文件中抓取一帧,然后解压并返回这一帧。返回的图像不可以被用户释放或者修改。 返回值:获取的IplImage指针。 (2)显示视频图像的过程和实现在文件中创建窗口,然后将获取的视频流逐帧的显示在窗口中就形成了视频。对视频文件的处理,可用如下程序。获得视频图像的效果如图4.1。 #include #include #include #include int main( int argc, char* argv ) /声明IplImage指针 IplImage* pFrame = NULL; CvCapture* capture = NULL; /创建窗口 cvNamedWindow(video, 1); /使窗口有序排列 cvMoveWindow(video, 30, 0); /打开摄像头capture = cvCaptureFromCAM(0); /逐帧读取视频 while(pFrame = cvQueryFrame( capture ) cvShowImage(video, pFrame); /显示图像/如果有按键事件,则跳出循环 if( cvWaitKey(2) = 0 ) break; /销毁窗口 cvDestroyWindow(video); cvReleaseCapture(&capture); return 0; 图4.1 获取显示的图像4.1.2对获取的视频进行保存用到的数据结构有如下:1. cvCreateVideoWriter 创建视频文件写入器 typedef struct CvVideoWriter CvVideoWriter;CvVideoWriter* cvCreateVideoWriter( const char* filename, int fourcc, double fps, CvSize frame_size, int is_color=1 );filename :输出视频文件名。 fourcc :四个字符用来表示压缩帧的codec 例如,CV_FOURCC(P,I,M,1)是MPEG-1 codec, CV_FOURCC(M,J,P,G)是motion-jpeg codec等。 在Win32下,如果传入参数-1,可以从一个对话框中选择压缩方法和压缩参数。 fps :被创建视频流的帧率。 frame_size :视频流的大小。 is_color :如果非零,编码器将希望得到彩色帧并进行编码;否则,是灰度帧(只有在Windows下支持这个标志)。 函数cvCreateVideoWriter创建视频写入器结构。2. cvWriteFrame 写入一帧到一个视频文件中 int cvWriteFrame( CvVideoWriter* writer, const IplImage* image );writer :视频写入器结构。 image :被写入的帧。 函数cvWriteFrame写入附加到视频文件一帧。4.1.3读取AVI视频用到的数据结构有如下:1. cvCreateFileCapture 初始化从文件中获取视频 CvCapture* cvCreateFileCapture( const char* filename );filename :视频文件名。 函数cvCreateFileCapture给指定文件中的视频流分配和初始化CvCapture结构。 当分配的结构不再使用的时候,它应该使用cvReleaseCapture函数释放掉。(成功从文件中获取视频之后播放视频的操作和从摄像头捕获视频流后的操作是一样的,用cvQueryFrame()和cvShowImage()显示出视频即可。)4.2小结在设计中对获取的视频进行保存的函数cvCreateVideoWriter()中的用四个字符来表示压缩帧的codec的fourcc变量,传入的参数用的是-1,在运行后的对话框中选择压缩方法和压缩参数,否则无法正确的保存视频文件;要想保存的视频文件可以播放还要安装divx codec控件。要读取硬盘中的AVI文件要安装K-Lite_Codec_Pack_710_Mega,此包是一套Video codec解码器的组合,提供了Video For Windows的接口,而OpenCV打开视频文件就是用的此接口。5运动目标监控系统的研究与实现视频序列中运动目标的识别是计算机视觉和图像编码研究的一个重要课题,在计算机导航,智能监控系统,交通检测,医学图像处理以及视频图像压缩和传输等领域都有广泛的应用。 本节使用Microsoft Visual C+6.0结合OpenCV1.0共同实现了一个简单的运动目标监控系统。由于本文主要研究的是运动目标的检测的效果,实验的样本都是摄像头在正常情况下的图像的变化,没有考虑监控中出现的各种特殊的情形(如摄像头晃动,光线突然变化等),因此目前开发的运动目标识别系统只能应用于简单的监控场所,实现对一定区域的简单监控运动检测。如监视的某个区域不允许有物体进入,当有东西进入这个区域时系统就能够检测出有物体的出现,并记录下此时的图像,并能够回放监控的录像。 5.1运动目标监控系统 运动目标监控系统是将视频图像中变化的部分作检测,通过判断图像是否变化,识别出该区域是否有物体闯入。因此整个监控系统主要包括视频获取、背景生成、保存录像、图像变化检测等几个部分。 本系统中的视频图像是来自摄像头实时采集的图像序列。视频捕获获取图像序列获取的帧数n是否小于10更新背景记录变化的图像写入视频前景图是否有变化是否按键跳出循环是否已记录10次还原n值是否回放写入的视频回放写入的视频结束是否否是是否否是否是图5.1 运动目标监控系统工作流程图如图5.1所示,为本运动目标监控系统的工作流程图。系统的视频捕获器不停的将视频信息输入,当缓存视频帧数目达到一定数量(n=10)时系统就会对捕获的一系列视频帧进行加权处理。为了获取是否有运动物体,首先需要产生视频序列的背景,同时为了减少系统的运行时间,考虑到监控场所的背景一般不会很快变化,在系统中缓存了一个背景图像,这个背景图像也设置了一个计时器,若发现背景图像已经生成了很长的时间(如1000帧)或已陈旧(如前景提取的前景图像与以前的不同但是时间过长),则再取10帧的图像使用背景更新算法来更新背景。有了背景之后,就可以运用图像差的方法来提取前景图像。若发现有运动物体进入该区域,则前景图像就会有变化,则记录此时的图像,若没有过一会则重新开始。 5.2基于背景建模的图像处理 本小节介绍背景的生成算法和图像帧的处理方法。5.2.1背景生成算法 本文处理的图像是静止背景序列,这种序列可以用背景相减法得到是否有前景图像,但这需要当前图像对应的背景图像,因此就要进行背景生成。同时场景中的光照等因素是在不断变化的,为了适应这种变化,背景需要有自适应能力,因此对得到的背景还要进行更新,以消除非目标变化的影响。下面将介绍几种常用的背景生成和更新方法,分析其优缺点,并在其原有方法的基础上提出了分组加权更新法,最后进行了实验效果比较。 1. 平均图像法 平均图像法是一个经典的自适应背景生成和更新方法,它是对最近一段时间内的图像求平均,生成一个除运动区域外与当前图像相似的背景图像。假设图像序列为Ii|i=1,2,n,背景图像Bkgn用公式可表示为Bkgn=(I1+I2+In)/n n=1,2,3 (5.1)平均图像法虽然对物体连续运动、大部分时间背景可见的图像序列是有效的,但是在有较多物体运动和物体作慢速运动的情况下效果并不好,这样会使背景中残留较多的运动目标(前景中的目标被归并到了背景中,成为背景的一部分),如果用背景差分的方法检测运动,残留在背景中的先前的目标将出现在差分图像中,被错误地当作一个新目标,影响进一步处理。该算法生成背景图像的效果如5.2(b)图所示。 2. 加权更新法 加权更新法是对平均图像法的改进,它是将得到的当前图像用加权的方法加入到背景图像中,产生了加权更新背景。假设图像序列为Ii|i=1,2,n ,初始背景为Bkg0=(I1+I2+In)/n n=1,2,3 (5.2) 则一般背景为 Bkgk+1=rBkgk+(1-r)In+k+1 k=0,1,2, (5.3)其中,n是初始背景中的帧数目。r是更新因子,表示当前背景图像在新背景中所占的比例,且r的取值在0到1之间。 对于这个方法,如果r的取值在0附近,由于初始背景产生后每来一帧图像算法更新一次背景,因此背景能迅速适应当前图像的变化。极端的情况,当r=0时,当前背景即为前一幅图像。如果r的取值在1附近,背景图像被更新的比例不大,不能适应当前图像的变化。极端的情况,当r=1时背景图像不被更新。如果r取在0.5附近,背景图像被较快地更新,但同时也记录下了目标运动的轨迹,即前几幅图像中的运动也出现在当前背景中,差分时当前图像和前几幅图像中的运动被一起得到(如5.2(c)图所示)。 对于这种方法,静止或慢速运动的目标会成为背景的一部分,也影响进一步的处理。但由于这种方法引入了加权的思想,背景中的已有图像所占比例会随着背景的更新而越来越小,即旧的图像在不断地被更新掉,新的图像不断地进入,背景图像保持相对较新。如果参数选的合适,该方法对光照、场景的变化有较好的自适应能力。 3. 分组加权更新法 在初始背景生成后,加权更新法是对每个当前图像帧都进行一次背景更新,但是一旦当前图像有干扰,干扰便会进入背景中。另外,对用于图像差分的背景图像来说,背景图像和当前图像要有一个合理的间隔,如果两者间隔太短,图像的内容变化太小,则可能检测不到目标的运动;如果两者间隔太大,背景就不能实时,检测到的目标不可靠。因此本文提出了分组加权更新法。这种方法首先将图像序列分组,对每组图像经过取平均后再更新背景,相对于加权平均法来说有一定的抗干扰能力。 假设图像序列为 Ii|i=1,2,N,N+1,N+2,2N,2N+1, ,N为每个分组中的图像数目。定义第k组图像的平均为Avrk=(IkN+1+IkN+1+IkN+1)/N, k=0,1,2 (5.4)则背景图像为Bkgj+1=rBkgj+(1-r)Avrj+1 j=0,1,2 (5.5)其中,初始背景Bkg0=(I1+I2+IN)/N=Avr0,r为更新因子,0r1 (5.6)r控制着背景更新的速率,r=0时更新最快,背景的实时性最好;r=1时背景不更新。分组的大小N既控制背景更新的频率,也控制了当前图像与当前背景图像的时间相隔。 分组更新法实现步骤如下: 先确定每组的图像帧数N,然后进行背景更新: step.1 累加最初的N帧图像,取平均后作为初始背景。step.2 重新累加最近的N帧图像。 step.3 对得到的图像取平均后按“(5.5)”对原背景进行更新。 step.4 如不再需要背景,转step.5,否则转step.2。 step.5 结束。 对于该算法,静止或缓慢运动的目标仍会出现在背景中,差分时会误认为新的目标,影响进一步的处理。但由于它仍具有加权的思想,旧的图像在不断的被更新掉,新的图像在不断的进入,背景图像相对较新,因此对光照,场景的变化有一定的自适应能力。图5.2(d)是这个方法对场景中运动目标由静止而进入背景到目标离开的适应过程。图5.2 原始图像序列,3种背景生成算法生成的背景序列比较图图5.2为背景生成实验效果图,其中 (a)组图像序列为原始视频图像序列中的部分图像,其相应的帧号分别为(从左到右,从上到下):37、54、84、132、162、286、316;(b)组图像为使用平均图像法生成的部分背景图像,其中N=30; (c)组图像为使用加权法生成的部分背景图像,其中N=30, r=0.8;(d)组图像为使用分组加权法生成的部分背景图像,其中N=30,r=0.5。5.2.2对捕获的图像帧的处理 图像序列的背景得到后,运用图像差运算,如果有物体闯入该区域,那么在前景图像中就可以看到图像的变化并记录此时的图像,但此时的图像存在诸多的干扰,其中噪声是很大的一个不利因素。为了准确提取出运动物体,还要对该图像进行相关处理,具体包括:平滑图像,转换为灰度图,去除噪声,图像二值化,图像翻转等处理,下面将做详细介绍。 1. 差图像 差图像是一种经典的运动目标检测方法。因为运动能够导致图像的变化,所以相邻的两帧或多帧图像之间的关系,或当前图像与背景图像之间的关系,尤其是图像差的关系,能较好地体现出运动所带来的变化。 设视频图像序列Ii|i=1,2,n, 对应的背景图像为Bkgi|i1,2,n,那么当前图像和背景图像之间的差分图像为:Di=|Ii-Bkgi|=|f(x,y,ti,S)-Bkg(x,y,ti,S)| x,y0,M-1 (5.7)如图5.4(1)所示,为当前图像5.4(a)与背景图像5.4(b)做差所生成的结果图像。 2. 灰度图的转换 当前的帧减去背景图像后,由于结果图像的每个像素的三个分量R,G,B值不同,所以得到的结果仍为真彩色图像。彩色图像颜色众多,不利于检测运动物体。为了便于后面的二值化处理,需要将该位图转化为灰度图。灰度图像没有颜色上的差异,有的只是亮度上的不同,如图5.4(2)所示。 将像素点的R,G,B三个分量用下面的公式做一下处理,然后将得到的数值再赋给R,G,B,这样就使得一个像素点的三个分量值相等,从而实现了灰度图的转化: fgray(x,y,i)=f(x,y,i,R)0.299+ f(x,y,i,G)0.587+ f(x,y,i,B)0.114 (5.8)该方程式中的f(x,y,i,R),f(x,y,i,G),f(x,y,i,B)分别代表源图像中像素(x,y)的红,绿,蓝三种颜色的分量数值,i表示当前图像序号。 3. 噪声的消除 在图像的生成或传输过程中,由于种种原因会包含物理上的噪声。图像中的噪声可定义为图像中不希望有的部分,或者是图像中不需要的部分。噪声会造成图像的退化,图像的退化是指由场景得到的图像没有能完全的反映场景的真实内容,产生了失真等问题。消除噪声的方法较多,这里采用了中值滤波方法。 中值滤波是把局部区域中灰度的中央值(中值)作为输出灰度值的,它的主要功能就是让与周围像素灰度值的差比较大的像素改取与周围像素值相近的值,所以它对孤立的噪声像素的消除能力很强。中值滤波既能消除噪声又能保持图像细节,如图5.4(3)为对图5.4(2)运用中值滤波后的结果图。 4. 图像二值化 在进行了灰度化处理后,图像中的每一个像素只有一个值,即像素的灰度值,它的大小决定了该像素的明暗程度。为了更加醒目的显示出运动物体,还需要对已经得到的灰度图像做二值化处理,二值化处理后监控人员就可以清晰的从图中看出图像是否有变化。 图像的二值化就是把图像中的像素根据一定的标准分成两种颜色。在提取运动物体目标时,一般需要设置一个阈值,用于判定某像素是否处于运动区域。为了分析图像的特征,常常从图像中分离出对象物,并为了分离图像与背景而采用二值化处理。图像的二值化可以根据下式的阈值处理来进行: (5.9)确定t的方法称为阈值选择。为了能够得到一个合理的阈值,处理的过程中使用了迭代阈值的方法。迭代的方法是基于逼近的思想,阈值可以由程序自动搜索而得到。 迭代阈值的求取步骤如下: 1)求出图像的最大灰度值和最小灰度值,分别记为MAX和MIN,令初始阈值 T0=(MAX+MIN)/2 (5.10)2)根据阈值Tk将图像分割为前景和背景,分别求出两者的平均灰度值Z0和ZB; 3)求出新阈值: Tk+1=(Z0+ZB)/2 (5.11)4) 若Tk+1与Tk相等,则所得即为阈值;否则转2),迭代计算。 如图5.4(4)为图5.4(3)的二值化图像。5.图像的腐蚀经过上面处理后的图像,会夹杂着一些干扰,表现为一些面积较小的离散的白色区域。如果采用滤波的方法比如中值滤波等也能处理噪声,但考虑到这些方法对一些连通数目较多的离散点处理不佳,而且还有些图像要多次使用滤波的方法才能去除图像中的噪声。为了便于统一处理,可以采用一种递归的算法来进行像素点连通数目的判定。 与得到的运动区域相比,离散区域噪声点的一个最大特点就是连通的像素点个数比较少,由此可以通过统计连通点的个数来判断这些区域是否要删去。以当前的像素点为中心,采用递归的方法,查看其周围8个像素点的像素值。如果其中有像素值满足的要求,则再以该点为中心,继续查看该点周围的像素。如此递归下去,直到查看的像素点周围全部是黑点或像素点的个数已经满足统计要求,这时递归结束,从而判断出该点是否是离散的,然后将离散点的像素值设置为0。如图5.4(5)为对图5.4(4)去除离散点后腐蚀的图像。 6. 图像的膨胀 虽然中值滤波在去除噪声的同时可以较好的保护图像的细节,造成的模糊也比较少,但在以上的处理过程中有可能会对目标区域造成一些破坏,诸如边界的
展开阅读全文