首先,它不是您处理的 BCC,而是它的一阶近似值,通常称为光流约束(OFC)。
OFC 不适用于您的示例,原因是您使用了不适当的衍生工具估计。
当您注意到您有两张图像时,应该会出现第一个错误提示,一张用于 t=0,一张用于 t=1。您应该使用哪一个来估计 I_x 和 I_y 导数?你选择了 t=0,为什么不选择 t=1?一种方法可能是两者都取,然后取平均值,即:
I_x = ( I_x(t=0) + I_y(t=1) )/2
这样做会导致导数滤波器不再是 2 点,而是 4 点,内核延伸到 t 域。许多光流专家使用两种 I_x 代替平均,得到两种光流:一种向前,一种向后,然后他们可以对其进行后处理。
你如何选择你的派生估计器将严重影响你的光流算法的行为!
在处理差分方程的数值估计时,更常见的是使用集中微分估计,即:
I_x = (I(x+1,y) - I(x-1,y))/2
在光流中,这很常见,然后在靠近图像边界时恢复到较小的单边差异。
但是,在保持 OFC 时,这仍然不会像您希望的那样表现得那么好。如果你调查 OFC,它可以重写为:
I_t = - I_x v_x - I_y I_y
I_t = - | v | ( k毕业 (I))
其中v = (v_x, v_y) = |v| (cos(a),sin(a)) 是运动向量,k = (cos(a),sin(a)) 是运动的单位向量。量 ( k grad(I)) 是所谓的方向导数。为了保持这一点,您也不应该使用 2 点集中式差异。您应该做的是使用共享相同内核/支持区域的 I_t、I_x 和 I_y 的估计值。例如,这可以是 3×3×2 大小的过滤器。
在 Matlab 中,此代码可以是例如:
[dx, dy, dt] = grad3D(imNew,imPrev)
gg = [0.2163, 0.5674, 0.2163];
f = imNew + imPrev;
dx = f(:,[2:end end]) - f(:,[1 1:(end-1)]);
dx = conv2(dx,gg','same');
dy = f([2:end end],:) - f([1 1:(end-1)],:);
dy = conv2(dy,gg ,'same');
dt = 2*conv2(gg,gg,imNew - imPrev,'same');
人们有时仍然使用较小的衍生过滤器的原因是因为您不会丢失任何分辨率,这是使用较大内核的缺点。请注意,上述导数估计算法与在更粗略的尺度上执行 2 点导数不同。很多人都这么认为,但事实并非如此。
在我编写的关于光流的交互式教程和工具箱中,您可以对这些问题有更多的了解。使用以下选项运行工具箱:
in.method = 'gradient';
您将获得一个交互式选项,可以帮助您获得更多直觉。