运动追踪

Author:朱本福

一、理论研究:

视频图像中的运动追踪的首要工作是确定场景中存在的运动目标,即运动目标的检测。并且检测要达到以下要求:

(1)对环境的缓慢变化(如光照变化等)不敏感;

(2)对于复杂背景和复杂目标有效;

(3)能适应场景中个别物体运动的干扰(如树木的摇晃,水面的波动等);

(4)能够去除目标阴影的影响;

(5)检测和分割的结果应满足后续处理(如跟踪等)的精度要求。

 

运动目标检测常用的方法有:

(1)帧间差分法

帧间差分法是检测相邻图像之间变化的最简单方法,主要利用视频序列中连续的两帧或几帧图像的差异来进行目标检测和提取。

帧间差分法的特点:

用帧间差分法进行目标检测和分割,算法复杂度低,便于实时使用。由于相邻帧的时间间隔一般较短,因此该方法对场景光线的变化一般不太敏感,稳定性较好。但是检测中依赖于选择的帧时间间隔,对快速运动的物体,需要选择较小的时间间隔。如果选择不合适,当物体在前后两帧中没有重叠时会被检测为两个分开的物体;而对慢速运动的物体应该选择较大的时间差,如果此时选择不适当,物体在前后两帧中几乎完全重叠,则检测不到物体。且一般都不能完全提取出所有的特征像素点,这样在运动实体内部容易产生空洞现象,即使进行了必要的数字图像的形态学处理和连通性分析,也不能得到运动目标的完整轮廓,给以后的运动目标识别和检测带来了困难。

 

(2)背景相减法

这种方法能够较完整的提取目标点,但对场景的动态变化如光照或外部条件引起的场景变化较为敏感。如果参考图像选取适当,这种方法的优点是可以准确地分割出运动物体。但是,该方法成功与否依赖于所采用的背景图像。如何获取一个相对准确的背景图像是背景相减法的一个重点内容,通常利用背景更新的方法以弥补动态场景中的光线变化等因素带来的不利影响。

引起背景变化的原因

①光照变化:包括连续的光照变化,通常是室外环境;突然的光照变化,通常是室内环境中关灯或者室外晴天出现乌云等情况;投影到背景中的阴影,这既可能是背景自己产生的阴影,如大楼、树,也可能是前景目标自身的阴影。

②背景扰动:背景中存在的如风中树叶的摇动、水面波光的闪动、车窗玻璃的反光以及天气变化等许多细微活动,都会影响到运动目标的检测。再如室外摄像机受风吹而抖动同样会影响运动目标的检测。

③背景变化:运动目标引起的背景变化包括人将某个东西带入或带出背景,汽车驶入或驶出,或者人或物在场景中停留一阵后又运动的情况。

④遮挡问题:遮挡也是运动目标检测过程中一个难以解决的问题,在运动目标前方的遮挡物能会作为目标的一部分被提取出来,从而造成检测目标变形严重,甚至还会检测目标的失败。这些因素都会大大提高背景建模及背景更新的难度,影响到检测的效果。

 

运动目标检测前需要对视频数据进行处理,常用的处理方法有:

(1)统计平均法:

该方法通过对连续的图像序列进行统计平均来获得背景图像,即连续采集N帧图像累加求平均,式中N为图像帧数。


这种更新方法在每次更新时考虑利用当前帧信息而废弃过时信息,从而有利于背景自适应地跟随新环境的变化而变化。算法简单易实现,由于采用递归算法,故时间开销小。

该算法的不足之处是需要保存帧图像的数据,增加了空间的开销。这种方法通常用于场景内目标滞留时间较小、目标出现不频繁的情况。但是统计平均法无法满足实时性要求。

 

(2)中值滤波器法

通常在背景模型提取阶段,运动目标可以在监视区域运动,但不会长时间停留在某一个位置上。对视频画面中某一像素进行一段时间的观测,可以发现,只有在前景目标通过该点时,它的亮度值才发生大的变化。中值滤波法的思想是先建

立一个视频流滑窗用来缓存L张视频帧,然后把缓存中所有视频帧同位置像素的中值作为背景中该处像素的值。



L值的大小由运动目标通过的速度和摄像机拍摄时的采样速率等因素决定。

 

(3)GMM方法

在一段较长时间内,对图像中同一位置的像素点进行采集,该像素点作为背景图像上的一点,在理想状态下,采样值应该是某一个固定值,但是由于光照等自然因素的影响存在偏差。在统计意义下,这些采样值是服从单高斯分布模型的,它们主要集中在概率大的高斯模型的中心位置上,而在该点上出现的运动目标则是属于发生概率小的远离高斯模型中心的部分。因此我们可以计算这个像素点的平均亮度μ0,以及它的方差σ02,用各点像素的亮度均值组成的具有高斯分布的图像作为背景图像B0,其中


但是,用单高斯模型来描述背景是不够的。例如,在某帧中一个像素可能表示天空,但在另一帧中则可能表示树叶,而在第3帧中则又可能表示树枝。显然,每一种状态下的像素亮度(颜色)值是不同的,因此可以对这些多模态情形使用多个高斯模型来混合建模。设用来描述每个点像素值的高斯分布共有k个,分别记为η(x, u,μit,σit),i =1,2,...,k,则有




如果没有任何高斯模型与当前亮度值匹配,则将权重最小的高斯分量以一个新的高斯模型替代。新高斯模型的内核密度均值为It ,偏差为最大初始偏差,权重为最小初始权重。其他高斯分布模型不变,只降低它们的权重,即


