光流估计论文阅读小结
最近在研究光流估计相关的论文工作,在此记录一下光流估计的发展历程。从最简单的 CNN 换个任务,到后续这么多年的发展,希望能梳理出一个脉络。也希望相关方向的大佬们不吝赐教,多多交流。
传说之始
FlowNet: Learning Optical Flow with Convolutional Networks【ICCV 2015】
传说,在最早的时候,CNN 能做的任务中并不包含光流估计。直到 FlowNet 给出第一套端到端监督 CNN,为 CNN 的传说又画上了浓墨重彩的一笔。

作者做了两套结构。FlowNetS 直接把两帧图像 cat 到一起,FlowNetC 用双分支提取特征,再通过 correlation layer 做匹配。这个 correlation 没有可学习参数,本质上就是两个位置特征向量的点积。decoder 会把上采样特征、encoder 同尺度特征和上一层 flow 拼起来,最终学习到四分之一分辨率光流,再插值回原图。
训练数据 FlyingChairs 一共有 22872 对图像,其中 22232 对训练,640 对测试。它用 Flickr 背景和椅子图片合成二维运动,画面很假,却比直接拿小规模 Sintel 训练有效。论文里,先用 Chairs 预训练再到 Sintel fine-tune,大约能少 1 pixel EPE;拿掉数据增强,Sintel 上还会再差约 2 pixel。
FlowNetC 也没有稳稳压过 FlowNetS。FlyingChairs test 上两者是 2.19 和 2.71,到了 Sintel Final test,FlowNetC 是 8.81,FlowNetS 则是 8.43。correlation 在训练域和干净画面上有帮助,碰到 motion blur、fog 或更复杂的运动就不一定了。
GTX Titan 上,FlowNetS 和 FlowNetC 分别耗时 80 ms、150 ms。可选的 variational refinement 会把时间增加到 1 秒左右,在 Chairs 上还会让误差变大。FlowNet 证明了端到端 CNN 能做光流,精度仍低于当时最好的传统方法。
初露峥嵘
FlowNet 2.0: Evolution of Optical Flow Estimation with Deep Networks【CVPR 2017】
FlowNet 出来之后,问题很快就暴露了。作为开山作,性能却还不如传统方法,小位移和真实场景尤其拉胯。这怎么行,作者赶紧补了一篇 2.0。
FlowNet 2.0 主要改了三处。
- 调整训练数据和训练顺序。
- 堆叠多个 FlowNet,继续加算力。
- 增加小位移分支。
1. 改进数据
作者先在 FlyingChairs 上训练,再用更复杂的 FlyingThings3D 微调。原论文 Table 1 里,FlowNetS 只用 Things3D 训练后在 Sintel Clean train 上是 4.50,两类数据五五混合是 4.10,先 Chairs 再 Things3D 能到 3.79。论文把它叫作 curriculum learning,简单二维运动确实适合拿来做第一阶段训练。
2. 堆叠网络

第一个网络先预测 flow,用它把第二帧 warp 到第一帧。后面的网络继续接收两张原图、上一版 flow、warped image 和 brightness error,逐级修正结果。
Table 2 把 warp 的作用测得很清楚。单个 Net1 在 Chairs test 和 Sintel Clean train 上分别是 3.01、3.79。接第二个网络却不做 warp,Chairs 降到 2.60,Sintel 反而恶化到 4.29。冻结 Net1,再训练带 warp 的 Net2,两个数字变成 1.94、2.93。网络堆得更深也开始收益递减。C、CS、CSS 在 Sintel Clean train 上是 3.04、2.20、2.10,GTX 1080 上耗时则从 33 ms 增加到 51 ms、69 ms。
3. 针对小运动
作者又做了 ChairsSDHom,里面大多是小位移和大块平滑区域,再单独训练 FlowNet2-SD。这个分支去掉开头的 stride 2,把 7×7、5×5 大卷积换成多层 3×3,尽量保住小运动。最终模型把大位移分支、小位移分支一起送进 fusion network。
小运动训练有明确取舍。Middlebury train AEE 从 0.44 降到 0.38,KITTI 2012 train 却从 3.55 变成 4.05。最终 FlowNet2 在 Sintel test 上是 Clean 3.96、Final 6.02,GTX 1080 上耗时 123 ms。误差大幅降下来了,模型也膨胀到了 162M 参数。
魔童降世
Optical Flow Estimation Using a Spatial Pyramid Network【CVPR 2017】
在 FlowNet 茁壮成长的时候,一个小小的灵珠炸弹也在光流估计领域掀起了一点浪花。SPyNet 没有继续堆 FlowNet,走的是传统方法和 CNN 结合的路线。传统光流本来就在做 coarse-to-fine 空间金字塔,放到 deep learning 里同样可以用。
顺带说一句,我之前一直以为金字塔是目标检测那边搞出来的东西,这次看光流才知道,传统算法几十年前就在用了。
它先建立图像金字塔,从最粗的尺度开始估计 flow。到下一层以后,把上一层的 flow 上采样,用它 warp 第二帧,再让当前层的小网络预测 residual flow。大位移在低分辨率上会变小,每层网络只处理剩下的一点残差。

