基于opencv的运动物体跟踪实验报告
基于opencv的运动物体跟踪
一、实验目的
1.通过实验了解opencv运动物体跟踪的数据结构、函数以及基本框架;
2.通过实验提高对于图像的认识;
3.通过实验了解光流法、背景差分法、Camshift等主流视频跟踪算法;
4.通过实验将理论和实践联系起来,提升对于理论知识的认识;
二、实验要求
1.调用基于intel 的开源视觉库opencv,实现视频或者摄像头的监控;
2.编程实现对进入视觉范围内的运动物体实施监测与跟踪;
3.统计出进入视觉范围内的物体个数,速度等;
4.针对实际的监控效果,实现对算法的改进,完成复杂背景下物体跟踪问题
三、实验环境
PC机一台(VC++)、摄像头一个
四、实验内容
1.opencv相关信息:
opencv是hite严开源计算机视觉库。它由一系列c函数和少量c++类构成,实现了图像处理和计算机视觉方面的很多通用算法。
其重要重要特性包括:拥有包括300多个C函数的跨平台的中、高层API。它不依赖于其它的外部库——尽管也可以使用某些外部库。
openCv的优势在于:(1)纯c代码,源代码开放;(2)丰富的函数功能,强大的图像和矩阵运算能力;(3)平台无关性;(4)程序运行的实时性;(5)方便灵活的用户接口;(6)交互性及强大的扩展功能;(7)可嵌入性。
可见,作为一个基本的图像处理、计算机视觉和模式识别的开源项目OpenCv可以直接应用于很多领域,作为二次开发的理想工具。
2.图像噪声的处理方面
图像信号在产生、传输和记录过程中,经常会受到各种噪声的干扰,一般来说,现实中的图像都是带噪图像。通常在图像处理工作中,在边缘检测、图像分割、特征提取、模式识别等高层次处理之前,选用适当的方法尽量地去除噪声干扰是一个非常重要的预处理步骤。依据噪声产生的原因,将经常影响图像质量的噪声源分为三类:阻性元器件内部产生的高斯噪声;光电转换过程中的泊松噪声(椒盐噪声);感光过程中产生的颗粒噪声。噪声的均值表明了图像中噪声的总体强度。一般地,对噪声的描述采用统计意义上的均值与方差。
综合使用各种方法去除图像噪声,通过实验比较了这些方法所适用的场合,深入了解了其中的均值和中值滤波算法,兼顾质量和实时性的要求,将两者结合起来,采用一种改进的实时滑窗递归中值算法。
均值滤波一般的具体实现步骤是:
.选择一个(2n+l)X(2n+l)的窗口(通常为3X3或5X5),并用该窗口沿图像数据进行行或列的滑动;
.读取窗口下各对应像素的灰度值;
.求取这些像素的灰度平均值替代窗口中心位置的原始像素灰度值。
中值滤波一般的具体实现步骤是:
.选择一个(2n+l)x(2n+l)的窗口(通常为3x3或5X5),并用该窗口沿图像数据进行行或
.读取窗口下各对应像素的灰度值;
.将这些灰度值从小到大排成一列,用排序所得的中值替代窗口中心位置的原始像素灰度值;
滑窗扫描的顺序是先从上往下扫描,建立滑窗的分行部分和循环链表,以及当前滑窗内各行数据的总和。每次滑动记录滑动的距离,根据滑动距离从分行部分和循环链表中提取最旧的行部分和从当前滑窗总和中减去,并计算移入行数据的和,覆盖掉刚提取的最旧的数据,再与当前滑窗总和相加。滑窗总和除以(2n+l)x(2n+l)得到滑窗均值,存储到目标图像中处于滑窗中心的位置。
由于每次运算只考虑滑窗移入和移出的数据,每次计算均值的时间复杂度就是O(2n+3)即使滑窗的尺度选取得很大,做整幅图像的均值运算量也只是线性增长,实时性显著提高。
3.运动目标检测方面
重点学习了目前在实际应用中普遍采用的帧间差分法和以背景差分算法,综合帧间差分法和背景差分法各自的特点,使用了一种自适应累积背景的背景差分法,使得背景更新算法使之能够排除目标的干扰,自适应地获取背景图像;为了适应背景图像的亮度变化,使用了基于直方图统计和最小二乘法的OTSU算法实时计算阐值提取运动目标。
本次实验基于OTSU算法进行改进完成二值化图像阐值的选取,OTSU算法由日本学者大津于1979年提出,是目前广泛使用的阐值分割法之一。OTSU法也称为最大类间方差法或最小类内方差法,又叫大津法,简称OTSU。该方法基于图像的灰度直方图,以目标和背景的类间方差最大或类内方差最小为闽值选取准则,按图像的灰度特性,将图像分成背景和目标两部分。背景和目标之间的类间方差越大,说明构成图像的两部分的差别越大,当部分目标错分为背景或部分背景错分为目标都会导致两部分差别变小。因此,使类间方差最大的分割意味着错分概率最小。OTSU算法在很多情况下都能取得良好的分割效果。
运动目标检测是视频运动目标检测与跟踪的第一部分,它就是实时的在被监视的场景中检测运动目标,并将其提取出来。运动目标检测常用的有四种常用方法:连续帧间差分法、背景差分法、光流法和运动能量法
连续帧间差分法对于动态环境有很好的适应性,但却不能够很好地分割运动对象,不利于进一步的对象识别与分析;背景差分法是将当前帧每个像素与背景图像逐一比较,能够较完整的提取目标点,却又对光照和外部条件造成的动态场景变化过于敏感;光流法的优点是能够检测出独立运动的对象,不需要预先知道场景的任何信息,而且可以应用于背景整体运动的情况,但是大多数光流方法的计算复杂,除非有特殊的硬件支持,否则很难实现于实时检测;运动能量法适合于复杂变化的环境,能消除背景中振动的像素,使按某一方向运动的对象更加突出地显现出来,但运动能量法也不能精确地分割出对象。
而背景更新算法能够自适应地获取背景图像,该算法提取背景的思想是将连续帧间差分法和背景差法相结合,通过当前帧帧差图像找到物体的运动区域,对运动区域的背景保持不变,而非运动区域的背景采用当前的帧进行替换更新,这样经过一段时间就可以提取出背景图像。
4.运动目标的跟踪
目标检测的后继步骤就是目标跟踪,目标跟踪是在事先不了解目标运动信息的条件下,通过来自信息源的数据实时估计出目标的运动状态,从而实现对目标的位置和运动趋势的判定。通过图像分割获取目标团块信息;采用Kalman滤波和运动模板的方法跟踪运动目标;对彩色图像采用Camshift算法完成目标跟踪,较好地解决目标的遮挡和重叠问题,最后,将检测和跟踪模块纳入openCv提供的运动目标分析框架,形成一个比较完整的目标检测和跟
五、实验步骤
1.开发平台搭建
安装、下载Opencv,并在vc++2006编译环境下配置opencv。在vc++2006中建立新工程以后,在工程设置里添加需要的opencv库,并在程序文件中包含opencv的头文件。
2.添加运动检测跟踪程序中所用到的opencv跟踪框架团块
运动物体的前景检测模块:判断每一个像素是前景还是背景。输入数据为当前帧图像,输出为当前帧的前景掩码。OpenCV可以检测出完全静止的背景,实际运用中可能发生平移或旋转,为满足背景变化也可以检测出运动物体,那就需要把摄像头的标定结合进来。
运动物体的团块特征检测模块:使用前景检测的结果检测场景中运动物体的像素结合—团块,输入数据为当前帧的掩码和已有的团块,输出数据为新检测到的团块。为满足在雷达系统上的应用,团块的图形特征和运动相关性分析都要考虑,而且要考虑团块之间以及团块与背景融合以后的处理。
运动物体的团块跟踪模块:括团块列表和单团块跟踪,使用新团块检测的结果,输入数据为当前帧、当前帧掩码和新团块,输出数据为当前帧的团块信息:ID号,位置,速度以及运动方向。
轨迹生成模块:手机所有团块的位置,建立轨迹列表,进行相关性处理。
轨迹后处理模块:进行运动物体标定时取出位置和运动趋势的抖动,对轨迹进行平滑处理。
3.添加自定义团块完成跟踪程序的团块关联及实现
自定义团块程序:
#include "cvaux.h"
#include "highgui.h"
#include
#include "myfgdetector.h"
void MyFGDetector::Create(double newalpha, double newthreshold)
{
frameNum = 0; //视频帧计数
alpha = newalpha; //得到输入的背景图像的更新权值
threshold = newthreshold; //得到二值化的阈值
pFrame = 0; //当前帧指针置为NULL
pFGMask = 0; //输出的前景检测图像指针置为NULL
pFrameMat = 0; //当前帧转换成的位浮点单通道矩阵指针置NULL
pFGMat = 0; //前景图位浮点单通道矩阵指针置为NULL
pBkMat = 0; //背景图位浮点单通道矩阵指针置为NULL }
MyFGDetector::MyFGDetector()
{
Create(0.150, 60.0);
}
MyFGDetector::MyFGDetector(double alpha, double threshold)
{
Create(alpha, threshold);
}
void MyFGDetector::Process(IplImage* pFrame)
{
if (frameNum == 0)
{/*视频的第一帧,利用这个帧图像的宽高信息来初始化内部的成员变量*/ pFGMask = cvCreateImage(cvGetSize(pFrame), IPL_DEPTH_8U, 1);
pBkMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);
pFGMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);
pFrameMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);
if (!pFGMask||!pBkMat||!pFrameMat)
{/*内部成员有一个初始化不成功的处理*/
fprintf(stderr, "Can not alloc memory.\n");
return ;
}
//将彩色的当前帧图像pFrame转换到单通道灰度图像pFGMask
cvCvtColor(pFrame, pFGMask, CV_BGR2GRAY);
//当前帧位单通道图pFGMask映射到位浮点单通道矩阵pFrameMat
cvConvert(pFGMask, pFrameMat);
//前景位浮点单通道矩阵pFrameMat
cvConvert(pFGMask, pFGMat);
//背景位浮点单通道矩阵pBkMat初始化
cvConvert(pFGMask, pBkMat); //用第一帧作背景
}
//转化成单信道图像再处理
cvCvtColor(pFrame, pFGMask, CV_BGR2GRAY);
cvConvert(pFGMask, pFrameMat);
//先高斯低通滤波去除噪声平滑图像
cvSmooth(pFrameMat, pFrameMat,CV_GAUSSIAN, 3, 0, 0);
// 当前帧跟背景图相减
cvAbsDiff(pFrameMat, pBkMat, pFGMat);
//二值化前景图
cvThreshold(pFGMat, pFGMask, threshold, 255.0, CV_THRESH_BINARY);
//进行形态学滤波,去掉孤立噪点
cvErode(pFGMask, pFGMask, 0, 1);//腐蚀,迭代次数
cvDilate(pFGMask, pFGMask, 0, 1);//再膨胀,迭代次数
//背景累计差分:pBkMat = alpha*pFrameMat+(1-alpha)*pBkMat
cvRunningAvg(pFrameMat, pBkMat, alpha, 0);
frameNum++; //帧计数
}
//返回前景检测图像pFGMask
IplImage* MyFGDetector::GetMask()
{
return pFGMask;
}
void MyFGDetector::Release()
{
frameNum = 0;
if (pFrame) cvReleaseImage(&pFrame);
if (pFGMask) cvReleaseImage(&pFGMask);
if (pFrameMat) cvReleaseMat(&pFrameMat);
if (pFGMat) cvReleaseMat(&pFGMat);
if (pBkMat) cvReleaseMat(&pBkMat);
}
MyFGDetector::~MyFGDetector()
{
Release();
}
4.使用blobtrack源程序将自定义的模块插入到opencv的框架中
5.编译连接,生成可执行程序
6.程序调试
7.程序演示
运行生成的可执行程序从自动跟踪画面中截取图像
远处人的运动跟踪
同时跟踪两个运动目标
近处运动物体跟踪
六、实验中出现的问题
由于差分法的不完善及自定义团块中对于图像阈值转换运算编程的不完善,跟踪时会出现目标跟踪分离及运动物体判断错误的情况
运动目标跟踪分离
运动目标跟踪偏离
七、实验心得
组员刘嘉伟:本次实验中对opencv进行了充分的了解,并利用opencv进行了运动物体跟踪监测的程序编译,初步了解了该视频处理环境的具体功能以及调用方法,并了解了视频跟踪中所涉及的一些算法以及图像处理的技巧,通过本次实验基本掌握了图像跟踪各模块的具体应用方式,在这次实验中受益颇深
组员赵秀娇:通过这次实验基本掌握了运动目标检测及跟踪的多种算法,深入了解了将图像的灰度、阈值及二值化计算应用于运动目标跟踪的方法,并通过背景差分法、帧差分法实现了运动图像的判断及跟踪。在实验过程中加深了vc++2006及opencv的理解,总体来说
收获颇多。
基于opencv运动物体跟踪的实习报告
组员:智能0701
刘嘉伟 06074008(08)
赵秀娇 06074009(09)