混合高斯法在背景建模过程中由于允许运动目标存在,因此尤其适合室外有光线和天气变化的小而速度快的运动目标的检测。它的缺点首先是计算复杂,不仅对背景建模,实际上也对前景建模,其计算复杂度与高斯模型的个数成正比,而且模型参数难调。其次,它对大而慢的目标检测效果也不好,特别是会将纹理少或对比度低的目标当作背景。第三就是它对全局亮度的突然变化非常敏感,如果场景很长时间没变,则背景分量的变化就非常小,但是全局亮度的突然变化会将

整个视频帧认为是前景。

 

二、工程实践:

(1)开发平台的选择,安装及配置:

Visual C++6.0:强大的MFC编程;

Directshow9.0:视频处理;

OpenCV1.0:开源视觉函数库;

Speech SDK5.1:语音函数库。

安装以上软件,并对Visual C++ 6.0进行

1. 用VC编译DirectShow的标准连接库。打开工程文件baseclasses.dsw,分别编译Debug和Release版本。如果资源文件的安装时选择的是默认目录,则baseclasses.dsw的地址为:

C:\DXSDK\Samples\C++\DirectShow\BaseClasses

 

2. 全局设置

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

C:\ProgramFiles\OpenCV\lib

 

3. 设置VisualC++编译环境。在Visual C++中,点击菜单“工具”,选择“选项”。在弹出的选项卡对话框中选择“目录”卡片。

“目录:”Include files,添加如下路径:

C:\PROGRAM FILES\MICROSOFT SPEECH SDK5.1\INCLUDE

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\highgui

C:\ProgramFiles\OpenCV\otherlibs\cvcam\include

C:\DXSDK\Include

C:\DXSDK\SAMPLES\C++\DIRECTSHOW\BASECLASSES

将添加的两个路径移至顶端。

“目录:”Library files,添加如下路径:

C:\PROGRAM FILES\MICROSOFT SPEECH SDK5.1\LIB\I386

C:\DXSDK\Lib

C:\DXSDK\SAMPLES\C++\DIRECTSHOW\BASECLASSES\DEBUG

C:\DXSDK\SAMPLES\C++\DIRECTSHOW\BASECLASSES\RELEASE

“目录:”source files,在下方填入路径:

C:\Program Files\OpenCV\cv\src

C:\Program Files\OpenCV\cxcore\src

C:\Program Files\OpenCV\cvaux\src

C:\Program Files\OpenCV\otherlibs\highgui

C:\ProgramFiles\OpenCV\otherlibs\cvcam\src\windows

以上具体设置参考自己软件安装的路径设置。

 

4. 项目设置

每创建一个将要使用OpenCV的VC Project,都需要给它指定需要的lib。菜单:Project->Settings,然后将Setting for选为AllConfigurations,然后选择右边的link标签,在Object/librarymodules附加上

cxcore.libcv.lib ml.lib cvaux.lib highgui.lib cvcam.lib

 

(2)建立基本的软件仿真实验开发平台:

1.Imgcx学习版:是一套完全可执行的Visual C++界面源代码,界面内容包括图像的表示、读入和保存,该软件给读者提供了图像表示、读入、保存的框架,笔者在Imgcx上通过编写算法对单张图片进行处理来验证算法。

软件基本框架:



2. FstarVideo:Directshow建立视频处理开发平台,该平台在博创科技未来之星的软件框架下进行修改,而来,笔者通过对视频图像处理来验证自己的算法。

主要操作代码1:

for (int x =0;x< m_nWidth;x++)      //m_nWidth为视频的宽度

              {

                     for(int y =0;y<m_nHeight;y++)  //m_nHeight为视频的宽度

                     {

                     //     Median(x,y,prgb);     // 中值滤波

                     //     prewitt(x,y,prgb,2.0);  //prewitt算子

                            GetColor(x,y,prgb);   //获得xy坐标处的颜色值

                            //亮度空间转换                   

                                   tY= 0.299*prgb->rgbtRed + 0.587*prgb->rgbtGreen + 0.114*prgb->rgbtBlue;                    //将RGB颜色空间转换为亮度空间

                                   if(tY>230)  //追踪亮度    //tY为亮度阈值

                                   {

                                          //SetColor(x,y,black);   //二值化,将坐标xy处像素值设为黑色

                                         

                                          m_pParam->Yx+= x;  

                                          m_pParam->Yy+= y;

                                          m_pParam->Ysum++;

                                          //计算被标记的点数量(不绘制总标记重心则可以去掉)

                                          m_nCX =m_pParam->Yx/m_pParam->Ysum;

                                          m_nCY=m_pParam->Yy/m_pParam->Ysum;

                                          prgb->rgbtBlue=0;

                                          prgb->rgbtGreen= 0xff;  

                                          prgb->rgbtRed= 0;

                                          DrawFocus(x,y,prgb);   //以绿色绘制满足tY的像素值

                                                                              

                                   }

                                   else

                                          SetColor(x,y,white);

                            }

主要操作代码2:

//为该区域像素变红色

       for (int m =400;m<426;m++)

       {

              for (int n=75;n<86;n++)

              {

                     SetColor(m,n,red);

              }

       }                   

}                          

       //对每个像素进行操作

       for (int p=400;p<409;p++)  //查询像素值

       {

              for (int q=400;q<409;q++)

              {

      prgb->rgbtBlue= m_pImageBuf[q*m_nWidth*3 + p*3];

       prgb->rgbtGreen =m_pImageBuf[q*m_nWidth*3 + p*3 + 1];

       prgb->rgbtRed =m_pImageBuf[q*m_nWidth*3 + p*3 + 2];

       //操作像素值

       if(prgb->rgbtBlue==0&& prgb->rgbtGreen==0xff && prgb->rgbtRed==0)   //绿色像素进行操作

       {

           SetColor(p,q,black);

       }

              }

       }



后续完成了,在上传总结文档……

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值