详细解释LK光流法(Lucas-Kanade)跟踪特征点附matlab不调库函数实现

LK光流法是什么

在很多场景我们都需要对特征点进行跟踪,比如人脸,无人机目标跟踪,SLAM中特征点跟踪来计算相机的姿态等等。最粗暴的方式是每次都重新计算一次特征点,然后找到前后两张图片的相同特征点,那么就可以实现跟踪。这种方法的特点是准确,因此在很多场合都有应用,如果你感兴趣可以看看这篇文章视觉SLAM中ORB特征点算法(关键点+描述子)。但是这种方法计算复杂度太高,因为每次都得遍历整个图找关键点,找完关键点后还得根据描述子找相同的特征点。事实上,如果我们不每次都找特征点,只是在第一帧找特征点。然后后面就只跟踪这个特征点像素那么就极大的减少计算量。LK光流法就是这个思想。

LK光流法怎么做

注意:你看到任何光流法都是有一个默认的前提假设那就是“某个特征点在各个帧中的灰度值是不变的,变化的只是位置关系”。你或许会问那不是很容易不成立吗?其实很多算法都是有很多前提假设的,能算出来总比算不出来好。任何算法都是在一定前提假设情况下成立的。

注意:下面提到的图片均是指的是一个视频中的某一帧图片,比如时刻t的图片指的是视频中时刻t那一帧的图片
假设我要跟踪当前时刻t位于(x,y)处的那个像素。那么我的目标就是计算出它下一个时刻t+dt的位置(x+dx,y+dy)。其中dx和dy分别是那个像素在x方向和y方向移动的距离。在前面提到了任何光流法都是默认同一个特征点像素的灰度值是不会发生变化的。也就是说原先t时刻的图片中的(x,y)处的像素灰度值与t+dt时刻图片的(x+dx,y+dy)处的灰度值是一样的。
假设第t个时刻图片的位置为(x,y)的像素灰度值为I(x,y,t)I(x,y,t),同理第t+dt时刻的图(x+dx,y+dy)处的灰度值为I(x+dx,y+dy,t+dt)I(x+dx,y+dy,t+dt)
前面我们提到了“任何光流法都是默认同一个特征点像素的灰度值是不会发生变化的”。也就是说I(x,y,t)=I(x+dx,y+dy,t+dt)I(x,y,t)=I(x+dx,y+dy,t+dt)。注意:我们的目标是为了解出dx,dydx,dy到底是多少。所以我们还得找个方程式,而且包含I(x,y,t)I(x+dx,y+dy,t+dt)I(x,y,t)和I(x+dx,y+dy,t+dt)。事实上我们可以对I(x+dx,y+dy,t+dt)I(x+dx,y+dy,t+dt)进行一阶泰勒展开这样得到I(x+dx,y+dy,t+dt)=I(x,y,t)+dIdxdx+dIdydy+dIdtdtI(x+dx,y+dy,t+dt)=I(x,y,t)+frac {dI}{dx}dx+frac {dI}{dy}dy+frac {dI}{dt}dt
现在我们得到了下面两个方程:

  1. I(x,y,t)=I(x+dx,y+dy,t+dt)I(x,y,t)=I(x+dx,y+dy,t+dt)
  2. I(x+dx,y+dy,t+dt)=I(x,y,t)+dIdxdx+dIdydy+dIdtdtI(x+dx,y+dy,t+dt)=I(x,y,t)+frac {dI}{dx}dx+frac {dI}{dy}dy+frac {dI}{dt}dt

所以这意味着:dIdxdx+dIdydy+dIdtdt=0frac {dI}{dx}dx+frac {dI}{dy}dy+frac {dI}{dt}dt=0,等式两边同时除dtdt得到:dIdxdxdt+dIdydydt=dIdtfrac {dI}{dx} frac {dx}{dt}+frac {dI}{dy}frac {dy}{dt}=-frac {dI}{dt}.
现在我们分析下各个部分代表什么意思:

  • dxdtfrac {dx}{dt}dydtfrac {dy}{dt}这两个分别表示特征点在x和y方向上的移动速度。
  • dIdxfrac {dI}{dx}dIdyfrac {dI}{dy}表示在x和y方向上的灰度变化,其实就是x方向和y方向相邻像素灰度值之差
  • dIdtfrac {dI}{dt}表示同在(x,y)处,t时刻与t+dt时刻两个时刻的周围灰度值变化

当然现在我们只有一个方程无法解得dydtfrac {dy}{dt}dxdtfrac {dx}{dt}。但是我们可以有很多特征点,而同一个图片上的特征点默认他们是移动速度是一样的,多个特征点一定可以解得dydtfrac {dy}{dt}dxdtfrac {dx}{dt}。下面是我们取k个特征点时候的得到的k个方程,我们只需要解这个线性方程即可得到dydtfrac {dy}{dt}dxdtfrac {dx}{dt}。得到这个两个了,dtdt是时间间隔我们是知道的,那么就很容易计算出下个时刻t+dtt+dt的特征点在图片中的位置(x+dx,y+dy)。
[[dI1dx,dI1dy]...[dI1dx,dI1dy]][dxdtdydt]=[dI1dt...dIkdt]egin{bmatrix} [frac {dI_1}{dx},frac {dI_1}{dy}]\ ...\ [frac {dI_1}{dx},frac {dI_1}{dy}] end{bmatrix} egin{bmatrix} frac {dx}{dt} \ frac {dy}{dt} end{bmatrix} =egin{bmatrix}frac {dI_1}{dt}\ ... \ frac {dI_k}{dt} end{bmatrix}

具体代码实现:
https://ww2.mathworks.cn/matlabcentral/fileexchange/48744-lucas-kanade-tutorial-example-1
https://ww2.mathworks.cn/matlabcentral/fileexchange/48745-lucas-kanade-tutorial-example-2

知乎 https://www.zhihu.com/people/yuanmuou/activities
原文地址:https://www.cnblogs.com/ailitao/p/11047261.html