【论文解读】单目3D目标检测 CUPNet(ICCV 2021)

news2025/3/13 15:37:19

本文分享单目3D目标检测,CUPNet 模型的论文解读,了解它的设计思路,论文核心观点,模型结构,以及效果和性能。

目录

一、CUPNet简介

二、论文核心观点

三、模型框架

四、损失函数

五、核心观点——3D高度估计误差 引起深度推断误差

六、核心内容——GUP模块、HTL模块

6.1 提出GUP模块处理推断可靠性问题

6.2 提出HTL模块处理训练稳定性问题

七、实验对比与模型效果


一、CUPNet简介

CUPNet是基于几何约束和回归方式输出3D框信息,在不依赖dcn的情况下获得了较好的性能。

它也是一款两阶段的单目3d检测器,先回归2D框信息,在ROI区域进一步提取特征,生成3D框信息。

开源地址:https://github.com/SuperMHP/GUPNet

论文地址:Geometry Uncertainty Projection Network for Monocular 3D Object Detection

二、论文核心观点

论文核心观点,主要包括为两点:

  • 1、物体高度估计误差,对深度计算有着较大的影响。
  • 2、模型训练的稳定性。在模型训练初期,物体高度的预测往往存在较大偏差,也因此导致了深度估算偏差较大。较大误差往往导致网络训练困难,从而影响整体网络性能。
  • 3、推断可靠性问题。如果物体的高度预测存在较大偏差,相应计算出的深度值也会存在较大误差。

三、模型框架

CUPNet是一个两阶段的框架,实现单目3d检测的。模型结构如下:

Backbone:DLA34

Neck:DLAUp

第一部分 2D 检测:3个分支

  • 分支一 通过输出heatmap,预测所有类别的中心点(默认类别为3)。
  • 分支二 预测的2D框中心点的偏移。
  • 分支三 预测2D框的size。

第二部分 3D 检测:4个分支

  •  分支一 预测偏航角。
  •  分支二 预测3D框的size。
  •  分支三 预测中心点的深度值,和和其不确定性(深度学习偏差)。
  •  分支四 预测2D框中心点与真实的3D投影坐标之间的偏移。

模型结构如下图所示:(基于CenterNet的2D检测+ROI特征提取+基础3D检测头)

整体的模型结构,可分为4步:

  1. 输入图像,经过主干网络提取特征。
  2. 基于CenterNet的2D框预测部分,用于输出热力图,信息包括:2D中心点、偏移量、2D框的尺寸。
  3. 提取出ROI的特征。
  4. 利用所提取的ROI特征,输入到不同的网络头,以获得物体3D框信息,包括:偏转角度、尺寸、深度值、物体3d框中心在图像投影点的偏移量。

 在第四步时,首先估计出3D框除了“深度值”以外的所有参数,然后2D框与3D框的高度将被输入到GUP模块中,提取出最终的depth。

 

在输入端,图像将缩放到384×1280的大小,然后经过DLA的backbone获得96×320,通道数为64的特征图。随后经过三个简单的网络头输出2d信息 

2D 检测3个分支结构代码:

self.heatmap = nn.Sequential(nn.Conv2d(channels[self.first_level], self.head_conv, kernel_size=3, padding=1, bias=True),
                            nn.ReLU(inplace=True),
                            nn.Conv2d(self.head_conv, 3, kernel_size=1, stride=1, padding=0, bias=True))
self.offset_2d = nn.Sequential(nn.Conv2d(channels[self.first_level], self.head_conv, kernel_size=3, padding=1, bias=True),
                            nn.ReLU(inplace=True),
                            nn.Conv2d(self.head_conv, 2, kernel_size=1, stride=1, padding=0, bias=True))
self.size_2d = nn.Sequential(nn.Conv2d(channels[self.first_level], self.head_conv, kernel_size=3, padding=1, bias=True),
                            nn.ReLU(inplace=True),
                            nn.Conv2d(self.head_conv, 2, kernel_size=1, stride=1, padding=0, bias=True))

3D 检测4个分支结构代码:

self.depth = nn.Sequential(nn.Conv2d(channels[self.first_level]+2+self.cls_num, self.head_conv, kernel_size=3, padding=1, bias=True),
                                nn.BatchNorm2d(self.head_conv),
                                nn.ReLU(inplace=True),nn.AdaptiveAvgPool2d(1),
                                nn.Conv2d(self.head_conv, 2, kernel_size=1, stride=1, padding=0, bias=True))
