在之前的几篇关于OpenCV的文章中我集中介绍了OpenCV中比较常用的操作和函数.在我们基础的学习中,这些函数其实在图像进行预操作的过程中已经够用了.因此在之后的文章中,我们要继续深入使用OpenCV中的一些函数来去实现几个简单的实例.能够在学习的过程中获得满足感.
第一个实例就是从物体跟踪开始.物体跟踪分为很多种类型,且每个类型中也都包含了不同的算法,因此我们今天先从光流法开始,这也是最基础的算法来开始学习.
一:什么是光流法
在OpenCV-PythonTutorials上的解释:光流是物体或者摄像头的运动导致的两个连续帧之间的图像对象的视觉运动的模式。
它是一个向量场,每个向量是一个位移矢量,显示了从第一帧到第二帧的点的移动。
上图表示了一个球在5个连续帧里的移动。箭头显示了它的位移矢量。
光流在日常生活中应用还是很广泛的,特别是在视频的监控领域,比如从移动构建再到视频拍摄,再到视频压缩存取,都有很广泛的应用.
二:光流法的原理
在推广光流法的时候,我们要有两个前提假设:
第一:所追踪的像素目标在连续的帧之间要保持基本不变.
第二:所追踪的像素目标在连续的帧之间要有相似的运动趋势.
现在我们开始推广一下光流方程:①:假设从首发帧的像素I(x,y,t),在dt时间之后的下一帧中移动距离为(dx,dy),且这些像素是相同的,而且亮度不变
因此得到以下推广:
②:对上边公式的右边做泰勒级数近似。除以dt得到下面的等式:
其中每个参数如下:
上面的等式被叫做光流等式,但是我们在这里会发现几个问题:
我们可以找到fx和fy,他们是图像的梯度。类似的ft 是沿时间的梯度,这些都可以计算出来.但是(u, v)是未知的。
我们无法解出这个等式。因此我们需要用到Lucas-Kanade 方法来解决这些问题.
三:Lucas-Kanade 方法
现在我们使用第二条假设,就是所有的相邻像素都有相同的移动。LK算法使用了一个3×3的窗口大小。所以,在这个窗口当中有9个像素点满足公式
将点代入方程,现在的问题就变成了使用9个点求解两个未知量。
所以现在我们的问题变成解决了9个方程式,其中两个未知变量是过度确定的.解的个数大于未知数的个数,这是个超定方程,使用最小二乘的方法来求解最优值.
观察上方矩阵,用Harris角点检测来检查法逆矩阵的相似性。逆矩阵与Harris角点检测很像,说明角点是适合用来做跟踪的.
说实在的刚刚听到这个算法的时候,当时觉得这个算法思路很简单,能够给出一些点用来追踪,再去获得点的光流向量。并且能够实现追踪,但是有另外一个问题需要解决,目前讨论的运动都是小步长的运动,如果有幅度大的运动出现,本算法就会失效。
使用的解决办法是利用图像金字塔。在金字塔顶端的小尺寸图片当中,大幅度的运动就变成了小幅度的运动。所以使用LK算法,可以得到尺度空间上的光流。
这个问题就变得复杂了.
在下一篇中我们要通过OpenCV中自带的calcOpticalFlowPyrLK()函数来去实现简单的光流法.