基于opencv目标跟踪与检测课程毕业设计论文

(此文档为word格式,下载后您可任意编辑修改!)

课程设计Ⅰ设计报告

题目:基于Opencv运动目标跟踪与检测

学号:

姓名:

学院:信息学院

专业班级:计算机软件2班

指导教师:黄文培

设计时间: 2012.9.3

摘要

本文先介绍一种开放源代码的计算机视觉类库OpenCV,主要阐述该类库的特点

及其结构,然后介绍本人学习opencv一些基本功能的实现以及结果。最后通过“检测一个视频中的运动物体”这一实例探讨了使用OpenCV进行编程的方法。关键词图像处理目标检测 OpenCV IplImage VC++

目录

1 概述 (4)

1.1目标跟踪与检测课程设计目的 (4)

1.2目标跟踪与检测设计任务与要求 (4)

1.3目标跟踪与检测的开发环境 (4)

2 目标跟踪与检测系统设计的基本概念与原理 (4)

2.1目标跟踪与检测的基本概念与知识 (4)

2.2目标跟踪与检测系统设计实现平台的搭建 (12)

2.1与目标跟踪与检测相关的一些基本功能 (18)

3 基于OPENCV运动目标跟踪与检测系统实现的详细说明 (33)

3.1一般目标跟踪的实现 (33)

3.2本文的检测算法 (34)

3.3C AMSHIFT算法原理及其O PENCV实现 (35)

3.4目标跟踪与检测系统的运行结果 (39)

4 目标跟踪与检测的课程设计总结 (44)

参考文献

1概述

1.1目标跟踪与检测课程设计目的

1.通过实验了解opencv运动物体跟踪的数据结构、函数以及基本框架;

2.通过实验提高对于图像与视频的认识;

3.通过学习,掌握基本的opencv图像与视频的知识。

4.通过实验将理论和实践联系起来,提升对于理论知识的认识;

1.2目标跟踪与检测设计任务与要求

1.通过学习做该课程设计,掌握一些opencv的基本知识以及图像与视频的知识。

2.调用基于intel 的开源视觉库opencv,实现视频或者摄像头的监控;

3.编程实现对进入视觉范围内的运动物体实施监测;

1.3 目标跟踪与检测Opencv开发环境

一台pc机,Microsoft Visual C++ 6.0

2 系统设计的基本概念与原理

2.1 目标跟踪与检测基本概念与知识

2.1.1. OpenCV简介

开放源代码的计算机视觉类库OpenCV (Intel Open Source Computer Vision Library)由英特尔公司开发.它是一套可免费获得的由一些C函数和C++类所组成的库,用来实现一些常用的图像处理及计算机视觉算法。OpenCV主要用于对图像进行一些高级处理,比如说特征检测与跟踪、运动分析、目标分割与识别以及3D重建等。

它有以下特点;开放C源码,基于Intel处理器指令集开发的优化代码,统一的结构和功能定义,强大的图像和矩阵运算能力,方便灵活的用户接口,同时支持WINDOWS、LINUX平台等。

(1) OpenVC的数据结构

OpenCV提供了多种基本数据类型,虽然这些数据类型在C语言中不是基本类型,但结构都很简单,可将它们作为原子类型。在运用OpenCV函数库进行编

程的过程中,常常会需要用到这些结构类型,只有真正了解这些结构才能够很好地利用OpenCV函数库来解决问题

基础的数据类型包括:CvPoint基于二维整形坐标轴的点.CvSize矩形框大小。CvRect矩形框的偏移和大小,以像素为精度,CvMat多通道矩阵等。

OpenCV提供了多种基本数据类型,虽然这些数据类型在C语言中不是基本类型,但结构都很简单,可将它们作为原子类型。在运用OpenCV函数库进行编程的过程中,常常会需要用到这些结构类型,只有真正了解这些结构才能够很好地利用OpenCV函数库来解决问题。

下面对几个比较常用的简单结构进行介绍。

1)CvPoint结构

在这些数据类型中最简单的就是CvPoint,它表示二维坐标系下的点,类型为整型,定义如下:

typedef struct CvPoint

{

int x; * x坐标, 通常以0为基点 *

int y; * y坐标, 通常以0为基点 *

} CvPoint;

2)CvSize结构

