多年来在从事计算机视觉研究的过程中,一直需要这样一个平台,一方面可以提供众多成熟稳定的检测、跟踪、轨迹分析算法,另一方面具备良好的编程接口,这样就可以将自己的算法很方便的嫁接进这个系统,测试和对比各种算法的优劣性能。而Intel OpenCV[1] 视频监控(Video Surveillance)模块恰恰提供了这样一个功能强大的平台,在下文中简称为VS。
从Intel OpenCV 1.0版本开始,其辅助库CVAUX中就增加了VS模块,直至OpenCV 2.2版本,该模块都相对稳定的存在。然而OpenCV提供的VS的相关资料相当少,在官方的帮助文档中甚至只字未提,国内外也少有相关的研究和介绍,这也是VS长期未被研发人员广泛关注的原因之一。
值得庆幸的,也是OpenCV最大的优势就在于其开源性。通过深入剖析VS的源代码,我们可以理清整个VS框架的脉络,探索其中的算法原理和实现方法。本文对VS的架构和算法体系进行了剖析和梳理,在此基础上给出一个该架构应用于行人统计的实例。
OpenCV是Intel公司开发的广受关注的计算机视觉开源库,其算法覆盖面广、实时性好。CVAUX是OpenCV的辅助类库,VS则是其中一个重要组成部分。用VC++6.0打开OpenCV 1.0工程源码,可以在CVAUX下看到VS结构和类定义,VS类多数以CvBlob开头。通过梳理VS的各个类和结构间的关系,可以归纳得到VS的UML关系图,从整体上把握VS的架构,如图1所示。
类似于MSMFC中的CObject,VS中的所有的类都有一个共同的父类CvVSModule,主要提供各个模块通用的参数的读写、拷贝等功能。VS提供了目标检测、跟踪和轨迹分析的算法接口:CvFGDetector,CvBlobDetector,CvBlobTracker,CvBlobTrackGen,CvBlobTrackPostProc,CvBlobTrackAnalysis,分别是前景检测、新目标检测、目标跟踪、轨迹生成、跟踪后处理、轨迹分析等六组算法接口,这些接口类是大多数VS类的父类。另外还有一个CvBlobTrackerAuto接口,其功能是对以上算法进行链接、调度,用于对整个算法流程和数据传递的控制。
VS中的很多类并没有导出用户接口,不能直接调用,而是提供了相应的全局函数作为唯一的用户接口。这是模式设计中类工厂的思想,有效的屏蔽了构建类实例的细节,这种设计思想被大量应用于COM技术中。
图1 OpenCV VS UML图
OpenCVVS覆盖了许多主流的检测、跟踪与轨迹分析方法,如前文中提到的6类算法,分别是:前景检测、新目标检测、目标跟踪、轨迹生成、跟踪后处理、轨迹分析,除了轨迹生成用于轨迹数据的保存以外,其他5个部分都是标准的视频监控算法体系中不可或缺的部分。在VS的标准应用中,算法的执行流程如图2所示。
图2 VS算法流程图
下面对VS算法体系进行简要介绍并给出参考文献,表1列举了各组算法和接口,方便读者查阅。
1)算法流程控制(CvBlobTrackerAuto)
整个算法流程的控制在接口类CvBlobTrackerAuto的子类中完成。VS中提供了一个范本,就是CvBlobTrackerAuto1,通过查看CvBlobTrackerAuto1::Process(),可以洞悉整个算法的标准流程。当然用户也可以在遵循接口CvBlobTrackerAuto的基础上进行扩展,重载Process(),构建自己的视频监控算法流程。
2)前景检测(CvFGDetector)
在视频监控中,前景一般是指相对于背景的运动区域,即通常关注的运动目标,如行人、车辆等。前景检测的方法大致可以分为三类:背景差法、帧差法和光流法。背景差法通过对对背景进行建模来检测运动的前景,由于其准确性、鲁棒性和实时性的优势受关注较多。
CvFGDetector是前景检测类的接口,在其子类CvFGDetectorBase中包含了[2] [3]两种背景差方法的实现,后者是被广泛研究和应用的混合高斯模型[4](MOG-Mixture Of Gaussians)。
OpenCV中还提供了一种基于码本的背景差方法[5] 的实现,只是该算法还没有整合进VS架构中,这个扩展工作有待完成。
3)新目标检测(CvBlobDetector)
新目标检测是多目标跟踪系统中的重要环节,主要用于判断检测到的目标是否是新出现的目标。该模块对每帧中检测到的目标进行判断,如果判定为已经存在的目标则参与之前已存在的跟踪滤波,如果判定为新目标则需要启动新的目标跟踪并进行初始化(分配新ID等)。
CvBlobDetector接口在前景掩模中检测新进入场景的Blob(块),子类有两个,分别是CvBlobDetectorSimple和CvBlobDetectorCC,原理可参考文献为[6]。新目标的判断准则是:当连续多帧图像中包含该连通区域,且具有一致的合理的速度。CvBlobDetectorCC与CvBlobDetectorSimple一个最显著的不同在于引入了CvObjectDetector,可用于检测分离的目标块。
4)目标跟踪(CvBlobTracker)
目标跟踪模块覆盖了众多熟悉的算法,如Kalman滤波、粒子滤波、MeanShift等,在表1中给出相应的接口及对应的功能。对MeanShift和粒子滤波感兴趣的读者可参考[7][8][9]。
目标跟踪应用非常广泛,而多目标跟踪由于其逻辑关系比较复杂,其算法的实现在许多系统应用中都是一个难点,而VS恰恰提供了众多跟踪算法的多目标版本,为广大研发人员提供了方便。
5)轨迹生成(CvBlobTrackGen)
轨迹生成模块保存目标检测和跟踪的特征至数据文件,为事后分析提供方便。接口为CvBlobTrackGen,子类包括CvBlobTrackGen1和CvBlobTrackGenYML,前者在目标跟踪结束后,以文本格式保存整个目标轨迹的序列参数,后者与帧数据同步,以YML格式保存当前帧中的目标信息参数。
6)跟踪后处理(CvBlobTrackPostProc)
跟踪后处理是一个可选模块,主要用于跟踪滤波后对目标轨迹的平滑滤波,接口为CvBlobTrackPostProc,表1中列举了算法的功能和接口。
7)轨迹分析(CvBlobTrackAnalysis)
当某个目标跟踪结束后,会产生一个轨迹,CvBlobTrackAnalysis的子类用于对轨迹进行数据分析。轨迹分析方法比较多,表1中列举了分析算法的功能和接口。
表1 OpenCV VS中的算法及接口
VS模块 |
算法及功能 |
用户调用接口 |
算法流程控制 |
调度整个跟踪算法及数据流 |
CvBlobTrackerAuto* cvCreateBlobTrackerAuto1(CvBlobTrackerAutoParam1* param); |
前景检测 |
背景差MOG |
CvFGDetector* cvCreateFGDetectorBase(int type, void *param); |
新目标检测 |
标准方法:连通区域一致性分析 |
CvBlobDetector* cvCreateBlobDetectorSimple();
|
加入了分离目标检测 |
CvBlobDetector* cvCreateBlobDetectorCC(); |
|
目标跟踪 |
连通区域跟踪 |
CvBlobTracker* cvCreateBlobTrackerCC(); |
连通区域跟踪 + 基于MeanShift 粒子滤波的碰撞分析 |
CvBlobTracker* cvCreateBlobTrackerCCMSPF(); |
|
MeanShift 算法 |
CvBlobTracker* cvCreateBlobTrackerMS(); |
|
基于前景的MeanShift 算法 |
CvBlobTracker* cvCreateBlobTrackerMSFG(); |
|
基于MeanShift 权重的粒子滤波 |
CvBlobTracker* cvCreateBlobTrackerMSPF();
|
|
轨迹生成 |
文本方式 |
CvBlobTrackGen* cvCreateModuleBlobTrackGen1(); |
YML方式 |
CvBlobTrackGen* cvCreateModuleBlobTrackGenYML(); |
|
跟踪后处理 |
轨迹矩形窗时间平均
|
CvBlobTrackPostProc* cvCreateModuleBlobTrackPostProcTimeAverRect() |
轨迹指数窗时间平均
|
CvBlobTrackPostProc* cvCreateModuleBlobTrackPostProcTimeAverExp() |
|
目标方位、尺寸的Kalman滤波平滑 |
CvBlobTrackPostProc* cvCreateModuleBlobTrackPostProcKalman() |
|
轨迹分析 |
5维矢量直方图分析(x,y,vx,vy,state) |
CvBlobTrackAnalysis* cvCreateModuleBlobTrackAnalysisHistPVS(); |
2维矢量直方图分析(x,y) |
CvBlobTrackAnalysis* cvCreateModuleBlobTrackAnalysisHistP(); |
|
4维矢量直方图分析(x,y,vx,vy) |
CvBlobTrackAnalysis* cvCreateModuleBlobTrackAnalysisHistPV(); |
|
起始点4维矢量直方图分析(startpos,endpos) |
CvBlobTrackAnalysis* cvCreateModuleBlobTrackAnalysisHistSS(); |
|
轨迹间距离分析 |
CvBlobTrackAnalysis* cvCreateModuleBlobTrackAnalysisTrackDist(); |
|
整合上述多种分析方法 |
CvBlobTrackAnalysis* cvCreateModuleBlobTrackAnalysisIOR(); |
VS架构可以应用到和视频目标检测和跟踪相关的诸多领域,本节以行人统计为例进行说明。行人统计是指对通过某个区域行人的数量和方向进行统计,主要应用在安防、交通等领域。
参考OpenCV VS架构,行人统计可由前景检测,新目标检测,目标跟踪,跟踪后处理和轨迹分析5模块组成。在系统设计中,主要的区别和改进在以下三个部分:
1)为了对整个行人统计算法流程进行控制,在继承接口CvBlobTrackerAuto的基础上设计了CvBlobTrackerAuto2,对行人统计中各个算法和数据流进行调度。VS的跟踪是基于目标块,而在行人统计中,往往出现单个目标块中有多个粘连的行人的情况。为了能够对粘连的人群进行统计,在该模块中加入了行人头部检测算法。
2)行人统计对系统的实时性要求比较高,而传统的MOG(混合高斯模型)[4]方法速度较慢,为此我们采用了一种自适应多模快速背景差算法[10]。在继承接口CvFGDetector的基础上设计了CvFGDetectorRunAver模块,并在该模块中加入了阴影、噪声、亮光的去除等算法,以增强前景目标检测的鲁棒性。
3)行人统计的重点在于对行人轨迹的序列特征进行分析,为此在继承接口CvBlobTrackAnalysis的基础上设计了CvBlobTrackAnalysisDir行人轨迹分析模块。该模块主要完成两个功能:a)通过目标序列特征,如头部的数量、目标块的大小、宽高比、运动方向、速度等特征,对目标的种类做出判断,如汽车、单车、行人等;b)通过对轨迹点序列的拟合分析,行人的方向、路径做出判断,最后给出统计结果。同时,为了去除摄像机倾斜观测造成的目标变形(远小近大)影响,在对相关的块目标特征数据进行了射影变换的校正。
基于VS框架我们在较短的时间内搭建了一个灵活高效的行人统计系统,如图3所示,该系统具备了完善的多目标检测、跟踪和轨迹分析的能力,在稳定性、准确性和实时性方面都达到了较高的水准。
OpenCVVS为视频目标检测、跟踪研究提供了一个通用、高效的平台,该平台覆盖了许多主流的检测、跟踪与轨迹分析算法,具有广阔的应用领域,但由于缺少相关资料而不为广大研究人员所熟悉。本文在源码分析的基础上对VS的架构和算法体系进行了剖析,并给出了一个VS架构应用实例:行人统计。VS内容非常丰富,由于篇幅关系,文中只能提纲挈领,对VS的算法及应用没有展开讨论,感兴趣的读者可以参考[11]。