写在前面
总算有时间写点东西,整理了一篇近期看的论文《A Large Dataset to Train Convolutional Networks for Disparity, Optical Flow, and Scene Flow Estimation》的阅读笔记。如有转载请注明出处。
1. 背景知识
立体视觉
目的在于重构场景的三维几何信息。
三种研究方法:
- 程距法:直接使用测距器(如结构光,激光测距器)来获得程距信息建立三维描述。这是一种主动方式的立体视觉方法,已知的深度图,用数值逼近的方法重建表面信息,根据模型建立场景中的物体描述,实现图像理解功能。这类方法适用于严格控制下的环境,如工业自动化的应用方面。
- 单张图像推断三维形状:依据光学成像的透视原理及统计假设,根据场景中灰度变化导出物体轮廓及表面,由影到形从而推断场景中的物体。线条图的理解就是这样的一个典型问题,曾经引起了普遍的重视而成为计算机视觉研究领域的一个焦点,由此产生了各种各样的线条标注法。这种方法的结果是定性的,不能确定位置等定量信息,该方法由于受到单一图像所能提供信息的局限性,存在难以克服的困难。
- 多张图像恢复三维信息:这是一种被动方式的方法,根据图像获取方式的区别又可以划分成普通立体视觉和通常所称的光流两大类。普通立体视觉研究的是由两摄像机同时拍摄下的两幅图像,而光流法中研究的是单个摄像机沿任一轨道运动时顺序拍下的两幅或更多幅图像。前者可以看作后者的一个特例,它们具有相同的几何构形,研究方法具有共同点。双目立体视觉是它的一个特例。
其他基本概念
双目立体视觉匹配(底层视觉问题)
是从双目相机所获取的左眼图像和右眼图像中恢复出逐像素点的深度。由于双目相机中的平行极线约束,该问题又转化为左右眼图之间的逐像素匹配问题。
Disparity 视差 (与深度图是反比关系)
就是从有一定距离的两个点上观察同一个目标所产生的方向差异。
Optional Flow 光流
光流指空间运动物体在观察成像平面上的像素运动的瞬时速度。
Scene Flow 场景流
场景流指空间中场景运动形成的三维运动场,论文中使用Disparity,Disparity change和Optional Flow表示。
光流是平面物体运动的二维信息,场景流则包括了空间中物体运动的三维信息。
EndPoint Error(EPE)
对预测错误率的一种评估方式,指所有像素的ground truth和预测出来的光流之间的欧式距离的平均值,越低越好。
(u,v) 是算法估计出的结果, (ug,vg) 是真实值。
2. 文章主要贡献
数据集:论文使用开源的3D Creation Suite Blender渲染出一系列带有复杂运动模式的物体双目图片。渲染时从3D到2D且物体及场景的三维模型已知,生成训练数据集。
模型:Dispnet,SceneFlownet(由一个Flownet和两个Dispnet组成)模型训练使用人工合成的数据集。
3. Dispnet的网络
Dispnet的网络结构是在Flownet的结构上进行的修改。因此先介绍Flownet的网络,然后介绍Dispnet的变化部分。
3.1. Flownet的网络结构
3.1.1. 整体思路:
收缩部分——主要由卷积组成,用于深度的提取两张图片的一些特征
扩大部分——智能的把结果由粗到细,恢复到高像素
3.1.2. 缩小部分
FlowNetS:两张图片的通道concat,输入通道为6
FlowNetC:两张图片分开处理(分开处理时经过相同的layer),得到各自的特征图,再找到特征图之间的联系。这里涉及一个corr层。
两个特征图分别为f1,f2: w * h * c, 然后corr层比较这两个特征图各个块。比如以x1为中心的一块和以x2为中心的一块,它们之间的联系用以下公式计算,块长为K:= 2k+1,大小为 K*K。
该公式和卷积的操作是一样的,以x1为中心的patch和以x2为中心的patch,对应位置相乘然后相加,这就是卷积核在图片上的操作啊,只是卷积网络里是和filter之间进行卷积,且它的weight是不需训练或不可训练。计算这两块之间的联系计算复杂度是 c * K * K,而f1上每个块都要与f2上所有块计算联系,f1上有w * h个块(每个像素点都可以做一个块的中心点),f2上也有w * h个块,所有整个计算复杂度是c * K * K * ( w * h) * ( w * h),这里是假设每个块在下一张图上时,可以移动任何位置。但是这样计算复杂度太高了,所以我们可以约束位移范围为d(上下左右移动d),就是每个块只和它附近D: 2d+1的位置块计算联系,而且以x1为中心的块去和它附近D范围计算联系时,还可以加上步长,就是不必和D范围的每个点都进行计算,可以跳着。
3.1.3. 放大部分
一边向后unconv,一边直接在小的特征图上预测,然后把结果双线性插值然后concat在unconv后的特征图上,然后接着往后传,重复四次后,得到的预测光流分辨率依然是输入的1/4,再重复之前的操作已没有太多提升,所以可以直接双线性插值得到和输入相同分辨率的光流预测图。
在最后的双线性插值放大上还有个可选方案就是variational approach。
3.2. Dispnet的网络结构
上图为DispnetS的结构,对应于FlowNetS,主要有3点改变:
- label的augmentation里多了一个dummydata——辅助实现,对效果无影响,多加一个dummydata是因为FlowAugmentation要求ground truth的channel需为2(原来处理flownet,光流的chhannel为2)。
- 放大部分在每个deconv和前一预测结果的concat后增加一个卷积层——文中解释是这样做得到的结果图更为平滑。
- 放大部分比Flownet多做了一次deconv——得到的结果图分辨率更高
Flownet 384*512->96*128
Dispnet 384*768->192*384
DispNetCorr1D结构对应FlowNetC ,除了上述与DispnetS一样的改变,对corr做了一些变换:
- DispNetCorr1D是两层卷积后做corr,FlowNetC是三层卷积后做corr;
- DispNetCorr1D将corr操作变为一维操作,只在x方向上做运算;
- 对于corr layer的一些参数设置进行了更改:
左为FlowNetC,右为DispNetCorr1D
4. 训练过程
端对端训练:Given the images as input and the ground truth as output。
优化方式:Adam
学习率:1e-4
divided it by 2 every 200k iterations starting from iteration 400k.
loss weight:
We found that using a loss weight schedule can be beneficial: we start training with a loss weight of 1 assigned. to the lowest resolution loss loss6 and a weight of 0 for all other losses (that is, all other losses are switched off). During training, we progressively increase the weights of losses with higher resolution and deactivate the low resolution losses. This enables the network to first learn a coarse representation and then proceed with finer resolutions without losses constraining intermediate features.
数据扩充
spatial (rotation, translation, cropping, scaling)
chromatic transformations (color, contrast, brightness)
For disparity, any rotation or vertical shift would break the epipolar constraint, and horizontal shifts between stereo views could lead to negative disparities.
旋转或垂直移动会破坏极线约束,水平移动可能导致错误视差。
因此,dispnet数据扩充无rotate。
5. 实现细节
5.1. 数据扩充
CustomData——读取数据,根据slice_point切割channel,输出为img0,img1,groundtruth
Eltwise——按元素操作层。支持3种基本操作:
PROD:按元素乘积 SUM:按元素求和(默认) MAX:保存元素大者
在dispnet中用于数据归一化[0,255]->[0,1]
DataAugmentation——对数据集进行扩充, aug params变换系数,42维
输入为归一后的orig data,输出为augmented data和aug params
输入为归一后的orig data和aug params,输出为augmented data
GenerateAugmentationParameters——生成适合于当前图片的变换参数
输入aug params,orig data, augmented data
输出适合orig data的aug params,这些操作与之前那张图片的操作相符
FlowAugmentation——对ground truth进行与图片相同的变换
输入FlowField, Img1TransfParams, Img2TransfParams
输出groundtruth_aug
DummyData——虚拟数据,可以用这一层模拟预测过程,常用来debug,也可以用来测试网络传递时间
Slice——按维度对输入进行切片,ground truth切片channel为1
5.2. 缩小部分
Convolution——对原有conv进行了修改,支持多bottom多top(此处也可以不修改conv,对对应layer进行参数共享达到同样的效果)
ReLU
5.3. 放大部分
Downsample——双线性插值放大图片
L1Loss——计算与euclidean_loss_layer等价,多线程
Deconvolution
Silence——SilenceLayer的作用就是避免在log中打印并没有使用的blobs的信息。作为一个output的管理层,梯度是0
Resample——恢复预测结果分辨率为原图大小,用于deploy.prototxt中,使用线性插值
阅读参考:
- A Large Dataset to Train Convolutional Networks for Disparity, Optical Flow, and Scene Flow Estimation
- FlowNet: Learning Optical Flow with Convolutional Networks
- http://www.xuebuyuan.com/1541954.html