CvSize结构用来表示矩形框大小,以像素为精度,结构体中分别定义了矩形的宽高和高度,定义如下:

typedef struct Cvsize

{

int width; *矩形宽度,单位为像素*

int ; *0:顶—左结构,1:底—左结构*

int width; * 图像宽像素 *

int 链函数cvApprexChains,函数cvMaxRect寻找包含两个输入矩形的具有最小面积的矩形边界等。

(3)运动分析与对象跟踪函数

例如背景重建函数cvAcc.用光流法或动态轮廓模型来实现目标跟踪的函数

cvCalcOp tiealFlowBM 和cvSnake Image以及卡尔曼滤波函数CvKalman 等。

(4)摄像机标定和3D重建函数

例如函数cvCalibrateCamera利用目标图像模式和目标模式的象素点信息计算相机参数.函数cvFindExtrinsieCamera_Params寻找模式的摄像机外参数矩阵等。

(5)模式识别

例如函数cvLoadHaarClassifierCascade用于从文件中装载训练好的利用海尔特征的级联分类器.或者从OpenCV中嵌入的分类器数据库中导入。

(6) GUI与视频处理函数

包括有高级图形用户接口highGUI用以实现对图像的载入、显示及保存等基本操作以及用以实现视频输入输出及处理的函数。

根据上述的函数体系。程序开发者可以根据自己所开发应用程序所要实现的功能来方便地选择所需的库函数.从而大大减少开发时间和精力。缩短程序开发的周期。

(3)OpenCV常用的函数

下面介绍一下OpenCV中常用的几个函数,也是利用OpenCV进行特定目标体识别的过程中常用到的函数,分别说明如下。

1)cvLoadImage( ):载入图像

IplImage* cvLoadImage(

const char* filename,

int iscolor=CV_LOAD_IMAGE_COLOR

);

filename:要被读入的文件的文件名。

iscolor:指定读入图像的颜色和深度。指定的颜色可以将输入的图片转为3信道(CV_LOAD_IMAGE_COLOR),单信道(CV_LOAD_IMAGE_GRAYSCALE),或者保持不变(CV_LOAD_IMAGE_ANYCOLOR)。

2)cvShowImage( ):在指定窗口中显示图像

void cvShowImage(

const char* name,

const CvArr* image

);

name:窗口的名字。

image:被显示的图像。

(3)IplImage* cvCreateImage分配图像空间

(CvSize size, int depth, int channels);

size: cvSize(width,)是将运动的物体从背景中检测出来,人们希望设计能适用于各种监控环境,不受光照、天气等外界因素影响的目标检测算法。但这种算法难免复杂度大,现有一些算法大多是针对某一类问题提出的,主要包括背景减法、相邻帧差法等。

(1)背景减法

背景减法(background subtraction)是目前运动目标检测的主流方法,其基本思想是将当前每一帧图像与事先存储或实时获取的背景图像相减,计算出与背景偏离超过一定阈值的区域作为运动区域。该算法实现简单,相减结果直接给出目标的位置、大小、形状等信息,能够提供关于运动目标区域的完整描述,特别是对于摄像机静止的情况,背景减法是实现运动目标实时检测和提取的首选方法。

背景减法实现的关键是背景模型的获取和更新。背景获取算法通常要求在场景中存在运动目标的情况下获取背景图像,更新过程使背景能够适应场景的各种变化和干扰,如外界光线的改变,背景中对象的扰动和固定对象的移动,阴影的影响等。

一种典型的背景建模方法是用混合高斯模型描述背景图像像素值的分布,目标检测过程中判断图像的当前像素值是否符合该分布,若是被判为前景点,否则为背景点。同时根据新获取的图像,对背景图像参数进行自适应更新。该方法能够可靠处理光照变化、背景混乱运动的干扰以及长时间的场景变化等。在此基础上,对背景、静止目标和运动目标三者采取不同的更新策略,以减弱背景更新过程中运动目标对背景的影响。

(2)相邻帧差法

相邻帧差法(temporal differencing)利用序列中连续两帧或几帧图像间

