密集光流计算可以用于三维建模,运动特征提取,物体追踪等一系列实际应用中,是解决很多实际问题的基础。因此说,一个好的光流模型可以提升整个系统的表现。在此,我们主要讨论三个问题,即 如何选择图像的底层特征; 如何选择正则化的方法; 如何解决大位移的问题。它们也是我们在设计一个光流模型去解决实际问题中最基本的三个步骤。 在最后,笔者会提供一个 Python module (only for Mac),有兴趣的看官们可以下载这个模块,自己动手做一下实验 X )
另外,这篇文章的主要目的是通过几个简单的例子来介绍一种光流计算的思路,因此我们只讨论比较基本的模型。不同于本博中其他文章先理论后实验的结构,我们在这里边做实验边介绍模型。首先,我们拿下面一个 gif 动图做测试。
@H_403_5@1. 图像特征选择
Horn-Schunck Method (1981)是基于变分法光流计算的鼻祖。后来几乎所有的模型都是在这个模型上的改造。 Horn - Schunck 模型为,
这个模型的基本假设为,视频中第一帧图像在经过位移之后会完全变成第二帧图像。 也就是说,第一幅图像和第二幅图像的对应像素具有相同的颜色(或者灰度值)。不过这样的假设在实际问题中基本上是不存在的,或者因为相机硬件的不完美,或者因为光照条件会变化,或者因为其中的一部分被遮挡……
我们以光照发生变化为例,假设第二幅图像在原来光照的基础上加了50,那么颜色不变的假设肯定不准了。因此,我们就假设第二幅图片和第一幅图片对应像素的梯度不变,因为光照是个常数,而常数的导数为0. 这样一来,模型就变为
我们可以用实验结果对比一下两个模型,其中第一张是基于颜色不变假设的,第二张是基于梯度不变假设的。在图示中,箭头的方向即位移方向,箭头的长度即位移的大小。同时颜色也用来表示位移的大小,颜色越红,位移越大。我们可以看到,基于颜色的模型计算墙的位移更精确,而基于梯度的模型计算玩偶的位移更精确。
Fig. 1: 颜色不变假设 (Horn-Schunck 模型)
Fig. 2: 梯度不变假设
当然,我们还可以把两种图像的特征结合,比如颜色不变和梯度不变的权重为65:35, 那么我们可以得到如下结果,其中墙的位移被改善了。
@H_403_5@Fig. 3:
我们在此引入一个非常重要的概念,叫鲁棒性统计。当把鲁棒性统计法引入光流的时候,可以有效提升模型抵抗遮挡,旋转,局部阴影等缺陷的能力。而引入鲁棒性统计很简单,以 Horn-Schunck 为例,把它鲁棒化以后,得到如下模型,
其中
2. 正则化设计
我们可以看到,墙的位移和玩偶的位移是不同的,所以我们需要一个分段平滑的解。根据置顶的文章所说的那样,我们在这里修改 Horn-Schunck model 为,
用这个模型,我们可以得到下面的结果
@H_403_5@Fig. 4: 分段平滑正则化
我们可以和 Fig.1 对比,可以看到通过正则化理论改良后的模型,可以让光流变的分段平滑,墙和玩偶的位移差别很明显。
3. 大位移问题
在《光流基础》这篇博文中,我们的模型是建立在小位移假设的基础上,因此颜色不变假设的方程才能进行泰勒展开。所谓大位移问题,是指视频内的物体运动过快,导致位移过大,泰勒级数展开失效的问题。通常,位移大于7个像素可以认为是大位移问题。即然泰勒展开失效,那我们把最原始的能量泛函写出来:
很明显,这是一个非凸优化的问题!因此大位移问题如今仍然极难搞定。除了用很复杂的算法之外,很多人研究了很多更有效的方法,其中最著名的如 (1)warping scheme,(2)与point matching 结合,(3)lifting method。 其中(2)很直白,就是说,先通过关键点匹配把位移大的地方初始化,然后求解。(3)是很数学的方法,即先通过level set 把模型升维,在这个高维空间中模型变为convex, 求解后再映射回来。
这篇文里面,我们简要介绍warping scheme,因为简单直观,也成了业界标准。原理很简单,即把本来建模用的泰勒展开放进数值计算的框架里。所以,warping scheme 总共分这么几步:
initialisation:根据尺寸建立一个图片的pyramid,其中第 k 层的图片比 k+1 层的要小。然后根据各层图片的尺寸给各层的光流分配内存。
for k = 0: K
if k==0
光流的增量 = 0;
end;
把 k-1 层得到的光流放大到 k 层上;
计算第 k 层的 **光流的增量**;
光流的增量加上放大的光流,计算该层的光流;
去下一层;
end;
其实 Fig. 4 是带 warpling 的。 这里我们来看一看不带的结果。显然, warping 可以大幅度的提高精度。
@H_403_5@Fig. 5 没有 warping 的结果。
4. Python Module
欢迎看官下载尝试。如果用于其他用途,请务必注明来源!
Python Module for Optical Flow Computation by bloodbreaker