OpenCV之光流法运动目标跟踪
[光流Optical Flow]的概念是Gibson在1950年首先提出来的。它是空间运动物体在观察成像平面上的像素运动的瞬时速度,是利用图像序列中像素在时间域上的变化以及相邻帧之间的相关性来找到上一帧跟当前帧之间存在的对应关系,从而计算出相邻帧之间物体的运动信息的一种方法。
一般而言,光流是由于场景中前景目标本身的移动、相机的运动,或者两者的共同运动所产生的。当人的眼睛观察运动物体时,物体的景象在人眼的视网膜上形成一系列连续变化的图像,这一系列连续变化的信息不断流过视网膜(即图像平面),好像一种光的流;,故称之为光流(optical flow)。
光流表达了图像的变化,由于它包含了目标运动的信息,因此可被观察者用来确定目标的运动情况。从图片序列中近似得到不能直接得到的运动场<运动场,其实就是物体在三维真实世界中的运动;光流场,是运动场在二维图像平面上(人的眼睛或者摄像头)的投影。
那通俗的讲就是通过一个图片序列,把每张图像中每个像素的运动速度和运动方向找出来就是光流场。那怎么找呢?咱们直观理解肯定是:第t帧的时候A点的位置是(x1, y1),那么我们在第t+1帧的时候再找到A点,假如它的位置是(x2,y2),那么我们就可以确定A点的运动了:(ux, vy) = (x2, y2) - (x1,y1)。
那怎么知道第t+1帧的时候A点的位置呢? 这就存在很多的光流计算方法了。
光流计算方法
大致可分为三类:基于匹配的方法、频域的方法和梯度的方法。
1. 基于匹配的光流计算方法包括基于特征和基于区域两种
2. 基于频域的方法,也称为基于能量的方法,利用速度可调的滤波组输出频率或相位信息。
3. 基于梯度的方法利用图像序列亮度的时空微分计算2D速度场(光流)。
当前对于光流法的研究主要有两个方向
一是研究在固有硬件平台基础上实现现有算法
二是研究新的算法。
光流算法的主要目的就是基于序列图像实现对光流场的可靠、快速、精确以及鲁棒性的估计。然而,由于图像序列目标的特性、场景中照明,光源的变化、运动的速度以及噪声的影响等多种因素影响着光流算法的有效性。
函数详解
1.CalcOpticalFlowPyrLK
计算一个稀疏特征集的光流,使用金字塔中的迭代 Lucas-Kanade 方法
C++函数代码
void calcOpticallFlowPyrLK (
InuputArray prevImg,
InputArray prevPts,
InputOutputArraynextPts,
OutputArray err,
Size winSize = Size(21,21),
int maxLevel = 3,
TermCriteriacriteria=TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, 0.01),
int flags = 0,
double minEigThreshold = 1e-4
);
函数参数详解:
参数 | 解释 |
---|---|
prevImg | 深度为8位的前一帧图像或金字塔图像。 |
nextImg | 和prevImg有相同的大小和类型,后一帧图像或金字塔。 |