的差异进行目标的检测和提取。由于相邻帧的时间间隔一般较短,因此算法对场景中的动态变化不太敏感,具有较强的自适应性。但该方法一般不能完全提取出所有相关的特征像素点,在运动实体内容易产生空洞现象。累积图像差分法进一步计算一阶和二阶差分图像,利用时间序列图像的历史积累信息,能够适应低对比度有噪时间序列,判断复杂情况下目标运动的多种状态。

以上两种目标检测方法适用于背景固定不变的情形,对于背景发生运动的情况,需要提前对由摄像机引起的背景移动进行补偿。帧间差分法是一种通过对视频图像序列中相邻两帧作差分运算来获得运动目标轮廓的方法,它可以很好地适用于存在多个运动目标和摄像机移动的情况。当监控场景中出现异常物体运动时,帧与帧之间会出现较为明显的差别,两帧相减,得到两帧图像亮度差的绝对值,判断它是否大于阈值来分析视频或图像序列的运动特性,确定图像序列中有无物体运动。图像序列逐帧的差分,相当于对图像序列进行了时域下的高通滤波。

帧间差分法的优点是:算法实现简单,程序设计复杂度低;对光线等场景变化不太敏感,能够适应各种动态环境,稳定性较好。其缺点是:不能提取出对象的完整区域,只能提取出边界;同时依赖于选择的帧间时间间隔。对快速运动的物体,需要选择较小的时间间隔,如果选择不合适,当物体在前后两帧中没有重叠时,会被检测为两个分开的物体:而对慢速运动的物体,应该选择较大的时间差,如果时间选择不适当,当物体在前后两帧中几乎完全重叠时,则检测不到物体。

(2)光流法

光流法检测运动物体的基本原理是:给图像中的每一个像素点赋予一个速度矢量,这就形成了一个图像运动场,在运动的一个特定时刻,图像上的点与三维物体上的点一一对应,这种对应关系可由投影关系得到,根据各个像素点的速度矢量特征,可以对图像进行动态分析。如果图像中没有运动物体,则光流矢量在整个图像区域是连续变化的。当图像中有运动物体时,目标和图像背景存在相对运动,运动物体所形成的速度矢量必然和邻域背景速度矢量不同,从而检测出运动物体及位置。采用光流法进行运动物体检测的问题主要在于大多数光流法计算耗时,实时性和实用性都较差。

但是光流法的优点在于光流不仅携带了运动物体的运动信息,而且还携带了有关景物三维结构的丰富信息,它能够在不知道场景的任何信息的情况下,检测出运动对象。

2.1.3.关于图像与视频

1.图像的种类:计算机的图像分为两大类,即位图图像和矢量图形。

位图:采用点阵方式构成图像,可以表现丰富的图像色彩,但是文件占用存储空间较大。

矢量图:以数学矢量方式记录图像,适合表示色彩较少的图像,但是可以表现和保持清晰的图像曲线,缩小、放大不会失真,文件占用存储空间较小。像素:位图图像是由许多个离散的点组成,它们是组成图像的基本单元,被称为像素。

2. 关于图像的通道(nchannels)问题:

1通道:描述一个像素点,如果是灰度,那么只需要一个数值来描述它,就是单通道,为1。

2通道:2通道图像不常见,通常在程序处理中会用到,如傅里叶变换,可能会用到,一个通道为实数,一个通道为虚数,主要是编程方便;还有一种情况就是16位图像,本来是3通道,但是为了减少数据量,压缩为16位,刚好两个通道,常见格式有RGB555或RGB565,也就是说R占5位,G占5或6位,B占5位,也有RGBA5551格式。古老的格式,不用也罢。

3通道:如果一个像素点,由RGB三种颜色来描述它,就是三通道,为3。

4通道:windows的bmp有时候是一个四通道图像,R、G、B加上一个A通道,一般叫做alpha通道,表示透明度。

3. 关于视频

视频(Video)泛指将一系列静态影像以电信号方式加以捕捉,纪录,处理,储存,传送,与重现的各种技术。连续的图像变化每秒超过24帧(frame)画面以上时,根据视觉暂留原理,人眼无法辨别单幅的静态画面;看上去是平滑连续的视觉效果,这样连续的画面叫做视频。

帧数:帧数就是在1秒钟时间里传输的图片的量,也可以理解为图形处理器每秒钟能够刷新几次,通常用fps(Frames Per Second)表示。每一帧都是静止的

