英语原文共 9 页,剩余内容已隐藏,支付完成后下载完整资料
第十章:跟踪与运动
跟踪基础
当我们在处理一段视频而非某张静止的图像时,通常视频中有一个或几个特定物体是我们想在整个视野范围内关注的。在前一章中,我们知道了如何在逐帧(frame-by-frame)分离出特定的形状,例如人或者车;现在,我们尝试理解这个物体的运动。理解物体的运动则主要包含两个部分:识别(identification)和建模。
识别是指在视频流后续的帧中找出之前某帧中的感兴趣物体。前面章节中讲到的矩和颜色直方图可以帮助识别我们关注的物体。一个相关的问题就是跟踪不明物体。当我们需要根据运动来确定什么是感兴趣的,或者当物体的运动使得其成为感兴趣物体时,跟踪不明物体就很重要了,经典的跟踪不明物体的方法是跟踪视觉上重要的关键点,而不是整个物体。OpenCV提供了两种方法实现跟踪关键点:Lucas-Kanade [Lucas81]和Horn-Schunk [Horn81]方法。这两种方法分别代表了通常提到的稀疏(sparse)和稠密(dense)光流。
上述方法实际上只能给出物体实际位置的初步计算。理解物体运动的第二个部分,也就是建模,则可以帮助我们解决这个问题。为估计由这种粗略测量得出的物体的轨迹,人们设计了许多有力的数学方法。这些方法适用于二维和三维物体或者物体位置的模型。
寻找角点
有多种局部特征可以用来进行跟踪。花一点时间去思考究竟角点(corner)用什么样的特征来描述是值得的。很明显,如果从一面很大的空墙上选择一个点,那么将很难从视频的下一帧中再找出这个点。如果墙上所有的点都是一样的或者相似的,我们就不会有太好的运气能在随后的视频帧中跟踪到这个点了。相反,如果选择一个独一无二的点,那么在找到这点的几率就非常大。实际上,被选择的点或特征应该是独一无二的,或者至少接近独一无二,并且与另一张图像的其他点可以进行参数化的比较。如图10-1所示
图10-1:圆圈圈出的特征点是易于跟踪的点,而矩形圈出的特征—甚至是明显的边缘—却不然
回到那面大而空的墙,我们想要找本身具有明显变化的点—例如导数值比较明显的地方。虽然仅此是不够的,但这是一个开始。一个导数值比较明显的点可能在某种类型的边缘上,但却和此边缘上的其他点看起来一样(参考图10-8和“Lucas-Kanade方法”一节中讨论的孔径问题)。
如果一个点在两个正交的方向上都有明显的导数,则我们认为此点更倾向是独一无二的,所以,许多可跟踪的特征点都称为角点。从直观上讲,角点(而非边缘)是一类含有足够信息且能从当前帧和下一帧中都能提取出来的点。
最普遍使用的角点定义是由Harris[Harris88]提出的。定义的基础是图像灰度强度的二阶导数矩阵。考虑到图像所有的像素点,我们可以想象图像的二阶导数即形成一幅新的“二阶导数图像”,或融合在一起形成一幅新的 Hessian 图像。这个术语源自于一个点的如下定义的二维
Hessian 矩阵:
对于Harris角点,我们使用每点周围小窗口的二阶导数图像的自相关矩阵。这个自相关矩阵的定义如下:
这里是可以归一化的权重比例,但是通常被用作产生圆形窗口或者高斯权重。
Harris定义的角点位于图像二阶导数的自相关矩阵有两个最大特征值的地方,这在本质上表示以此点为中心周围存在至少两个不同方向的纹理(或者边缘),正如实际的角点是由至少两个边缘相交于一点而产生,之所以采用二阶导数是由于它对均匀梯度不产生响应。角点的这个定义还有另一个优点。被跟踪的物体在移动过程中也可能会旋转,找到同时对移动和旋转不变的量是很重要的。只考虑自相关矩阵的特征值可以达到这个目的。这两个最大特征值不仅可以判定一个点是否一个好的可跟踪的特征点,同时也提供了对这个点进行识别的一个标识。
Harris最原始的定义是将矩阵的行列式值与的迹(带权重系数)相减,再将差值同预先给定的阈值进行比较。后来Shi和Tomasi[Shi94]发现,若两个特征值中较小的一个大于最小阈值,则会得到强角点。Shi和Tomasi的方法比较充分,并且在很多情况下可以得到比使用Harris方法更好的效果。
函数cvGoodFeaturesToTrack( )采用Shi和Tomasi提出的方法,先计算二阶导数(利用Sobel算子),再计算特征值,它返回满足易于跟踪的定义的一系列点。
void cvGoodFeaturesToTrack(
const CvArr image,
CvArr eigImage,
CvArr tempImage,
CvPoint2D32f corners,
Int corner_count,
double quality_level,
double min_distance,
const CvArr mask = NULL,
int block_size = 3,
int use_harris = 0,
double k = 0.4
);
函数中,输入图像image须为8位或32位(也就是,IPL_DEPTH_8U 或者 IPL_DEPTH_32F)单通道图像。第二和第三个参数是大小与输入图像相同的32位单通道图像。参数tempImage和eigImage在计算过程中被当作临时变量使用,计算结束后变量eigImage中的内容是有效的。特别地,每个元素包含了输入图像中对应点的最小特征值。Corners是函数的输出,为检测到的32位(CvPoint2D32f)结果点数组;在调用函数cvGoodFeaturesToTrack( )之前需要给这个数组分配内存变量,很明显,只能为此数组分配有限的内存。corner_count输出实际检测到的角点数目。参数quality_level表示一点被认为是角点的可接受的最小特征值。实际用于过滤角点的最小特征值是quality_level与图像中最大特征值的乘积。所以quality_level的值不应超过1(常用的值为0.10或者0.01).检测完所有的角点后还要进一步剔除掉一些距离较近的角点。min_distance保证返回的角点之间距离不小于min_distance个像素。
mask是可选参数,是一幅像素值为布尔类型的图像,用于指定输入图像中参与角点计算的像素点。若mask的值设为NULL,则选择整个图像。block_size是计算函数的自相关矩阵时指定点的领域,采用小窗口计算的结果比单点(也就是block_size为1)计算的结果要好。若use_harris的值为非0,则函数使用harris的角点定义;若为0,则使用Shi-Tomasi的定义。当use_harris为且不为0,则为用于设置Hessian自相关矩阵即对Hessian行列式的相对权重的权重系数
函数cvGoodFeaturesToTrack( )的输出结果为角点的位置数组,我们往往会希望再另一幅相似的图像中寻找这些角点。就本章而言,我们关注的是在后续的视频帧中找到这些特征点,但是这个函数也有其他的应用,例如,对从微小不同的视角拍摄的多幅图像进行匹配。这个问题将在后面讨论立体视觉的小节中遇到。
亚像素级角点
如果我们进行图像处理的目的不是提取用于识别的特征点而是进行几何测量,则通常需要更高的精度,而函数cvGoodFeaturesToTrack( )只能提供简单的像素的坐标值,就是说,我们有时会需要实数坐标值而不是整数坐标值,例如(8.25,117.16)。
您也许需要确定图像中一个尖锐的峰值点的位置,但是峰值的位置一般都不会恰好位于一个像素的正中心,使得确定其位置比较困难。要解决这个问题,需要先用一条曲线(例如一条抛物线)拟合图像的值,再用数学的方法计算位于像素之间的峰值点的位置。亚像素检测方法就是一些有关峰值点位置的计算技巧(了解更多此方面知识以及最新的方法,请参考Lucchese [Lucchese02]和Chen [Chen05])。图像测量常用的领域为三维重建、摄像机标定、图像拼接以及在卫星图像中查找特定信号,如一栋建筑的精确位置。
亚像素级角点的位置在摄像机标定、跟踪并重建摄像机的轨迹或者重建被跟踪目标的三维结构时是一个基本的测量值。我们已经知道如何对整数网格像素来检测角点并得到角点的位置,下面所要讨论的是如何将求得的角点位置精确到亚像素级精度。一个向量和与其正交的向量的点积为0,角点则满足这种情况,如图10-2所示
图10-2:计算亚像素级精度的角点:(a)点p附近的图像是均匀的,其梯度为0; (b)边缘的梯度与沿边缘方向的q-p向量正交。在图中的两种情况下,p点的梯度与q-p向量的点积均为0(参考正文)
图10-2 假设起始角点在实际亚像素级角点的附近。检测所有的向量。若点位于一个均匀的区域,则点处的梯度为0。若向量的方向与边缘的方向一致,则此边缘上点处的梯度与向量正交,在这两种情况下,点处的梯度与向量的点积为0。我们可以在点周围找到很多组梯度以及相关的向量,令其点积为0,然后可以通过求解方程组,方程组的解即为角点的亚像素级精度的位置,也就是精确的角点位置。
函数cvGoodFeaturesToTrack( )用于发现亚像素精度的角点位置
void cvFindCornerSubPix(
const CvArr* image,
CvPoint2D32f* corners,
int count,
CvSize win,
CvSize zero_zone,
CvTermCriteria criteria
);
输入图像image是8位单通道的灰度图像。corners为整数值的像素位置,例如是由cvGoodFeaturesToTrack( )得到的位置坐标。corners设定了角点的初始位置。count为需要计算的角点数目。
实际计算亚像素级的角点位置时,解的是一个点积的表达式为0的方程组(参考图10-2),其中每一个方程组都是由邻域的一个点产生。win指定了等式产生的窗口的尺寸。搜索窗口的中心是整数坐标值的角点并从中心点在每个方向上扩展win指定的像素(也就是说,如果win.width=4,则窗口的实际大小为4 1 4=9个像素宽)。这些等式构成一个可用自相关矩阵的逆(非前文讨论的Harris角点时涉及的自相关矩阵)来求解的线性方程组。实际上,由于非常接近的像素产生了很小的特征值,所以这个自相关矩阵并不总是可逆的。为了解决这个问题,一般可以简单的剔除离点非常近的像素。输入参数zero_zone定义了一个禁区(与win相似,但通常比win小),这个区域在方程组以及自相关矩阵中不被考虑。如果不需要这样一个禁区,则zero_zone应设置为cvSize(-1,-1)。
当找到一个的新位置时,算法会以这个新的角点作为初始点进行迭代直到满足用户定义的迭代终止条件。迭代过程的终止条件可以是最大迭代次数CV_TERMCRIT_ITER类型,或者是设定的精度CV_TERMCRIT_ITER类型(或者是两者的组合)。终止条件的设置在极大程度上影响最终得到的亚像素值的精度。例如,如果指定0.10,则求得的亚像素级精度为像素的十分之一。
不变特征
继Harris提出角点以及后来Shi和Tomasi提出角点后,许多其他类型的角点和相关局部特征点也被提出来。SIFT(“scale-invariant feature transform”)是其中一种广泛应用的类型[Lowe04]。SIFT特征正如其名称一样是缩放不变的,根据这个方向记录局部梯度直方图结果,所以SIFT也是旋转不变的。正是由于这些特点,SIFT特征在小的仿射变换中有相对不错的表现,虽然OpenCV库中还没有实现SIFT算法(参考第14章),但可以用OpenCV的基本函数实现它。我们将不再这个问题上花更多的时间,但需要记住的是,用前面已经介绍过的OpenCV函数可以实现计算机视觉领域的文献中提到的绝大部分特征。
光流
如前所述,我们经常不知道任何关于视频内容的先验知识,但是需要估计两帧之间(或者一个帧序列)的运动。运动本身就说明了存在运动的感兴趣的目标。在图10-3中解释了光流。
图10-3:光流。目标特性点(a)被连续跟踪,他们的运动被转换成速度矢量(b);下面的两幅图分别表示一幅走廊的图像(c)和摄像机沿着走廊运动时的光流矢量(d)(原图由Jean-Yves Bouguet提供)
可以将图像中的每个像素与速度关联,或者等价地,与表示像素在连续两帧之间的位移关联。这样得到的是稠密光流(dense optical flow),即将图像中的每个像素都与速度关联。Horm-Schunck方法[Horn81]计算的就是稠密光流的速度场。OpenCV中实现了一种比较简单直接的方法,即对前后连续两帧的一个像素的邻域进行匹配。这种方法被称为块匹配(block matching)。这两种方法都会在“稠密跟踪方法”一节中讨论。
实际上计算稠密光流并不容易。我们先来看看一张白纸的运动。上一帧中的白色的像素在下一帧中仍然为白色,而只有边缘的像素并且是与运动方向垂直的像素才会产生变化。稠密光流的方法需要使用某种插值方法在比较容易跟踪的像素之间进行插值以解决那些运动不明确的像素,从中可以很清楚地看到稠密光流相当大的计算量
于是我们找到了另一
全文共6746字,剩余内容已隐藏,支付完成后下载完整资料
资料编号:[145709],资料为PDF文档或Word文档,PDF文档可免费转换为Word
以上是毕业论文外文翻译,课题毕业论文、任务书、文献综述、开题报告、程序设计、图纸设计等资料可联系客服协助查找。