Lucas Kanade 光流:理解数学

Lukas Kanade optical flow: Understanding the math

我找到了 LKT 算法的 Matlab 实现 here,它基于亮度恒定方程。

该算法通过将图像与适当的 2x2 水平和垂直边缘梯度运算符进行卷积来计算 x 和 y 方向上的图像梯度。

经典文献中的亮度恒常方程右边是两个连续帧之间的差异。

但是,在前面提到的link的实现中,右边是卷积的差异。

It_m = conv2(im1,[1,1;1,1]) + conv2(im2,[-1,-1;-1,-1]);

为什么 It_m 不能简单地计算为:

it_m = im1 - im2;     

正如您所提到的,理论上光流计算只规定了逐个像素的差异。 然而,在实践中,所有自然(非合成)图像都包含一定程度的噪声。另一方面,微分是某种高通滤波器,会强调(高通)噪声与信号的比率。 因此,为了避免由噪声引起的伪影,通常在任何图像微分之前进行图像平滑(或低通滤波)(我们在边缘检测中也有这样的过程)。该代码正是这样做的,即在图像上应用移动平均滤波器以减少噪声影响。

It_m = conv2(im1,[1,1;1,1]) + conv2(im2,[-1,-1;-1,-1]);

(评论转换为答案。)

理论上取一个pixel-wise差是没有错的:

Im_t = im1-im2;

计算时间导数。在计算时间导数时使用空间平滑器可以减轻噪声的影响。

此外,看看 code 计算空间(x 和 y)导数的方式:

Ix_m = conv2(im1,[-1 1; -1 1], 'valid');

使用类似的内核和 valid 选项计算时间导数可确保矩阵 It_xIt_yIm_t 具有兼容的大小。

时间偏导数(沿 t)连接到空间偏导数(沿 x 和 y)。

将您正在分析的视频序列想象成一个体积、时空体积。在任何给定点 (x,y,t),如果您想估计偏导数,即估计该点的 3D 梯度,那么您将受益于拥有 3 个具有相同内核支持的滤波器。

有关为什么会这样的更多理论,请查看主题可控滤波器,或者更好地查看偏导数应该是什么的基本概念,以及它如何连接到方向导数。

通常,首先估计 2D 梯度,然后人们倾向于认为其次的时间导数与 x 和 y 分量无关。这可能而且经常会导致最终光流计算中的数值错误。处理这些错误的常用方法是进行前向和反向流估计,最后将结果合并。

考虑您正在估计的梯度的一种方法是它具有 3D 的支持区域。这样一个区域的最小尺寸应该是2x2x2.

如果您在第一张和第二张图像中都仅使用 2x2 滤波器进行 2D 渐变,则通过对两个滤波器的结果进行平均来收集 3D 体积的相应 FIR 滤波器。

大多数人都清楚您应该在 2D 中具有相同的滤波器支持区域这一事实:这就是为什么 Sobel 和 Scharr 运算符看起来像它们的样子。

您可以在此 Matlab toolbox that I made 中看到通过合理设计的光流微分算子得到的结果,部分是为了说明这一点。