图象,快速连续地显示帧便形成了运动的假象。高的帧率可以得到更流畅、更逼真的动画。每秒钟帧数 (fps) 愈多,所显示的动作就会愈流畅。但文件大小会变得越大。帧率:帧率(Frame rate)是用于测量显示帧数的量度。所谓的测量单位为每秒显示帧数(Frames per Second,简称:FPS)或“赫兹”(Hz)。此词多用于影视制作和电子游戏。 Frame rate中文常译为“画面更新率”或“帧率”,是指视频格式每秒钟播放的静态画面数量。典型的画面更新率由早期的每秒6或8张(frame per second,简称fps),要达成最基本的视觉暂留效果大约需要10fps的速度。

2.2 系统设计实现平台的搭建

开发平台搭建

安装、下载Opencv,并在Microsoft Visual C++ 6.0编译环境下配置opencv。在vc++2006中建立新工程以后,在工程设置里添加需要的opencv库,并在程序文件中包含opencv的头文件。

2.2.1安装OpenCV

从下载OpenCV安装程序。假如要将OpenCV安装到C:\Program Files\OpenCV。(下面附图为OpenCV 1.0rc1的安装界面,OpenCV 1.0安装界面与此基本一致。)在安装时选择"将\OpenCV\bin加入系统变量"(Add\OpenCV\bin to the systerm PATH)。

2.2.2配置Windows环境变量

检查C:\Program Files\OpenCV\bin是否已经被加入到环境变量PATH,如果没有,请加入。加入后需要注销当前Windows用户(或重启)后重新登陆才生效。(可以在任务管理器里重启explorer.exe)

2.2.3配置Visual C++ 6.0

全局设置

菜单Tools->Options->Directories:先设置lib路径,选择Library files,在下方填入路径:

C:\Program Files\OpenCV\lib

然后选择include files,在下方填入路径:

C:\Program Files\OpenCV\cxcore\include

C:\Program Files\OpenCV\cv\include

C:\Program Files\OpenCV\cvaux\include

C:\Program Files\OpenCV\ml\include

C:\Program Files\OpenCV\otherlibs\(int argc, char* argv[])

{

创建一个IplImage指针,使用cvLoadImage函数打开一个视频,第一个参数是视频的路径,第二个参数是指

IplImage* src = cvLoadImage("C:\\Documents and Settings\\Administrator\\My Documents\\图像\\2j.jpg" , 1);

给打开的窗口命名

cvNamedWindow("show_image");

显示这张图片

cvShowImage("show_image",src);

cvWaitKey(0);

return 0;

}

2.3.2加载一个视频。

(1)有关代码:

#include"(int argc, char* argv[])

{

cvNamedWindow("avi");

CvCapture

CvCapture* capture = cvCreateFileCapture("E:\\学习\opencv\\学习opencv 代码\\读取一个视频\\绝望的主妇第七季01.avi");

IplImage* frame;

while(1)

{

frame = cvQueryFrame(capture);

if(!frame)

{

break;

}

cvShowImage("avi",frame);

char c = cvWaitKey(33);

if(c==27)

{

break;

}

}

cvReleaseCapture(&capture);

cvDestroyWindow("avi");

return 0;

}

(2)制作说明

1.加载视频需一定的解码器,播放视频实际上是边解码边播放的。所以一定要安装解码器,程序才能加载一个视频。

2.由于打开的视频格式为avi格式,需要一些视频的转换器。自己就在网上下载了一个狸窝视频转换器用来转换视频格式。

(3)流程图

(4)加载视频中可能遇到的问题以及可能的原因。

1视频文件路径没写对

2没有安装解码器

3如果使用的是Opencv2.0或更高版本,那么,能否正确加载opencv_ffmpeg210.dll

4尽管是AVI文件,但也可能使用了某种codec,例如:MJPEG Decompressor。需要把它转换OpenCV支持的AVI文件. OpenCV支持的AVI。例如使用狸窝全能视频转换器,在《预置方案》处,选择AVI-Audio_Video Interleaved(*.avi)。或者使用格式工厂也可以。

5读摄像头数据,需要安装与摄像头相应的驱动程序。

(5)运行结果

(6)加载视频既可以使用加载一段视频,也可以打开一个自己电脑上的摄像头。

