这篇写光流基本原理,及经典算法Lucas-Kanade,Horn-schunk。大量图片和公式出自LearnOpen3和下面几个PPT。
相关论文,
[1] An Iterative Image Registration Technique with an Application toStereo Vision
[2] Determining optical flow
[3] Pyramidal Implementation of the Lucas Kanade Feature Tracker Description of the algorithm
光流
光流算法寻找一张图片上的像素在另一张图片的位置。这两张图片一般是时间序列图片。算法输出了像素的速度,也可以说是像素在这两张图片的相对位置变化。计算图片中每个像素的光流,称为稠密光流,而只对特定像素点计算光流的算法就是稀疏光流。
如上图,光流问题就是估计连续图像像素的运动,等价于寻找连续图像中像素的相关性。
关键假设
经典光流算法使用了如下假设
- 颜色/亮度恒定假设(Color Constancy/Brightness Constancy)
- 小运动假设
Brightness Constancy可知,
- Ix, Iy是I(x, y)在空间上的导数,即图像的梯度。通过Sobel filter等就可以获得。
- It为时间上的导数,可以通过两帧图像做减法获得。
- u, v代表光流,是未知量。这个方程有两个未知数,仅由一个像素是无法求解这个方程的。后续出现很多求近似解的算法,最有代表性的就是Lucas-Kanade与Horn-schunck
Lucas-Kanade算法
1981年,论文[1]提出了Lucas-Kanade算法。该算法引入一个新的假设求解上面这个方程 ——空间一致性假设。假设同一平面上邻近的点具有相似的运动,具体来说就是选取一个mxn的窗口,在此窗口内假定光流值相同,所以这种算法也被称为constant flow。举个例子,假设我们选取5x5的窗口,如果在此窗口内光流相同,我们就可以得到25个公式,
LK算法最初用于求稠密光流,但是由于其对角点有较多要求,因此通常只能应用于稀疏光流。
这个算法假设窗口内光流一致,然而这样的窗口不易选择。窗口越小,越容易出现孔径问题, 窗口越大,越无法保证窗口内光流的一致性。
举一个孔径问题的例子,
这个窗口内所有x轴方向的梯度为0(Ix(i,j)=0),只能算出v,而无法算出u。
Horn-Schunck算法
Horn-Schunck算法引入了另一种假设 - 平滑性。与LK的光流一致性不同,他认为相邻像素的运动是相近的,平滑的。
光强一致性
平滑性
在平滑性假设下,相邻像素的光流变化越小越好,
完整能量函数
全局约束算法需要引入能量函数E,算法的目的是获取合适的参数使得E最小 ,
优化过程
求解这个能量函数的最小值。
整个算法流程非常简单,
- 计算图像梯度Ix, Iy
- 计算前后两帧图像差It
- 初始化光流,比如说u=0, v=0
- 迭代求解上面两个方程,直到收敛。
光流金字塔
无论是Lucas-kanade还是Horn-schunck算法,均有小运动的假设。然而在实际场景的下,无法保证这个假设。Jean-Yves Bouguet在论文[3]中提出了光流金字塔算法,以改善小运动假设带来的弊端。
前后两帧图片(image1, image2)按照一定的比例缩放,最下面一层为原始大小图片。算法从最顶端开始计算光流,将上一层估计的结果作为下一层估计的起始输入进行估计,直到最后一层。因此这个过程也称为coarse-to-fine。
图像金字塔
代码
Github上关于LK和HS的代码,对论文还原的最好的来自Eric yuan。可以通过代码进一步理解论文。
https://github.com/xingdi-eric-yuan/optical-flow.git