基于FlowNet的光流估计

我为什么要写这篇文章?

因为我最近在读FlowNet【1】这篇论文,虽然网上多多少少有一些相关的博客,例如【2】【3】【6】,但我发现很少有对这个论文中的一些细节介绍得比较详细的review,所以本文就出现了。本文会先简要介绍一下光流的概念,主要的重心还是在FlowNet这个论文一些细节的介绍上。

我会延续自己的风格,尽最大的努力,用intuitive的表述来介绍相关概念和算法流程,当然也包括数学公式。如果你觉得本文哪里还是有问题,请毫不犹豫地怀疑是我错了,无论是理解错误、表述错误、还是打字错误,并在评论区指出。

1. 光流的基本概念

光流(Optical Flow)呢,这是一个有关物体运动的概念。这个概念最早由Gibson提出,描述的是空间中运动的物体在成像平面上,造成像素运动的瞬时速度。这个运动主要包括三大类: - 场景中前景目标本身在移动; - 成像平面在移动(比如,相机); - 或者两者共同运动而所产生的混合动作。

反正无论怎么运动吧,在时序上,必然是会产生一些列连续的图像帧,而且这些帧之间的像素有有一定的对应关系。比方说,视频的第 基于FlowNet的光流估计 帧在左上角有一只鸟,经过10帧后(即第 基于FlowNet的光流估计 帧时),这只鸟成像在了图片的右上角,并且这个“飞”的过程是连续,从而形成一系列连续变化的图像(也就是连续的10帧),产生类似光“流动”的效果,故被简称为光流(Optical Flow)。

光流是一个有方向、有长度的矢量,我们需要做的就是,根据2个连续的帧来求解对应像素的运动速度(你说偏移量也没问题),下图是光流问题的一个示意图。

基于FlowNet的光流估计

在光流中,有个亮度恒定假设(Brightness Constancy Assumption),即同一物体在连续的帧间运动时,其像素值都不会改变(也就是上面举例说的,那只鸟不会因为飞了一下就变了样子)。根据该假设可以得到:

基于FlowNet的光流估计

而根据泰勒公式可得 基于FlowNet的光流估计 , 从而有 基于FlowNet的光流估计 ,记 基于FlowNet的光流估计 分别为光流沿着 基于FlowNet的光流估计 和 基于FlowNet的光流估计 方向上的变化量,从而可以得到以下光流基本方程:

基于FlowNet的光流估计

其中 基于FlowNet的光流估计 均可以有连续两帧计算得到,这显然是一个由一个方程求解两个未知量的问题,需要添加约束,而根据约束条件的不同,就导致了不同的光流场计算方法。下面简单介绍两种已有的方法,H&S【4】和FlowNet【1】,各自代表了传统方法和基于深度学习的方法两类。

2. Horn & Schunck

Horn & Schunck【4】光流估计法在光流基本方程的前提下,作出了光流平滑约束(Smoothness constrain),即认为光流的变化是光滑的,于是问题可以转化为最小化:

基于FlowNet的光流估计

被积函数是一个泛函数(即关于函数的函数),可以用变分法来求解。根据欧拉-拉格朗日方程(这个可以搜一下相关的数学证明,我记得Youtube上有个很棒的推导)可以求得:

基于FlowNet的光流估计

其中 基于FlowNet的光流估计 ,也就是二阶导,而在离散情况下,可以用Laplacian算子来求解二阶导,即用 基于FlowNet的光流估计 来代替 基于FlowNet的光流估计 ,其中 基于FlowNet的光流估计 为每个位置对应上下左右四个位置的平均值,从而有:

基于FlowNet的光流估计

于是可以得到如下解析解:

基于FlowNet的光流估计

用迭代的方法可以很容易求解光流。

PS:如果你对这一小节的数学推导不太明白,我强烈建议你去看一下Mubarak Shah教授的关于光流的Lecture【5】。>>传输门<<

3. FlowNet

FlowNet是第一个用CNN来估计光流的工作,并将光流估计这个问题看做成一个有监督的问题。其实说白了,光流估计就要根据两张连续的帧,去估计(也就是,猜)两帧之间pixel-wise的光流。凡是有关估计相关的东西,CNN都很在行,只要有足够的训练数据和一个较好的网络结构。FlowNet就开辟了这个工作,也创造了一个数据集。

>>FlowNet到FlowNet2.0:基于卷积神经网络的光流预测算法<<,这篇文章对FlowNet、FlowNet2都做了很好的介绍,建议移步去看看再过来,我这里就专注于网络中的细节了。

3.1 网络整体设计

在FlowNet中,作者设计了如上图所示的两种不同的架构:

基于FlowNet的光流估计

1. 把相邻两帧concat到一起作为网络输入,然后经过一些列的conv、pool、upsample等等又最终refine到和输入图片一样的大小,并得到估计的光流结果,这种架构简称为FlowNetS,也就是Simple的意思。

2. 因为估计光流实际上就是去让网络做像素级别的matching,于是作者提出了另外一种基于Correlation Layer的架构,简称为FlowNetC,也就是Correlation 的意思。

3.2 Correlation Layer

