【单目3D检测】smoke(1):模型解析

07-17 1801阅读

SMOKE是纵目科技在2020年提出的单目3D检测新方法,论文展示了一种新的3D目标检测方法,该方法通过将单个关键点估计与回归3D变量相结合来预测每个检测到的目标3D bounding box。SMOKE延续了centernet的key-point做法,认为2d检测模块是多余的,只保留了3d检测模块,预测投影下来的3dbox中心点和其他属性变量得到3dbox。整体来说SMOKE框架简洁,性能当年还算不错,推理速度快,部署起来方便!

题目:SMOKE:Single-Stage Monocular 3D Object Detection via Keypoint Estimation

代码:https://github.com/lzccccc/SMOKE

Introduction

2D目标检测目前已经在精度和速度上都取得了不错的成绩,而3D目标检测由于需要同时估计出目标的位置与姿态,因此相比2D是一个更具挑战的方向。

目前性能最好的3D目标检测还是需要依赖激光雷达的点云或者点云+图像融合,考虑到成本因素,仅依靠单目摄像头的3D目标检测还是非常值得研究的。

本作有以下几个贡献点:

  • 提出了一个one-stage单目3D检测方法,思路简答,且end-to-end。
  • 3D框8个角点的计算使用了多种方式得到,每种方式都参与了loss的计算,使训练更容易收敛。
  • 在KITTI数据集上达到了SOTA。

    网络总述

    网络结构非常简洁,backbone接两个head,分别为分类head(heatmap)和回归head。

    【单目3D检测】smoke(1):模型解析

    backone

    使用dla34,这与centernet中的网络结果一致,唯一的改变就是将BN替换为GN(group norm),因为GN对batch size不那么敏感。输出尺寸为[H/4, w/4,C]。网络结构中包含多个cross path、下采样与上采样。如下图(来自于centernet):

    【单目3D检测】smoke(1):模型解析

    3d detection

    3d检测模块(head)分为两部分:(1)key-point分支,即heatmap分类分支;(2)回归分支。结构图如下:

    【单目3D检测】smoke(1):模型解析

    key-point(heatmap)分支

    与centernet不同的是这里预测3d box中心点投影下来的在2d图像上的点,而不是2d box的中心点。因为本文中直接抛弃了2d检测分支,而通过3d box中心点的投影点可以辅助恢复相机坐标系下的3d box的xy,所以这里用3d box投影下来的点更合适,在其他文献中也指出了用投影下来的点更容易建立2d和3d的关系。heatmap制作与centernet类似,不再赘述。

    两个点的差异在近处目标上尤其明显。如下图红色为2d box中心点,橙色为3d box中心点投影下来的点。这个问题在很多单目检测算法中都会提及到,我们在之后的文章解析中还会再次看到。

    【单目3D检测】smoke(1):模型解析

    reg head预测与3d属性相关的变量。

    【单目3D检测】smoke(1):模型解析

    这里使用e的幂次是为了保证正数乘到均值上,结果一定为正。实际在网络输出加了sigmoid来映射:

    【单目3D检测】smoke(1):模型解析

    【单目3D检测】smoke(1):模型解析

    【单目3D检测】smoke(1):模型解析

    【单目3D检测】smoke(1):模型解析

    【单目3D检测】smoke(1):模型解析

    【单目3D检测】smoke(1):模型解析

    来看下代码:smoke/smoke/modeling/smoke_coder.py:200

    def decode_orientation(self, vector_ori, locations, flip_mask=None):

    locations = locations.view(-1, 3)

    rays = torch.atan(locations[:, 0] / (locations[:, 2] + 1e-7)) # 计算theta,用的gt

    alphas = torch.atan(vector_ori[:, 0] / (vector_ori[:, 1] + 1e-7)) # arctan(sin/cos)

    # get cosine value positive and negtive index.

    cos_pos_idx = torch.nonzero(vector_ori[:, 1] >= 0) # 比较cos值是否大于0,判断属于哪个区间

    cos_neg_idx = torch.nonzero(vector_ori[:, 1]

    alphas[cos_pos_idx] -= PI / 2 # 通过这步转换为kitti中的alpha角度定义

    alphas[cos_neg_idx] += PI / 2

    # retrieve object rotation y angle.

    rotys = alphas + rays # ry = alpha + theta

    而且还对sin,cos做了norm,将值域放到了-1,1之间。

    【单目3D检测】smoke(1):模型解析

    基于上面估计量,就可以计算出3dbox的8个角点坐标了。

    【单目3D检测】smoke(1):模型解析

    【单目3D检测】smoke(1):模型解析

    【单目3D检测】smoke(1):模型解析

    数据增广

    heatmap分类分支。包括水平翻转、多尺度、平移。

    针对回归分支,只做了水平翻转。因为3d属性会随着缩放平移变化,需要对标签也做相应修改。

    结果

    1. 仅用了60epoch就收敛,说明确实收敛更快了。
    2. test数据上比其他算法好,而val上不如其他算法。说明smoke需要更多数据才能训好,也说明kitti的val(当然这个val是人为划分的)和set设置不是很合理。

      【单目3D检测】smoke(1):模型解析

    3. 回归中将不同属性的loss解耦后,性能提升明显。不同属性间会相互影响,这是单目检测或者多任务中经常面临的问题,而解耦loss是常用的解决方案。具体可以参考:Disentangling Monocular 3D Object Detection。

      【单目3D检测】smoke(1):模型解析

    4. 对比了GN和BN,GN效果更好,训练更快。

      【单目3D检测】smoke(1):模型解析

    5. 其他细节还有使用本文中sin/cos编码角度比四元数效果要好。本文无2d模块,将3d结果投影到图像作为2d检测结果,性能也不错。

    总结

    优点:整体来看本文框架简洁,性能不错,推理也快。

    缺点:在实测表现中说

    实测表现

    框架简洁带来的结果就是性能上限有限,对于实际使用需要慎重。

    单卡训练性能较差,必须多卡才可能接近作者报告的指标

    依赖dcn,对落地部署不友好。

    漏检严重,主要是小目标时高斯半径为0导致的。

    角度估计误差太大,实践中发现这个问题非常突出,而且算法的泛化性也不太好。

    参考:https://zhuanlan.zhihu.com/p/452676265

VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]