self.offset_3d = nn.Sequential(nn.Conv2d(channels[self.first_level]+2+self.cls_num, self.head_conv, kernel_size=3, padding=1, bias=True),
                                nn.BatchNorm2d(self.head_conv),
                                nn.ReLU(inplace=True),nn.AdaptiveAvgPool2d(1),
                                nn.Conv2d(self.head_conv, 2, kernel_size=1, stride=1, padding=0, bias=True))
self.size_3d = nn.Sequential(nn.Conv2d(channels[self.first_level]+2+self.cls_num, self.head_conv, kernel_size=3, padding=1, bias=True),
                                nn.BatchNorm2d(self.head_conv),
                                nn.ReLU(inplace=True),nn.AdaptiveAvgPool2d(1),
                                nn.Conv2d(self.head_conv, 4, kernel_size=1, stride=1, padding=0, bias=True))
self.heading = nn.Sequential(nn.Conv2d(channels[self.first_level]+2+self.cls_num, self.head_conv, kernel_size=3, padding=1, bias=True),
                                nn.BatchNorm2d(self.head_conv),
                                nn.ReLU(inplace=True),nn.AdaptiveAvgPool2d(1),
                                nn.Conv2d(self.head_conv, 24, kernel_size=1, stride=1, padding=0, bias=True))

四、损失函数

CUPNet 的损失由7部分组成,

2D 框检测损失:3部分

  • 分支一 通过输出heatmap,预测所有类别的中心点;使用 Focal Loss 函数。
  • 分支二 预测的2D框中心点的偏移;使用 L1 Loss 函数。
  • 分支三 预测2D框的size;使用 L1 Loss 函数。

 

3D Detection损失:4部分

  •  分支一 预测偏航角。类别使用交叉熵损失,偏航角使用L1 Loss。
  •  分支二 预测3D框的size。长和宽为L1 Loss,权重占2/3,3D 高使用laplacian_aleatoric_uncertainty_loss() 函数,权重占1/3。
  •  分支三 预测中心点的深度值,和和其不确定性;使用 laplacian_aleatoric_uncertainty_loss() 函数。
  •  分支四 预测2D框中心点与真实的3D投影坐标之间的偏移;使用 L1 Loss 函数。

五、核心观点——3D高度估计误差 引起深度推断误差

在相机投影模型引入几何信息,在估计深度时采用“相似三角形模型”,如下图所示:

depth 是深度值、f是焦距、h_3d是实际物体高度、h_2d是图像中物体的高度。(h_3d、h_2d这种表述方式是打字比较方便,有些编辑公式支持)

在该关系下,depth估计可以转化为先估计h_3d与h_2d,再通过投影的方式得到。如果物体的高度预测存在较大偏差,相应计算出的深度值也会存在较大误差。

下面作者做了实验,由 ±0.1m 3D 高度抖动引起的深度偏移的可视化示例,图中画了一些BEV鸟瞰图的例子来展示误差放大的效果。

该图中,横轴和纵轴的单位均为米,纵轴对应深度方向。 绿色框表示原始投影输出。 蓝色和红色框分别是由 +0.1m和 -0.1m 3D高度偏差引起的移位框。

从图中可以看出,即使高度估计误差只有0.1m,也可能导致4m的深度值偏差

解决方案:

解决的问题其实是投影模型中的误差放大现象。我们对投影模型的输入加入一个微小的偏置,其输出则会变成原始的投影结果不确定性项(偏差项)引发的depth误差的和:

详细设计看GUP模块

六、核心内容——GUP模块、HTL模块

6.1 提出GUP模块处理推断可靠性问题

如果只会输出单一的深度值,作者提出Geometry Uncertainty Projection (GUP) 模块,它输出深度值+不确定度,这里的不确定度是用来表征当前深度值的可靠性。

思路流程:预测物体3D高度 → 做映射得到深度值 → 预测偏移量 → 深度值+偏移量得到最终的不确定度

a)预测物体3D高度。作者这里引入了Laplace distribution的假设,也就是假设物体3D高度的预测值是符合拉普拉斯分布的。

拉普拉斯分布可以用两个变量描述,均值和方差。期望3D高度预测值,均值越接近于ground-truth,方差=1最好。方差越趋近于1,表明当前高度预测值越稳定。

通过设计损失函数,让网络朝着我们希望的方向发展:

b)做映射得到深度值,如下式:

将预测出的3D高度带入,即可得到深度值。

c)预测偏移量,给深度值又加了一层不确定度的保障。

d)深度值+偏移量得到最终的不确定度。假设深度值和偏移量是符合拉普拉斯分布,最终的深度估计值可以有如下表示:

希望depth的均值无限接近于真值,其方差无限趋近于1。也就得到了下式的损失函数

6.2 提出HTL模块处理训练稳定性问题