CvCapture 是一个结构体,用来保存图像捕获所需要的信息。opencv提供两种方式从外部捕获图像

一种是从摄像头中,一种是通过解码视频得到图像。两种方式都必须从第一帧开始一帧一帧的按顺序获取,因此每获取一帧后都要保存相应的状态和参数。比如从视频文件中获取,需要保存视频文件的文件名,相应的解码器类型,下一次如果要获取将需要解码哪一帧等。这些信息都保存在CvCapture结构中,每获取一帧后,这些信息都将被更新,获取下一帧需要将新信息传给获取的api 接口

2.3.3获取摄像头,显示图像。

(1)与其相关的说明

在获取摄像头之前先来熟悉以下opencv中视频获取的数据结构的管理方式。1.CVCapture:视频获取结构

说明:OpenCV中的视频获取结构。结构CVCapture没有公共接口,它只能用来作视频获取函数中实用的一个参数。

2.cvCreateFileCapture:初始化文件中获取视频

语法:CvCapture * cvCreateFileCapture(const char *filename);

参数类型说明

Filename const char* 使用视频文件名

说明:该函数给指定文件的视频流分配和初始化CvCapture.

返回值;分配的CvCapure

3.cvCaptureFromCAM:从摄像头中获取视频

语法:CvCapture * cvCaptureFromCAM(int index)

参数类型说明

Index in t index指的是摄像头的索引,当只有

一个摄像头时,index设为-1

4. cvQueryFrame:从摄像头或者文件中抓取并返回一帧

语法:IplImage* cvQueryFrame(CvCapture * capture)

参数类型说明

cvCapture CvCapture* 视频获取结构cvQueryFrame:从摄像头或者文件中抓取一帧,然后解压并返回一帧。返回的图像不可以被用户释放或者修改。

返回值; IplImage获取的指针

(2)相关代码

对A VI文件中的视频进行处理,可用如下程序。获得图像的效果如下图。

#include "(int argc, char* argv[])

{

cvNamedWindow("avi");

CvCapture* capture = cvCreateCameraCapture(-1);

IplImage* frame;

while(1)

{

frame = cvQueryFrame(capture);

if(!frame)break;

cvShowImage("avi",frame);

char c = cvWaitKey(33);

if(c==27)

break;

}

cvReleaseCapture(&capture);

cvDestroyWindow("avi");

return 0;

}

(3)相关代码的解释。

该代码与加载视频基本一致。只是有一处代码有所改只需把cvCreateFileCapture改成cvCreateCameraCapture即可。该函数的输入参数是一个ID号,只有存在多个摄像头时才起作用。当ID=-1时,表示随机选择一个。HighGUI做了很多工作,使得摄像机图像序列像一个视频文件一样。

(4)运行结果。

3.基于opencv运动目标跟踪系统实现的详细说明。运动目标检测时各种后续高级应用如目标跟踪,目标分类,目标行为理解等的基础主要目的是从视频图像中提取出运动目标并获得运动目标的特征信息,如颜色,形状,轮廓等。提取运动目标的过程实际上就是一个图像分割的过程,

而运动物体就只有在连续的图像序列(如视频图像序列)中才能体现出来,运动目标的提取过程就是在连续的图像序列中寻找差异,并把由于物体运动和表现出来的差异提取出来。

3.1一般目标跟踪的实现的流程图。

3.2本文的检测算法。

3.2.1连续适应性均值移动算法(CamShift)

本平台在进行运动物体检测跟踪时所采用的算法是:首先利用“帧差法”检测出初始的运动目标;一旦认为此目标合法,便根据目标在HSI(色调、饱和度、强度)空间中H通道的色调特性,利用“连续适应性均值移动算法(CamShift)”,对目标进行跟踪。

CamShift算法简述如下:

(1)在图像HSI空间中计算H通道(色彩通道)分量的1D直方图

(2)利用此1D直方图将原图改建成2D概率分布图

(3)计算出目标区域的重心。

(4)利用经典的“Mean Shift”算法,不断平移调整窗口中心到与目标重心重合

(5)将上一帧的窗口大小和中心,作为下一帧Mean Shift算法搜索窗口的初始值,在下一帧中继续Mean Shift运算。