First thing first,也就是网络中的Correlation Layer。先看下FlowNetC网络在Correlation Layer之前部分的网络设计,作者设计了3个卷积和池化操作,得到了比较粗粒度的feature maps,这个部分,对于两帧都是共享的,也就是说两张图片都会过一遍这个部分。

基于FlowNet的光流估计

现在假设两张图片经过这个部分,分别得到各自的featur maps为 基于FlowNet的光流估计 和 基于FlowNet的光流估计 , 基于FlowNet的光流估计 分别代表特征图的通道数、高度和宽度,如下图所示,图中假设 基于FlowNet的光流估计 都为3,非数字部分是一圈padding。

基于FlowNet的光流估计

我们现在假设这个特征图中提取到的是图片的一些速度之类的信息(我瞎说的),然后我们希望可以根据 基于FlowNet的光流估计 和 基于FlowNet的光流估计 的每个位置相似度来得到一些关于两张图片偏移量的信息,那怎么求呢?

很简单的一个想法就是,对于 基于FlowNet的光流估计 和 基于FlowNet的光流估计 上的每个位置的组合,我们都求一次二者的相似度,比方说,我们想去求 基于FlowNet的光流估计 和 基于FlowNet的光流估计 在位置1处的相似度。但是一般我们都不会真的只求一个像素的相似度(准确地说,这里不应该叫像素,而是特征图上的每个cell),因为图片像素的特征往往都是和相邻特征是有关的,相应地,在特征图上,也就是相邻的cells是有关系的。于是为了求某个位置在两个feature maps上的相似度,我们会求以这个cell为中心的两个patch的相似度,并将这两个patch的相似度作为这个中心cell的相似度。如果我们去patch的大小为3,那么 基于FlowNet的光流估计 和 基于FlowNet的光流估计 在位置1处的相似度如下图所示,分别用橙色框和灰色框表示。

基于FlowNet的光流估计

 

也就是论文中的

基于FlowNet的光流估计

假设patch的大小为 基于FlowNet的光流估计 ,每一次的相关性操作的计算量为 基于FlowNet的光流估计 ,其中 基于FlowNet的光流估计 是特征图的通道数。对于 基于FlowNet的光流估计 和 基于FlowNet的光流估计 上的每个位置的组合(即 基于FlowNet的光流估计 和 基于FlowNet的光流估计 , 基于FlowNet的光流估计 和 基于FlowNet的光流估计 ...一直到 基于FlowNet的光流估计 和 基于FlowNet的光流估计 ),那么总的计算量为 基于FlowNet的光流估计 ,这也太大了。

于是作者作出了限制,理念就是说,虽然相邻的特征之间有关系,但也不至于要相邻到整个特征图的大小上去,现在我们假设特征图的大小不再是 基于FlowNet的光流估计 的,而是 基于FlowNet的光流估计 的,如下图所示,这里也加了一圈padding。

基于FlowNet的光流估计

现在我们定义一个邻居框,这个框的大小记作 基于FlowNet的光流估计 ,如果我们假设 基于FlowNet的光流估计 取值为3的话,那么我们认为,位置7处的值只和{1,2,3,6,7,8,11,12,13}处的值关系有关,和其他位置的关系不大。和之前说的一样,在求相关性操作的时候,也是基于patch的(即以当前cell为中心)。举例来说, 基于FlowNet的光流估计 就是上面橙色框和黄色框的卷积。

于是,在添加了邻居框后,对于输入 基于FlowNet的光流估计 中的每个cell,都会在 基于FlowNet的光流估计 中存在一个相应的邻居框内,且和框内每个cell都存在一个相关度(即 基于FlowNet的光流估计 个),我们把这个 基于FlowNet的光流估计 个相关度在输出时按照channel维度上叠加起来,从而correlation layer的输出特征图 基于FlowNet的光流估计 。

Ok,但愿我已经把这个细节操作讲明白了。别急,还没完,这只是细节1。

  • 细节2:其实在上面画图的时候,我是特意画了一圈padding的,因为我们要保证特征图上的每个cell都有一个patch。我想可能说作者嫌麻烦,索性把patch的大小 基于FlowNet的光流估计 中 基于FlowNet的光流估计 取了0,于是就成了 基于FlowNet的光流估计 大小的patch,很类似 基于FlowNet的光流估计 卷积核,就不需要再考虑padding操作了,瞬间简单了许多。
  • 细节3:在FlowNetC中, 基于FlowNet的光流估计 中的 基于FlowNet的光流估计 取值为20,即 基于FlowNet的光流估计 ,也就是说,输出特征图 基于FlowNet的光流估计 。channel维度1681个dimension???你想多了,这里又是一个细节。作者又加了一个stride操作,从而让 基于FlowNet的光流估计 ,于是correlation layer层的输出特征图 基于FlowNet的光流估计 。
  • 细节4:你以为细节3完了就没了? 对不起,还是没完!上面我们只是得到了correlation features,作者还在 基于FlowNet的光流估计 的channel维度上添加了关于图片特征的信息,也就是论文图2中的re_dir部分。

这下是真的讲完了,总的来说,可以归结为下面这个图(图来创作于Abbas Khan

 

基于FlowNet的光流估计

 

3.3 Refine部分

这一部分没什么太多隐藏的细节,按照下图coarse-to-fine的思路在上采样时不断把之前的特征融合就好了。

基于FlowNet的光流估计