在训练开始时,对h_2d和h_3d的预测都很不准确,会误导整体训练,损害训练表现。

  • 作者提出了一个多级task学习策略Hierarchical Task Learning (HTL) ,来进行多任务学习。
  • 既然所有模块合在一起训练不稳定,那就分开好了,分级训练,为不同模块指定不同的训练权重,用以控制其在模型训练中的重要性。

七、实验对比与模型效果

在KITTI 测试集上的 3D物体检测,用以粗体突出显示最佳结果

在KITTI 验证集,汽车类别,进行消融实验:

模型效果:

 分享完成~

【数据集】单目3D目标检测:

3D目标检测数据集 KITTI(标签格式解析、3D框可视化、点云转图像、BEV鸟瞰图)_kitti标签_一颗小树x的博客-CSDN博客

3D目标检测数据集 DAIR-V2X-V_一颗小树x的博客-CSDN博客

【论文解读】单目3D目标检测:

【论文解读】SMOKE 单目相机 3D目标检测(CVPR2020)_相机smoke-CSDN博客

【论文解读】单目3D目标检测 MonoDLE(CVPR2021)_一颗小树x的博客-CSDN博客

【论文解读】单目3D目标检测 MonoCon(AAAI2022)_一颗小树x的博客-CSDN博客

【实践应用】

单目3D目标检测——SMOKE 环境搭建|模型训练_一颗小树x的博客-CSDN博客

单目3D目标检测——SMOKE 模型推理 | 可视化结果-CSDN博客

单目3D目标检测——MonoDLE 模型训练 | 模型推理_一颗小树x的博客-CSDN博客 

单目3D目标检测——MonoCon 模型训练 | 模型推理-CSDN博客

后面计划分享,实时性的单目3D目标检测:MonoFlex、MonoEF、MonoDistillI、DEVIANT等

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1104037.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python之并发编程(进程)

文章目录 一、操作系统的发展史二、进程基础(操作系统中的概念)1.什么是进程2.进程的调度算法3.进程的并行与并发4.进程的三状态5.同步异步6.阻塞与非阻塞7.同步异步与阻塞非阻塞综合使用 三、如何创建进程Process的几个方法如何开启多进程进程间的数据默认隔离基于TCP协议的高…

【Qt控件之QButtonGroup】概述及使用

概述 QButtonGroup 类提供了一个容器来组织一组按钮部件。 QButtonGroup 提供了一个抽象容器,可以将按钮部件放置其中。它不提供此容器的可视表示(请参见 QGroupBox,用于容器部件),而是管理组中每个按钮的状态。 一个…

Electron webview 内网页 与 preload、 渲染进程、主进程的常规通信 以及企业级开发终极简化通信方式汇总

Electron 嵌入的页面中注入的是 preload.js 通过在标签中给 prelaod赋值,这里提到了 file://前缀,以及静态目录 static 怎么获取 实际代码,其中__static就是我们存放静态文件的地方,这个 static 是 electron 源代码根目录下的文件…

使用unordered_write调优RocksDB写性能

在使用rocksdb存储的服务中,我们发现QPS在4w/s就怎么调整都上不去了,写性能受到了某种限制。为什么呢?下图描述了rocksdb写入的流程。我们发现 unordered_write true可以提高写入吞吐量。 rocksdb的数据正常写入流程是,多个线程形…

九月 NFT 行业解读:熊市情绪仍占上风

作者: stellafootprint.network 9 月,著名主流媒体《滚石》(Rolling Stone)发表了一篇题为《你的 NFT 实际上——终于——完全不值钱了》(Your NFTs Are Actually — Finally — Totally Worthless)的文章&#xff0c…

【网络编程】从网络编程、TCP/IP开始到BIO、NIO入门知识(未完待续...)

目录 前言前置知识一、计算机网络体系结构二、TCP/IP协议族2.1 简介*2.2 TCP/IP网络传输中的数据2.3 地址和端口号2.4 小总结 三、TCP/UDP特性3.1 TCP特性TCP 3次握手TCP 4次挥手TCP头部结构体 3.2 UDP特性 四、总结 课程内容一、网络通信编程基础知识1.1 什么是Socket1.2 长连…

NumPy基础及取值操作

目录 第1关:ndarray对象 相关知识 怎样安装NumPy 什么是ndarray对象 如何实例化ndarray对象 使用array函数实例化ndarray对象 使用zeros,ones,empty函数实例化ndarray对象 代码文件 第2关:形状操作 相关知识 怎样改变n…

液压自动化成套设备比例阀放大器

