1. Optical Flow
1.1 摘要
随着计算机视觉学界从图像理解转向视频理解,互联网用户从发布图片朋友圈转向发布短视频,人们对视频的研究和应用的关注不断增强。光流估计作为视频理解的隐形战士,等着我们去寻找其踪迹。
1.2 介绍
光流,顾名思义,光的流动。比如人眼感受到的夜空中划过的流星。在计算机视觉中,定义图像中对象的移动,这个移动可以是相机移动或者物体移动引起的。具体是指,视频图像的一帧中的代表同一对象(物体)像素点移动到下一帧的移动量,使用二维向量表示。如图2-1。
![](https://i-blog.csdnimg.cn/blog_migrate/bbb144ad773fb678e0d4875b0c71573e.png)
根据是否选取图像稀疏点进行光流估计,可以将光流估计分为稀疏光流和稠密光流,如图2,左图选取了一些特征明显(梯度较大)的点进行光流估计和跟踪,右图为连续帧稠密光流示意图。
![](https://i-blog.csdnimg.cn/blog_migrate/22a10419b10e36f87a55dbd75cd031f0.png)
稠密光流描述图像每个像素向下一帧运动的光流,为了方便表示,使用不同的颜色和亮度表示光流的大小和方向,如图2-2右图的不同颜色。图2-3展示了一种光流和颜色的映射关系,使用颜色表示光流的方向,亮度表示光流的大小。
![](https://i-blog.csdnimg.cn/blog_migrate/7683c30c0605edefbc51a0dfab0e4264.png)
1.3 算法
最为常用的视觉算法库OpenCV中,提供光流估计算法接口,包括稀疏光流估计算法cv2.calcOpticalFlowPyrLK()和稠密光流估计cv2.calcOpticalFlowFarneback()。
光流分为稀疏光流和稠密光流,稀疏光流就是只计算图片中特定点的光流,而稠密光流则是每个像素都要计算光流。
稀疏光流估计算法为Lucas-Kanade算法,该算法为1981年由Lucas和Kanade两位科学家提出的,最为经典也较容易理解的算法,下文将以此为例介绍传统光流算法。 对于最新的深度学习光流估计算法,FlowNet的作者于2015年首先使用CNN解决光流估计问题,取得了较好的结果,并且在CVPR2017上发表改进版本FlowNet2.0,成为当时State-of-the-art的方法。
1.3.1 Lucas-Kanade算法:
为了将光流估计进行建模,Lucas-Kanade做了两个重要的假设,分别是亮度不变假设和邻域光流相似假设。
![](https://i-blog.csdnimg.cn/blog_migrate/57ac5075b29aa70a02b40a97019b17fa.png)
![](https://i-blog.csdnimg.cn/blog_migrate/39ab1ccb8da4120a7fc592b47dc64538.png)
![](https://i-blog.csdnimg.cn/blog_migrate/0b7acebd8381b86d234f0be649439acc.png)
![](https://i-blog.csdnimg.cn/blog_migrate/725b97e031835652b655d54103a6b04f.gif)
可以说传统光流基于两个重要假设:
1)核心问题:同一个空间中的点,在下一帧即将出现的位置
2)重要假设:光流的变化是光滑的
由两个重要假设同时借助于角点信息来最终帮助完善光流算法。
即:角点处的光流能够通过角点邻域完全确定下来,因此角点处的运动信息最为可靠;其次是边界信息
1.3.2 深度学习光流算法
对于深度学习来做的光流估计,网络部分也是值得进行总结的。经典的FlowNet也是比较有一定时间的网络结果。
FlowNet1.0:
![](https://i-blog.csdnimg.cn/blog_migrate/4c3bb146d37c4c2a6fcc2f1660d85e2f.png)
网络结构上,采用的是编解码网络结构,其编码模块均为 9 层卷积,解码模块为 4 层反卷积。作者主要设计了两种结构,FlowNetSimple 和 FlowNetCorr,二者的编码模块不同。FlowNetSimple 直接将两张图像按照通道拼接后输入,因此输入的通道数为 6。FlowNetCorr 先分别对两张图像进行特征提取获得高层特征,再进行相关性运算(一种按图像匹配思想设计的算子)。解码模块的反卷积的每一层输入前一层的输出,同时还输入前一层预测的低尺度的光流和对应编码模块中的特征层。
FlowNet2.0:
![](https://i-blog.csdnimg.cn/blog_migrate/15328749ff363a5af4ca547b028cfab3.png)
Flownet2.0 是在 2017 年实现的FlowNet的改进算法。这个算法的主要改进一是通过堆叠多个 FlowNet 网络,实现由粗到精的光流估计。每次堆叠网络结构时,将当前得到的光流作用在第二帧上,做后向映射(backward warp),往第一帧图像的方向对齐;包括做图像brightness的比较和Flow的数值magnitude比较。改进二是通过实验发现 Flownet 对于比较小的物体运动估计不准。改进做法是将卷积核缩小并缩短卷积步长。Flownet2.0 合成了新的数据集,在 FlyingChairs 的基础上增加了一些小位移数据。同时,还混合了2017年提出的一个更复杂的数据集 Things3D(加入了各种各样的物体,并考虑了三维空间的运动)。最终 Flownet2.0 达到了传统的光流估计算法的最好结果,并且速度上比传统算法快两个数量级。
参考的blog是:
光流估计——从传统方法到深度学习
一文搞懂光流 光流的生成,可视化以及映射(backward warp)
2. grid-sample
参考博客:
Pytorch光流warp函数解读(grid_sample函数的使用)
grid_sample()函数及双线性采样
3. 可变性卷积
参考博客:
【视频超分】《Understanding Deformable Alignment in Video Super-Resolution》 2020
Understanding Deformable Alignment in Video Super-Resolution理解
统一先写一下感悟吧:
光流在H*W的图片上的计算结果就是H*W*2的矢量图,光流可以由input到output,也可以从output到input,这样我们根据output到input的光流图,将output图中的每一个像素逆向推导得到其应该在的input位置,这个时候因为光流可能非整数,所以就需要进行插值;但是每一个像素的插值情况又不相同,所以需要借助grid_sample这样自适应的插值方式来做到这件事情。
传统的光流计算就是这样的原理,但是deformable convolution的推出使得大家发现相比较于图片层级的flow计算与warp、align;在featuremap上面做warp和align的收益明显更大,伪影等artifacts引入地更少。