SPyNet 训练了 5 个尺度网络,每个都是独立的小 CNN,包含 5 个 7×7 卷积,各层不共享参数。整套模型只有 120 万参数、9.7 MB,比 FlowNet 小约 96%。论文表里给出的耗时是 69 ms,FlowNetS、FlowNetC 的 80 ms、150 ms 则引用自原论文。几组时间来自不同实验环境,只能看大致量级。
它也没有在所有 benchmark 上超过 FlowNet。Sintel Clean、Final test 分别是 6.69、8.43;针对 Final fine-tune 后是 8.36,仍高于 FlowNetS+ft 的 7.76。coarse-to-fine 对快速小物体尤其吃亏。Sintel Final 中位移超过 40 pixel 的区域,SPyNet+ft 的 EPE 是 49.71,FlowNetS 和 FlowNetC 分别是 43.24、40.78。小物体在粗尺度消失以后,后面的 residual 网络很难补回来。
PWC-Net: CNNs for Optical Flow Using Pyramid, Warping, and Cost Volume【CVPR 2018】
SPyNet 打开了传统方法结合 CNN 的大门,一年后 PWC-Net 横空出世。它在空间金字塔上加入可学习特征、feature warp 和局部 cost volume。
两帧图像先各自提取特征金字塔。每一层用上一层的 flow 把第二帧特征 warp 到第一帧坐标系,再和第一帧特征计算局部 cost volume,卷积网络据此预测当前层光流。最后还有一个 dilated context network。输出仍是四分之一分辨率,再插值回原图。

原论文 Table 5 把几个组件逐个拆开。只用 FlyingChairs 训练时,完整模型在 Sintel Clean、Final 上是 3.33、4.59,去掉 warp 后变成 3.79、5.30。context network 也有稳定收益,拿掉以后 Final 从 4.59 变成 4.74。cost volume 的搜索半径倒不用开得很大。每层最大位移设成 2、4、6 时,Final 分别是 4.50、4.59、4.60,金字塔已经把有效搜索范围放大了。
同一台 Pascal Titan X 上,FlowNet2 有 162.49M 参数,forward 84.80 ms;PWC-Net 是 8.75M 参数和 28.56 ms。PWC-Net-ft 在 Sintel test 上是 Clean 3.86、Final 5.13,KITTI 2015 test 的 Fl-all 是 9.60%。这些是各自 fine-tune 后的模型,不能当成一个模型同时拿到的结果。
LiteFlowNet: A Lightweight Convolutional Neural Network for Optical Flow Estimation【CVPR 2018】
如果说 FlowNet 2.0 是对 FlowNet 的力大砖飞,那 LiteFlowNet 就是在逐个处理 FlowNet 2.0 里留下的问题。它在每个金字塔层先做 descriptor matching,得到 pixel-level flow,再做 sub-pixel refinement。后面还有一个 Flow Regularization 层,用 feature-driven local convolution 约束局部流场。这里使用 feature warp,FlowNet 2.0 使用 image warp。

Table 4 的消融很直接。这些 variant 都只在 FlyingChairs 上训练,再放到 Sintel 和 KITTI 的训练集看迁移。以 Sintel Final 为例,只有 matching 时是 5.69,加 feature warp 后降到 4.81,再加 sub-pixel refinement 是 4.45,最后加 regularization 到 4.17。KITTI 2015 也从 18.24 依次降到 14.52、12.32、11.58,feature warp 带来的那一步最大。
LiteFlowNet 的 “30 倍” 指参数量。相同 GTX 1080 上,它有 5.37M 参数、耗时 90.25 ms;FlowNet2 是 162.49M 和 122.39 ms,速度只快 1.36 倍。论文没有报告 FLOPs 或 MACs。精度也要分数据看。LiteFlowNet-ft 在 Sintel Clean、Final test 上是 4.86、6.09,低于 FlowNet2-ft-Sintel;KITTI 2015 test 的 Fl-all 是 10.24%,又优于 FlowNet2-ft-KITTI 的 11.48%。用 on par 概括更合适。
IRR-PWC: Iterative Residual Refinement for Joint Optical Flow and Occlusion Estimation【CVPR 2019】
PWC-Net 之后,IRR-PWC 又把传统优化里的迭代思想搬了进来,同时加入遮挡估计。
PWC-Net 原来每个金字塔层都有独立 decoder,IRR-PWC 改成不同层共享同一个 decoder,反复预测 residual 再更新 flow。多跑几轮不会继续增加 decoder 参数。

论文先在相同训练设置下比较共享迭代和直接堆网络。跑到第 5 轮时,共享 IRR 在 Sintel Clean train 上是 3.302,独立堆叠 FlowNetS 是 3.517;IRR 从第 3 轮的 3.325 往后已经基本不再提升。PWC-Net 上只加 IRR,Sintel Clean、Final 从 3.13、4.41 降到 2.79、4.10,参数量减少 61.2%。完整模型加入双向估计、遮挡和 refinement 后是 2.34、3.95,参数量仍比 baseline 少 26.4%。
遮挡分支同时预测前向和反向 flow,再用独立 decoder 预测 occlusion mask。全分辨率 occlusion upsampling 会把 Sintel Final 的 F1 从 0.602 提高到 0.624,flow EPE 反而略有上升。这组实验至少说明上采样模块主要在修 mask,没有顺手把光流也一起抬高。
最终 IRR-PWC 在 Sintel test 上是 Clean 3.84、Final 4.58,参数量 6.36M;相同 fine-tune 设置下的 PWC-Net-ft-final 是 4.39、5.04 和 8.75M。KITTI 2015 test 的 Fl-all 是 7.65%。论文没有报告 runtime、FPS 或 FLOPs,因此只能确认参数量下降,推理时间还没法从论文数字里判断。
后面有机会的话,再把 RAFT、GMFlow 这些工作接着补上。