3.2.2上述运动物体检测和跟踪的算法的流程图

3.3 Camshift算法原理及其Opencv实现。

CamShift算法,即"Continuously Apative Mean-Shift"算法,是一种运动跟踪算法。它主要通过视频图像中运动物体的颜色信息来达到跟踪的目的。我把这个算法分解成三个部分,便于理解:

1) Back Projection计算

2) Mean Shift算法

3) CamShift算法

3.3.1Back Projection

计算Back Projection的步骤是这样的:

1. 计算被跟踪目标的色彩直方图。在各种色彩空间中,只有HSI空间(或与HSI 类似的色彩空间)中的H分量可以表示颜色信息。所以在具体的计算过程中,首先将其他的色彩空间的值转化到HSI空间,然后会其中的H分量做1D直方图计算。

2. 根据获得的色彩直方图将原始图像转化成色彩概率分布图像,这个过程就被称作"Back Projection"。

在OpenCV中的直方图函数中,包含Back Projection的函数,函数原型是:void cvCalcBackProject(IplImage** img, CvArr** backproject, const CvHistogram* :

IplImage* rawImage;

get from video frame,unsigned byte,one channel

IplImage* result=cvCreateImage(cvGetSize(rawImage),IPL_DEPTH_8U,1);

cvCalcBackProject(&rawImage,result, Shift算法。

(1)计算重心。

.在讨论Mean Shift算法之前,首先讨论在2D概率分布图像中,如何计算某个区域的重心(Mass Center)的问题,重心可以通过以下公式来计算:

1.计算区域内0阶矩

for(int i=0;i< Shift算法的具体步骤

接下来,讨论Mean Shift算法的具体步骤,Mean Shift算法可以分为以下4步:

1.选择窗的大小和初始位置.

2.计算此时窗口内的Mass Center.

3.调整窗口的中心到Mass Center.

4.重复2和3,直到窗口中心"会聚",即每次窗口移动的距离小于一定的阈值。在OpenCV中,提供Mean Shift算法的函数,函数的原型是:

int cvMeanShift(IplImage* imgprob,CvRect windowIn,

CvTermCriteria criteria,CvConnectedComp* out);

需要的参数为:

1.IplImage* imgprob:2D概率分布图像,传入;

2.CvRect windowIn:初始的窗口,传入;

3.CvTermCriteria criteria:停止迭代的标准,传入;

4.CvConnectedComp* out:查询结果,传出。

(注:构造CvTermCriteria变量需要三个参数,一个是类型,另一个是迭代的最大次数,最后一个表示特定的阈值。例如可以这样构造criteria:criteria=cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,10,0.1)。) meanshift算法是一种密度函数梯度估计的非参数方法,通过迭代寻优找到概率分布的极值来定位目标。

算法过程为:

(1).在颜色概率分布图中选取搜索窗W

(2).计算零阶距:

计算一阶距:

计算搜索窗的质心:

(3).调整搜索窗大小

宽度为;长度为1.2s;

(4).移动搜索窗的中心到质心,如果移动距离大于预设的固定阈值,则重复2)3)4),直到搜索窗的中心与质心间的移动距离小于预设的固定阈值,或者循环运算的次数达到某一最大值,停止计算。

3.3.3 CamShift算法

1.原理

在了解了MeanShift算法以后,我们将MeanShift算法扩展到连续图像序列(一般都是指视频图像序列),这样就形成了CamShift算法。CamShift算法的全称是"Continuously Apaptive Mean-SHIFT",它的基本思想是视频图像的所有帧作MeanShift运算,并将上一帧的结果(即Search Window的中心和大小)作为下一帧MeanShift算法的Search Window的初始值,如此迭代下去,就可以实现对目标的跟踪。整个算法的具体步骤分5步:

Step 1:将整个图像设为搜寻区域。

Step 2:初始话Search Window的大小和位置。

Step 3:计算Search Window内的彩色概率分布,此区域的大小比Search Window 要稍微大一点。

Step 4:运行MeanShift。获得Search Window新的位置和大小。

Step 5:在下一帧视频图像中,用Step 3获得的值初始化Search Window的位置和大小。跳转到Step 3继续运行。

2.实现

在OpenCV中,有实现CamShift算法的函数,此函数的原型是:

相关文档
最新文档