In defense of classical image processing: fast depth completion on the CPU
文章目录
摘要
随着数据驱动的深度神经网络作为一种通用函数逼近器的实现的兴起,大多数关于计算机视觉问题的研究已经远离了手工制作的经典图像处理算法。本文表明,通过一个设计良好的算法,我们能够在深度完成任务上优于基于神经网络的方法。该算法简单、快速,运行在CPU
上,仅依靠基本的图像处理操作对稀疏激光雷达深度数据进行深度完成。随着数据驱动的深度神经网络作为一种通用函数逼近器的实现的兴起,大多数关于计算机视觉问题的研究已经远离了手工制作的经典图像处理算法。本文表明,通过一个设计良好的算法,我们能够在深度完成任务上优于基于神经网络的方法。该算法简单、快速,运行在CPU
上,仅依靠基本的图像处理操作对稀疏激光雷达深度数据进行深度完成。
Introduction
通过深度神经网络实现通用函数逼近器,已经彻底改变了计算机视觉和图像处理技术。深度神经网络已被用于近似困难的高维函数,涉及目标检测[2],语义和实例级分割[3],甚至是驾驶汽车[4]的决策过程。这些函数逼近器在人工智能完成的[5]任务上的成功,已经导致研究界偏离了经典的基于非学习的方法来解决几乎所有的问题。本文旨在表明,与基于深度学习的方法相比,设计良好的经典图像处理算法仍然可以提供非常具有竞争力的结果。我们专门解决了深度补全的问题,即从图像和稀疏深度图输入推断出密集深度图。
深度完成是机器视觉和机器人技术的重要任务。目前最先进的激光雷达传感器只能在投影回图像空间时提供稀疏的深度地图。这限制了许多依赖于深度作为输入的感知算法的性能和操作范围。例如,3D对象检测算法[2]、[6]、[7]只有在对象有足够的点才能回归边界框。
深度补全提出了许多不同的方法。这些方法的范围从简单的基于双边上采样的算法[8]到基于端到端深度学习的算法[9]。后者非常有吸引力,因为由于它们具有数据驱动的特性,它们需要最少的人工设计决策。然而,使用深度学习方法会产生多种结果。首先,对嵌入式系统的计算能力是有限的。GPU
非常耗电,为每个模块部署一个GPU
是禁止的。其次,在没有适当理解问题的情况下创建深度学习模型可能会导致次优的网络设计。事实上,我们认为,用高容量模型来解决这个问题,只有通过尝试用经典的图像处理方法来解决它,才能提供良好的结果。
本文旨在证明,在某些问题上,基于深度学习的方法仍然可以优于设计良好的经典的基于图像处理的算法。为了验证这一点,我们设计了一个简单的仅依赖于图像处理操作的深度补全算法。该算法是非引导的,仅依赖于激光雷达数据,使其独立于图像质量的变化。此外,我们的算法不是基于深度学习的,不需要训练数据,使其对过拟合具有鲁棒性。该算法的运行速度与基于深度学习的方法一样快,但在CPU
上,同时性能优于定制设计的稀疏不变卷积神经网络。综上所述,我们的贡献如下:
- 我们提供了一个快速深度完成算法,在
CPU
上运行,并在KITTI
深度完成基准[10]的所有已发布的方法中排名第一。 - 我们表明,我们的算法优于基于
CNN
的方法,这些方法已经被设计为处理稀疏输入表示。(与字典学习和稀疏性和压缩感知有关系)
本文的其余部分的结构如下:第二节简要概述了最先进的深度补全算法。第四节从数学的角度描述了深度补全的问题,然后介绍了我们提出的算法。
Related Works
深度完成或上采样是一个活跃的研究领域,应用于立体视觉、光流和从稀疏激光雷达数据的三维重建。本节讨论了最先进的深度补全算法,同时将它们分为两大类:引导深度补全和非引导深度补全。
Guided Depth Completion:
属于这类方法依靠彩色图像指导执行深度地图完成。以往的各种算法都提出了联合双边滤波来对目标深度图[11]、[12]、[13]进行“孔填充”。中值滤波器也被扩展到从彩色图像引导[14]。最近,出现了深度学习方法来解决引导深度完成问题[15],[16]。这些方法已经被证明可以产生更高质量的深度图,但是它们是由数据驱动的,需要大量的训练数据来很好地泛化。此外,这些算法假设在规则网格上运行,当应用于非常稀疏的输入,如激光雷达传感器的深度图输出时,将失败。上述所有的引导深度补全模型都依赖于引导彩色图像的质量。随着相关彩色图像的质量下降,深度完成任务的性能也会下降。此外,深度图输出的质量与深度传感器和摄像机之间的校准和同步的质量高度相关。我们提出的算法是非引导的,不需要训练数据,解决了引导深度补全方法所面临的大部分问题。
![](https://i-blog.csdnimg.cn/blog_migrate/7749609c720185e1b85cd8d58ebd1e83.png)
图1-该算法的流程图。从左上角开始的顺时针方向:输入激光雷达深度图(能见度增强)、反转和膨胀、小孔闭合、小孔填充、向帧顶部延伸、大孔填充和模糊、输出反转、场景图像(未使用,仅供参考)。
Non-Guided Depth Completion:
![](https://i-blog.csdnimg.cn/blog_migrate/d09c8bafc55e486383d79433db08692a.png)
图2-一个总结公式1中描述的问题公式的玩具例子。空值用红色表示,并通过将函数f应用于Dsparse
来填充。
Problem Formulation
![](https://i-blog.csdnimg.cn/blog_migrate/f8e7712f7a85a3cb4157257e06a4c4a3.png)
这里,Ddense
是输出密集深度图,与I
和Dsparse
大小相同,空值替换为深度估计值。在非引导深度补全的情况下,上述公式与图像I
无关,如图2所示。我们通过下面描述的一系列图像处理操作来实现f_hat
。
![](https://i-blog.csdnimg.cn/blog_migrate/f8a6704f1551d2b1f52ae614e14ccc7c.png)
图3- Different kernels used for comparison.
Proposed Algorithm算法说明
如图1所示,所提出的方法是用Python
实现的,并使用一系列的OpenCV
[19]和NumPy
[20]操作来执行深度完成。我们利用了标准的OpenCV
操作的实现,它使用较大的像素值来覆盖较低的像素值。这样,稀疏性的问题就可以通过选择适当的操作来填充空像素来解决。通过利用OpenCV
操作的这一特性,我们通过下面描述的八步算法实现了深度补全。
该算法的最终结果是一个密集的深度映射Ddense
,可用作三维目标检测、占用网格生成,甚至同时定位和映射(SLAM)的输入。
Depth Inversion
:主要的稀疏处理机制是OpenCV
形态变换操作,它用较大的像素值覆盖较小的像素值。当考虑到原始的KITTI
深度图数据时,更接近的像素值接近0m
,而进一步的像素值最大值为80m。但是,空像素也取了0m
的值,这就阻止了使用无需修改的本机OpenCV
操作。在原始深度图上应用扩张操作将导致更大的距离覆盖更小的距离,导致更近对象的边缘信息丢失。为了解决这个问题,有效(非空)像素深度根据Dinverted=100.0−Dinput
反转像素深度,这也在有效和空像素值之间创建一个20m
的缓冲区(也就是说,没有值的位置,定义为0
,有值但是深度为零的位置,定义为20
)。这种反演允许算法在应用扩张操作时保持更近的边缘。20m
缓冲区用于偏移有效深度,以便在后续操作中屏蔽无效像素。Custom Kernel Dilation
:我们首先填充最接近有效像素的空像素,因为这些像素最有可能与有效深度共享接近的深度值。考虑到投影点的稀疏性和激光雷达扫描线的结构,我们设计了一个针对每个有效深度像素的初始扩展的自定义内核。内核形状的设计是使具有相同值的最有可能的像素被放大到相同的值。我们实现并评估了如图3所示的四种核形状。从第五节的实验结果来看,使用5×5的z钻石核
来膨胀所有有效像素。Small Hole Closure
:在初始膨胀步骤之后,在深度图中仍然存在许多孔。由于这些区域不包含深度值,我们考虑了环境中物体的结构,并注意到附近扩张深度的斑块可以连接起来形成物体的边缘。一种形态学闭合操作,采用5×5全核
,用于关闭深度图上的小孔。此操作使用了一个二进制内核,它保留了对象的边。这一步用于连接附近的深度值,可以看作是一组从最远到最近堆叠的5×5
个像素的平面(我理解:这句话的意思是,切出不同深度的平面,当然是按照不同的深度数值切,如果某一个深度单独拿出来之后,具备可以闭合成一个圈的条件,那就在这一步,用5*5的full核
把它们闭合)。Small Hole Fill
:深度图中的一些小到中型的孔没有被前两个膨胀操作填充。为了填补这些孔,首先计算空像素的掩模(a mask),然后计算7×7全核
扩张操作。此操作导致只填充空像素,同时保持以前计算过的有效像素不变。Extension to Top of Frame
:为了考虑高层物体,如树木、柱子和延伸到激光雷达点顶部的建筑物,每一列的顶部值被外推到图像的顶部,提供更密集的深度地图输出。Large Hole Fill
: 最后的填充步骤处理深度图中没有完全填充的较大孔。由于这些区域不包含任何点,也不使用任何图像数据,因此这些像素的深度值是从附近的值推断出来的。使用31x31完整内核
的扩展操作用于填充任何剩余的空像素,同时保持有效像素不变。Median and Gaussian Blur
:在应用前面的步骤之后,我们将得到一个密集的深度图。然而,异常值(outliers)作为扩张操作的副产品存在于这个深度图中。为了去除这些异常值,我们使用了一个5×5的内核
中值模糊。这个去噪步骤非常重要,因为它在保持局部边的同时去除异常值。最后,采用5×5
高斯模糊来平滑局部平面和圆形清晰的物体边缘。(嗯?为什么要平滑?而我们为什么要锐化边缘?)Depth Inversion
:我们的算法的最后一步是从算法的前面步骤中使用的反向深度值恢复到原来的深度编码。这是简单地计算为Doutput=100.0−Dinverted
倒置。
![](https://i-blog.csdnimg.cn/blog_migrate/438bd8d56e455014e90446b3fb4d9c74.png)
图4:我们提出的算法在KITTI测试集中的三个样本上的定性结果与稀疏CNN
和CNN
最近邻插值的比较,这两种方法都是在[9]中提出的。顶部:输出密集深度贴图。底部:可视化的估计中的像素级误差,从蓝色的低误差到红色的高误差。可以看出,我们的方法在估计过程中误差较小,特别是对较远的像素。
实验和结果
我们在KITTI
深度完成基准测试中测试了该算法在深度完成任务上的性能。最近发布的深度补全基准包含大量的激光雷达扫描投影到图像坐标中,以形成深度地图。利用前置相机校准矩阵将激光雷达点投影到图像坐标上,得到与RGB
图像相同大小的稀疏深度图。稀疏性是由于激光雷达数据的分辨率远低于它被投影到的图像空间而造成的。由于激光雷达扫描线的角度,只有底部三分之二的深度图包含点。发现在深度图的底部区域的点的稀疏度在5−7%
之间。每个深度图也提供了相应的RGB
图像,但我们的非引导深度补全算法没有使用。所提供的1000张
图像的验证集用于所有实验的评估,而1000张
图像测试集的最终结果由KITTI
的测试服务器提交并进行评估。使用逆均方根误差(inverse Root Mean Squared Error (iRMSE))
、反平均误差(iMAE)
、均方根误差(RMSE)
和平均平均误差``(Mean Average Error MAE)
度量对算法和基线的性能进行评估。我们建议读者通过[9]对这些指标有更深入的了解。由于方法是基于KITTI
的测试服务器上的RMSE
进行排序的,所以RMSE
度量被用来作为选择最佳设计的标准。
A.Performance on the Depth Completion Task
在提交时,所提出的算法在RMSE
和MAE
指标上的所有已发布的方法中排名第一。表I提供了与基线纳达拉亚-沃森核方法(纳达拉ayaw)的比较结果,以及基于学习的方法稀疏不变CNN
(稀疏convs)和CNN``(NN+CNNCNN)
[9]的最近邻插值,所有这些都是专门为处理稀疏输入而定制的。我们的算法比在KITTI
数据集上领先的NN+CNN
更好,在RMSE
是131.29mm
,在MAE
是113.54mm
。这相当于最终点云结果中11cm
平均误差的差值,这对于精确的三维物体定位、避障和SLAM
非常重要。此外我们提出的算法在英特尔酷睿i7-7700K
处理器上以90Hz
运行,而第二和第三个排名的方法都需要一个额外的GPU
分别以50
和100Hz
运行。
![](https://i-blog.csdnimg.cn/blog_migrate/6beb2b2125ee533fbaba4a81d3ddaade.png)
表一:纳达拉亚-Watsan核基线、稀疏有线网络、CNN最近邻插值和我们的方法在KITTI深度完成测试集上的性能比较。结果由KITTI的评估服务器[10]生成。
B. Experimental Design
在设计算法时,采用了一个贪婪的设计程序。由于有效像素附近的空像素可能共享相似的值,我们用较小的孔填充构造较大的算法顺序。这允许每个有效像素的效应面积缓慢增加,同时仍然保持局部结构。剩下的空白区域被外推,但比以前小得多。最后一个模糊步骤用于减少输出噪声和平滑局部平面。
首先探讨了设计选择对膨胀核大小的影响,然后是该核的形状,最后是膨胀后使用的模糊核。我们选择每个实验的最佳结果来继续下一个设计步骤。由于这种贪婪的设计方法,前两个关于核大小和形状的实验不包括步骤7的模糊。最终的算法设计使用每个实验中表现最好的设计来获得最好的结果。
Custom Kernel Design
: 初始膨胀核的设计对算法的性能有很大的影响。为了找到一个最佳的膨胀核,一个完整的核的大小在3×3
,5×5
和7×7
大小之间变化。7×7
内核所扩展的深度值超过其实际效应面积,而3×3
内核扩展所扩展的像素不足以允许边缘通过以后的闭孔操作连接。表二显示,5×5
内核提供了最低的RMSE
。
利用核尺寸实验的结果,探讨了5×5
二进制核形状的设计空间。一个完整的内核被用作基线,并与圆形、交叉和菱形内核形状进行比较。膨胀核的形状定义了每个像素的初始效应面积。表二显示,一个钻石内核提供了最低的RMSE
。金刚石核形状保留了圆形边缘的粗糙轮廓,同时足够大,允许边缘通过下一个孔关闭操作连接。
需要注意的是,膨胀核的大小和形状对运行时没有显著影响。
![](https://i-blog.csdnimg.cn/blog_migrate/637a6f4d7ffb310cdbdc4be83f1e1360.png)
表二:膨胀核的形状和大小对算法性能的影响。算法设计首先对核大小进行贪婪优化,然后对核形状进行优化。
Noise Reduction through Blurring
: 由于环境的曼哈顿[21]特性,深度图输出包含许多小的平面和尖锐的边缘,以及在前面步骤中应用的一系列二值图像处理操作。此外,小的异常值区域可能会被扩张,提供错误的深度值斑块。为了对局部平面进行平滑,绕过(round off)对象边缘,去除离群深度像素,我们研究了中值、双边和高斯模糊对算法性能的影响。
![](https://i-blog.csdnimg.cn/blog_migrate/2339c8ee165ff69cc2651b60d920ea50.png)
表三显示了不同的模糊方法对算法的最终性能和运行时的影响。中值模糊被设计为消除椒盐噪声,使其有效地消除离群值的深度值。这个操作为运行时增加了2个ms
,但是有所改进可以通过RMSE
和MAE
的减少来看出。双边模糊通过只模糊像素与其他具有相似值的像素来保持局部结构,并且对评估的RMSE
和MAE
指标的影响最小,同时向运行时添加4个ms
。由于RMSE
度量的欧几里得计算,高斯模糊通过最小化离群像素深度的影响,显著降低了均方根误差。高斯模糊也运行得最快,平均运行时只增加了1个ms
。最后的算法采用了中值和高斯模糊,因为这种组合提供了最低的RMSE
。
图5显示了在KITTI
对象检测基准测试中的一个样本的投影点云上使用两个不同的模糊核运行算法的结果。将深度值扩展到框架顶部和大孔填充的步骤被跳过了,因为它们引入了大量的外推深度值。对于不需要完全密集深度图的应用程序,建议限制每列的向上扩展和扩展内核大小(意思是说:为了节省运算时间,向上延伸的过程,可以做一个限制,不需要一直延伸到顶部)。虽然高斯模糊版本提供了最低的RMSE
,但它也为场景引入了许多额外的3D点
。双边模糊版本保留了对象的局部结构,并被推荐用于实际应用。需要注意的是,这些点是使用RGB
图像进行着色的,但在我们的非引导方法中没有使用图像数据。一个精确、更密集的点云可以用于依赖于点云数据的三维目标检测方法[2]、[6]、[22]进行目标分类和定位。在深度补全后,可以看到真实标记的物体包含更多的点。汽车和道路场景变得更加清晰,这一点对于更远的物体尤其明显。更多的定性结果可在视频格式上获得https://youtu.be/t CGGUE2kEM
(已失效)。
结论
在这项工作中,我们提出了一种深度补全算法,以稀疏深度图输出,密集深度图作为输入。我们提出的算法只使用了传统的图像处理技术,不需要训练,就可以制作过度拟合是鲁棒的。我们展示了我们的基于图像处理的算法提供了在KITTI
深度完成基准上的最先进的结果,优于几种基于学习的方法。我们的算法也在90hz
实时运行,不需要任何额外的GPU
硬件,这使得它成为部署在嵌入式系统上的竞争候选者,作为更复杂任务的预处理步骤,如SLAM
或3D
对象检测。最后,这项工作并不是要削弱深度学习系统的力量,而是要阐明当前文献中的趋势,在文献中,经典的方法没有被仔细考虑进行比较,尽管如果设计得当,它们可以成为强大的基线。
ip_basic文献阅读笔记
- 我是不是没有考虑,原本有数值的位置,应该保留原有的位置。(这也是刘sir让我考虑补全,是在做什么事情的目的?)
我原本的输出,的确是有规律的在貌似应该具有测量值的位置上,产生了一些异常点。
- 我是不是也可以,类似ip_basic的方法,即便间隔jg取了10,先把他们周围的点,补全一圈,就用diamond的5*5的kernel,这是不是可能把原有的大间隔的结果,趋近于小间隔的结果?
- ip_basic最后一步,除了通过均值滤波处理异常值了,之后又通过高斯滤波平滑了边缘。我不理解了,为什么要平滑边缘?而我们为什么要锐化边缘?