液压电气成套设备的比例阀放大器是一种电子控制设备,用于控制液压动力系统中的液压比例阀1。 比例阀放大器通常采用电子信号进行控制,以控制比例阀的开度和流量,以实现液压系统的可靠控制。比例阀放大器主要由以下组成部分: 驱动…

tomcat 服务器

tomcat 服务器 tomcat: 是一个开源的web应用服务器。区别nginx,nginx主要处理静态页面,那么动态请求(连接数据库,动态页面)并不是nginx的长处,动态的请求会交给tomcat进行处理。 nginx-----转发动态请求-…

Golang学习:基础知识篇(三)—— Map(集合)

Golang学习:基础知识篇(三)—— Map集合 前言什么是Golang?Map集合定义 Map综合实例补充 前言 很久之前就想学Go语言了,但是一直有其他东西要学,因为我学的是Java嘛,所以后面学的东西一直是跟J…

Element-UI 日期选择器--禁用未来日期

在做项目的时候经常会遇到一些报表需要填写日期,一般是填写当日及当日以前,这时候我们的日期选择器就需要进行一些限制,比如: 这样之后,就不会误填写到明天啦,下面让我们看一下代码实现 html页面代码 这里…

Unity ECS最新DOTS环境搭建教程

最近DOTS终于发布了正式的版本, 今天我们来基于Unity 2023.1.6来搭建DOTS 1.0.16的开发环境与注意事项。 对啦!这里有个游戏开发交流小组里面聚集了一帮热爱学习游戏的零基础小白,也有一些正在从事游戏开发的技术大佬,欢迎你来交流学习。 1…

Liunx C运算符

一、运算符 &#xff08;一&#xff09;算数运算符 1、float和double不能进行取余操作。 &#xff08;二&#xff09;关系运算符 1、逻辑非 2、逻辑与 例子&#xff1a; if(&#xff08;a-1&#xff09;<b&&b) 如果为真则自增&#xff0c;为假不自增 3、逻辑或 …

leaflet 绘制显示半圆形,扇形示例 (134)

第134个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+leaflet中绘制显示半圆形,扇形 。这里引用了一个插件,非常方便的绘制扇形和半圆形等。 直接复制下面的 vue+leaflet源代码,操作2分钟即可运行实现效果 文章目录 示例效果配置方式示例源代码(共77行)安装插件相…

虚拟内存技术的基本概念(局部性原理,特征,实现)

1.传统存储管理方式的特征、缺点 很多暂时用不到的数据也会长期占用内存&#xff0c;导致内存利用率不高。 1.一次性: 作业必须一次性全部装入内存后才能开始运行。 这会造成两个问题: ①作业很大时&#xff0c;不能全部装入内存&#xff0c;导致大作业无法运行; ②当大量作…

node多版本管理器nvm

node多版本管理器nvm 1、为何要使用node版本管理器2、nvm安装步骤2-1、卸载系统中的node2-2、下载nvm2-3、安装 3、维护node版本3-1、安装指定版本node3-2、查看本机已安装的所有node版本3-3、切换本机node版本 1、为何要使用node版本管理器 在日常开发中&#xff0c;难免会遇…

apache log4j漏洞复现

log4j是开源的java存储日志的框架&#xff0c;一般都是大企业用&#xff0c;小企业自带的日志功能足够使用&#xff0c;Log4j2是默认支持解析ldap/rmi协议的&#xff0c;打印的日志中包括ldap/rmi协议都行。 具体介绍参考以下文章&#xff1a; log4j2---基于vulhub的log4j2漏…

Triple协议的隐式参数传递过程

前言 Dubbo 框架的 RPC 调用除了可以传递正常的接口参数外&#xff0c;还支持隐式参数传递。 隐式参数的传递依赖 RpcContext 对象&#xff0c;它持有一个 Map 对象&#xff0c;消费者往 Map 里写入数据&#xff0c;客户端在发起 RPC 调用前会构建 RpcInvocation&#xff0c;然…

linux中如何配置静态ip模式?

对于Linux系统来说&#xff0c;静态IP模式是一种常见的网络配置方式。相比动态IP模式&#xff0c;静态IP模式可以提供更加稳定的网络连接和更好的网络性能。本文将介绍在Linux中如何配置静态IP模式。 一、准备工作 在开始配置之前&#xff0c;需要先做好以下准备工作&#xff1…

Python爬虫基础之Selenium详解

目录 1. Selenium简介2. 为什么使用Selenium&#xff1f;3. Selenium的安装4. Selenium的使用5. Selenium的元素定位6. Selenium的交互7. Chrome handless参考文献 原文地址&#xff1a;https://program-park.top/2023/10/16/reptile_3/ 本文章中所有内容仅供学习交流使用&…