第二章 差分法应用
差分法原本为数学概念,在数学与计算机结合的学科中被越来越广泛地应用于图像识别领域,且已经成为了当前主流的识别算法的核心内容,本章将对这一方法的发展历程和使用方法做一个大致的介绍。
第一节 数学中的差分法
在数学中,差分法是一种估计方法。它利用导数的近似公式——两点间函数斜率的线性主部将其替换,使之离散化,从而达到化简的目标。常用于经济数学中和数值比较运算中。另有各种衍生差分法,如有限差分法、中心差分法。
有限差分法(finite difference method)是求解积分微分方程与微分方程的数值解的方法[7]。基本思想是用有限个离散点构成的网格来代替代替连续定解的区域, 这些离散点被称作网格的节点;用在网格上定义的离散的变量函数来近似代替连续的定解区域上的连续的函数变量;用差商来近似代替原方程和定解条件中的微商,积分用积分和来近似,于是原是连续区间内无限的微分方程和定解条件就被代数方程组以有限的形式代替,即为有限差分方程组,解此方程组就得到的值就可以近似代替原问题的解。最后再利用插值法即可得到在整个区域上从离散解向定解近似的近似解。
同样,如果用数值计算法来求偏微分方程的解时,把每一个导数都用有限差分法来近似替代,那么偏微分方程的求解就可以简化为代数求解方式,这就是有限差分法求解。其步骤如下:
首先区域离散化,即把所求偏微分方程的求解区域划分为有限方格; 然后近似替代,将方格的格点用有限差分法近似代替; 最后通过近似方式逼近求解。
中心差分法(central difference method)主要应用于结构动力学,基本原理是用有限差分法近似代替后,采用等时间步长Δt(i)=Δt(Δt为常数),用u表示位移,求近似求速度的中心差分和加速度的中心差分,其值为:
u'(i)=[u(i+1)-u(i-1)]/(2Δt)
u''(i)=[u(i+1)-2u(i)+u(i-1)]/(Δt*Δt)
求得速度和加速度的中心差分以后,就能求解各种结构动力学问题。
第二节 背景差分法和帧间差分法
背景差分法(The background difference method),这种方法在目标检测的过程中,非常依赖背景图像建模,建模的准确程度甚至直接影响识别的最后效果[8]。原则上任何运动目标识别算法,都要满足任何准确性不随背景变化而降低或波动,但是由于运动物体背景具有不可预知性、复杂性、时变性以及外界干扰,如光线照射角度造成的光影变化、背景物体的动作、摄像机的意外晃动、目标场景切换,加大了背景建模和模拟困难度。
6
背景差分法对目标的快速与精确地检测识别都取决于背景图像的获取[9]。但是获取背景图像的时时获取与更新仅仅是理想实验条件下的理论,并不能很好地适应实际使用,但由于背景图像具有时变性,所以需要进行背景重建,即通过视频流中的帧间信息估计与恢复背景,故需选择性地进行背景更新[10]。
帧间差分法(Frame difference method),一种运动目标检测方法,通过检测视频流中的相邻两帧作差分实现目标[11]。这种方法很好的解决了同一背景内多个物体运动和摄像头移动造成的检测准确率波动问题[12]。帧间差可以很好的反映出监控场景内的每一个变化,包括被测目标和背景内任何物体的细小抖动。把两帧之间差的绝对值与动态阈值相比较,根据其大小关系确定有无物体运动
[13]
。以此类推,可获得整个过程内的物体运动状态。这相当于对图像序列进行差分法流程图如下图所示:
图3.1 差分法流程图
物体运动 物体静止 大于阈值 相邻两帧作差 小于阈值 拍摄一组含有被测物体的视频流 背景保存 了时域下的高通滤波。
7
第三章 Opencv的介绍与使用
计算机视觉领域是当今的一门前沿科学,它不仅可以用于图像中的物体分析,还能用于安全和入侵检测系统,自动监视和安全系统,制造业中的产品质量检测系统,摄像机标定,军事应用,无人飞行器,无人汽车和无人水下机器人,非常有发展潜力,但由于当今技术停留在对三维图像的二维化之后作为计算机识别的基本依据上,记录下的数据庞大而精确,很容易被噪声干扰,对于被测物体的识别并不能有效实施,为了能够利用计算机进行高级物体识别运算,opencv应运而生,本章主要介绍了opencv的来源、发展与优势。
第一节 opencv简介
Opencv,全称Open Source Computer Vision Library。1999年由intel发起建立,现在由Willow Garage提供支持。是一个开源发行的跨linux,windows和Mac OS平台计算机视觉库。Opencv是一个轻量级而且高效的视觉库——它由一系列的C 函数和少量 C++ 类构成, Ruby、Python以及MATLAB等语言的接口也同时被包含其中,基本实现了图像处理和计算机视觉方面通用算法。目前最新的opencv版本是2.4.5。OpenCV的C函数,包括300多个跨平台,高层次的API。它不依赖于外部库,尽管这些外部库也可以被使用。OpenCV为用户提供一个透明的接口英特尔?集成性能基元(IPP)。如果检测到特定的处理器优化的IPP库存在,OpenCV可以自动运行加载这些库。
OpenCV 拥有包括 500 多个C,c++函数的跨平台的中、高层 API。它不依赖于其它的外部库——尽管也可以使用某些外部库。
在计算机视觉市场潜力飞速增长的当今,却很少有一款兼容性高,平台广泛的视觉函数库,已有的大多数函数库或者正在研究,或者商业化明显,价格昂贵,亦或者使用方向明显,不具有普遍性。OpenCV的出现很有效的解决了这一问题。高性能的C代码编程极大地提高了运行速度,还可以通过购买intel的IPP高性能多媒体函数库(Integrated Performance Primitives)进一步得到更高的处理速度,相比其他函数库优势非常明显,在很多国家都有广泛应用。近几年来随着移动设备android系统的兴起,基于android系统的OpenCV发展肯定会上升到一个新阶段。
OpenCV的应用领域也非常广泛除了物体识别、运动分析、动作识别和运动跟踪这几个传统的使用领域以外[14],还被越来越多的投入于人机互动、图像分割、人脸识别、机器人运动分析、机器视觉和结构分析等新兴技术之中。 OpenCV历史发展
8
1999年1月,Intel主导下CVL项目启动。其主要研究目标面对人机界面,和能被UI调用的实时计算机视觉库,其目的是为了自己旗下的Intel处理器做了特定优化。
2000年6月,首个开源版本OpenCV alpha 3发布。
2000年12月,首个基于linux平台的OpenCV beta 1发布。之间相隔6年时间,开发商对opencv移植Mac OS平台做了深层研究
2006年,基于Mac OS的OpenCV 1.0版本发布。 2009年9月,OpenCV 1.2(beta2.0)版本发布。 2009年10月1日,OpenCV 2.0版本发布。 2010年12月6日,OpenCV 2.2版本发布。 2011年8月,OpenCV 2.3发布。
2012年4月2日,发布OpenCV 2.4版本。
第二节 有关图像识别的opencv函数
(1) CvSize 矩形框大小,以像素为精度
typedef struct CvSize {
int width; // 矩形宽 int height; // 矩形高 } CvSize; // 构造函数
inline CvSize cvSize( int width, int height );
(2) IplImage IPL 图像头
typedef struct _IplImage {
int nSize; // 将IplImage的尺寸定义 int ID; // 版本 (=0)
int nChannels; // 定义通道(很多OpenCV函数支持4个以内的通道) int alphaChannel; // 定义alphaChannel,OpenCV的函数库会忽略这个通道
int depth; // 定义深度,其可支持: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16U和IPL_DEPTH_16S还有IPL_DEPTH_32S, IPL_DEPTH_32F 和 IPL_DEPTH_64F
char colorModel[4]; // 定义colorModel[4],其亦被忽略
9
char channelSeq[4]; // 定义channelSeq[4],其亦被忽略
int dataOrder; // 定义颜色通道,其中0被称为交叉存取,1被称为分开存取,交叉存取只有cvCreateImage可实现
int origin; // 定义结构,其中0为顶—左,1为底—左
int align; // 图像行,(取值为4 或者 8). OpenCV不会调用这个值,在它的位置出现的是widthStep
int width; //定义图像的宽度值 int height; // 定义图像高度值
struct _IplROI *roi; // 图像集中观察区域。当这个数值不是0的时候程序只对这个被定义的区域进行运算
struct _IplImage *maskROI; // 这个值是一个OpenCV一直将其设定为空的值
void *imageId; //这个值是一个 OpenCV一直将其设定为空的值 struct _IplTileInfo *tileInfo; // 这个值是一个 OpenCV必定将其设定为空的值
int imageSize; //定义所用图像的数据尺寸(在交叉存取格式下imageSize=image->height*image->widthStep),以字节为单位
char *imageData; // 定义图像数据
int widthStep; //定义图像宽度,单位是字节
int BorderMode[4]; // 定义边界结束的模式, OpenCV不会调用 int BorderConst[4]; // 定义边界结束的模式, OpenCV不会调用
char *imageDataOrigin; // 指针指向另一个图像数据结构(不一定要定义的),它的目的是把错误的图像的内存改正过来 }
IplImage:IplImage源于 Intel Image Processing Library(自带)。OpenCV 仅仅调用某个一个子集:
? alpha通道在 OpenCV中不会被调用。
? colorModel 与channelSeq 两个定义不会被OpenCV调用。 OpenCV中仅有的颜色转换函数是cvCvtColor,它把初始图像的颜色空间里边的目标物体的颜色空间一同对待,一并看作cvCvtColor的一个参数。
? 数据顺序 必须是IPL_DATA_ORDER_PIXEL (颜色通道存取方式为交叉存取), 但是平面图像的被选择通道可被处理,好像COI(集中观察通道)被设定过。
? 当 widthStep 被用于去接近图像行序列,排列是被OpenCV忽略的. ? 不支持maskROI。处理MASK的函数把它看成一个分离参数. 它在
10