【论文阅读】PETRv2: A Unified Framework for 3D Perception from Multi-Camera Images

在这里插入图片描述

Q: 论文如何解决这个问题?

A: 论文通过提出PETRv2框架来解决多相机图像的3D感知问题,具体方法包括以下几个关键点:

时间建模(Temporal Modeling):

  • 通过3D坐标对齐(3D Coordinates Alignment)实现不同帧之间的时间对齐,将上一帧的3D坐标转换到当前帧的坐标系中,以增强目标定位和速度估计。
    多任务学习(Multi-task Learning):

引入任务特定的查询(task-specific queries),

  • 例如车道检测的3D锚定车道和BEV分割的seg查询,这些查询在不同的空间中初始化,并与transformer解码器中的多视图图像特征进行交互。
    特征引导的位置编码器(Feature-guided Position Encoder, FPE):

改进原有的3D位置嵌入(3D PE)

  • 通过FPE使3D PE依赖于输入图像数据,利用2D图像特征提供的信息(如深度)来指导查询学习。
    鲁棒性分析(Robustness Analysis):

对PETRv2进行详细的鲁棒性分析

  • 考虑了包括相机外参噪声、相机缺失和时间延迟等多种噪声情况,以评估和提高系统在现实世界条件下的性能和可靠性。

结构图

在这里插入图片描述

  1. 2D backbone(例如 ResNet-50),3D 坐标是从相机截锥空间生成的,考虑到自我运动,首先通过姿态变换将前一帧t−1的三维坐标转化为当前帧t的坐标系。
  2. 将相邻帧的2D特征和3D坐标分别连接在一起,输入到特征引导位置编码器(FPE)。之后,使用 FPE 为变压器解码器生成键和值组件.
  3. 特定于任务的查询,包括从不同空间初始化的检测查询(det 查询)和分割查询(seg 查询)(lane 查询)被馈送到变压器解码器并与多视图图像特征交互。
  4. 更新后的查询被输入到特定于任务的头部以进行最终预测

Q: 论文如何解决这个问题?

A: 论文通过提出PETRv2框架来解决多相机图像的3D感知问题,具体方法包括以下几个关键点:

时间建模(Temporal Modeling):

通过3D坐标对齐(3D Coordinates Alignment)实现不同帧之间的时间对齐,将上一帧的3D坐标转换到当前帧的坐标系中,以增强目标定位和速度估计。

在这里插入图片描述

P 3 d t = T t − 1 t P 3 d t − 1 \bm{P^t_{3d}} = \bm{T^t_{t-1}}\bm{P^{t-1}_{3d}} P3dt=Tt1tP3dt1

多任务学习(Multi-task Learning):

引入任务特定的查询(task-specific queries),例如车道检测的3D锚定车道和BEV分割的seg查询,这些查询在不同的空间中初始化,并与transformer解码器中的多视图图像特征进行交互。

3D object detection
在这里插入图片描述
Det Queries: 3D Anchor Points (~1500)+ MLP

Segmentation
在这里插入图片描述
Seg Queries:

  • 我们引入了用于 BEV 分割的 seg 查询,每个 seg 查询对应于一个特定的Patch(例如,BEV map ( 25 × 25 像素)。
  • seg 查询在 BEV 空间中使用固定的锚点进行初始化,类似于 PETR 中检测查询 (det 查询) 的生成。然后使用具有两个线性层的简单 MLP 将这些锚点投影到 seg Queries。
    在这里插入图片描述

3D Lane Detection

将每根车道线作为一个Query(Anchor)表达成平行于Y轴的n个3D点

l a n e i = ( x 1 , y 1 , z 1 , ) , ( x 2 , y 2 , z 2 ) , ⋅ ⋅ ⋅ , ( x n , y n , z n ) \bm{lane^i= {(x_1, y_1, z_1, ), (x_2, y_2, z_2), · · · , (x_n, y_n, z_n)}} lanei=(x1,y1,z1,),(x2,y2,z2),⋅⋅⋅,(xn,yn,zn)

在 Y 轴上均匀采样K条车道线,一共K个Quries(~100个)
对于每个Quries,预测车道线的分类以及x/z轴偏移 ( Δ x , Δ y ) (\Delta x,\Delta y) Δx,Δy

特征引导的位置编码器(Feature-guided Position Encoder, FPE):

改进原有的3D位置嵌入(3D PE),通过FPE使3D PE依赖于输入图像数据,利用2D图像特征提供的信息(如深度)来指导查询学习。
在这里插入图片描述

P E i 3 d ( t ) = ξ ( F i ( t ) ) ∗ ψ ( P l ( t ) i ( t ) ) \bm{{PE}^{3d}_i (t)} = \xi(\bm{F_i(t)}) * \psi(\bm{P_{l(t)}^i (t)}) PEi3d(t)=ξ(Fi(t))ψ(Pl(t)i(t))
ξ : MLP + sigmoid function
ψ(.):一个简单的多层感知(MLP)
key: 2D feature + 3D PE
value: 2D Feature

def position_embeding(self, img_feats, img_metas, masks=None):eps = 1e-5  # 用于避免除零错误的极小值# 获取填充后的图片高度和宽度 (pad_h, pad_w),以及其它相关信息pad_h, pad_w, _ = img_metas[0]['pad_shape'][0]# 获取特征图的形状信息:B(批次大小),N(图像数量),C(通道数),H(高度),W(宽度)B, N, C, H, W = img_feats[self.position_level].shape# 计算每个像素点在填充后图像中的实际高度坐标和宽度坐标coords_h = torch.arange(H, device=img_feats[0].device).float() * pad_h / Hcoords_w = torch.arange(W, device=img_feats[0].device).float() * pad_w / Wif self.LID:# 如果使用 LID 方法计算深度坐标index = torch.arange(start=0, end=self.depth_num, step=1, device=img_feats[0].device).float()index_1 = index + 1bin_size = (self.position_range[3] - self.depth_start) / (self.depth_num * (1 + self.depth_num))coords_d = self.depth_start + bin_size * index * index_1else:# 否则,直接计算深度坐标index = torch.arange(start=0, end=self.depth_num, step=1, device=img_feats[0].device).float()bin_size = (self.position_range[3] - self.depth_start) / self.depth_numcoords_d = self.depth_start + bin_size * index# 获取深度坐标的数量 DD = coords_d.shape[0]# 生成坐标网格,并将其维度排列为 W, H, D, 3coords = torch.stack(torch.meshgrid([coords_w, coords_h, coords_d])).permute(1, 2, 3, 0)# 添加第四维坐标(均为1),形成 W, H, D, 4coords = torch.cat((coords, torch.ones_like(coords[..., :1])), -1)# 计算 x 和 y 坐标的变换,确保 z 坐标不为零coords[..., :2] = coords[..., :2] * torch.maximum(coords[..., 2:3], torch.ones_like(coords[..., 2:3])*eps)# 生成 img2lidar 矩阵列表img2lidars = []for img_meta in img_metas:img2lidar = []for i in range(len(img_meta['lidar2img'])):# 计算每个 lidar2img 矩阵的逆矩阵img2lidar.append(np.linalg.inv(img_meta['lidar2img'][i]))img2lidars.append(np.asarray(img2lidar))# 将 img2lidar 列表转换为 numpy 数组img2lidars = np.asarray(img2lidars)# 将 numpy 数组转换为 tensor,形状为 (B, N, 4, 4)img2lidars = coords.new_tensor(img2lidars)# 调整 coords 和 img2lidars 的维度,并进行重复操作coords = coords.view(1, 1, W, H, D, 4, 1).repeat(B, N, 1, 1, 1, 1, 1)img2lidars = img2lidars.view(B, N, 1, 1, 1, 4, 4).repeat(1, 1, W, H, D, 1, 1)# 计算3D坐标,将坐标从齐次坐标变换到3D坐标coords3d = torch.matmul(img2lidars, coords).squeeze(-1)[..., :3]# 对3D坐标进行归一化coords3d[..., 0:1] = (coords3d[..., 0:1] - self.position_range[0]) / (self.position_range[3] - self.position_range[0])coords3d[..., 1:2] = (coords3d[..., 1:2] - self.position_range[1]) / (self.position_range[4] - self.position_range[1])coords3d[..., 2:3] = (coords3d[..., 2:3] - self.position_range[2]) / (self.position_range[5] - self.position_range[2])# 创建掩码,检查是否有坐标超出范围coords_mask = (coords3d > 1.0) | (coords3d < 0.0)# 计算掩码,若超过一半的深度坐标超出范围,则设置掩码coords_mask = coords_mask.flatten(-2).sum(-1) > (D * 0.5)# 合并输入掩码和计算的坐标掩码coords_mask = masks | coords_mask.permute(0, 1, 3, 2)# 调整 coords3d 的维度coords3d = coords3d.permute(0, 1, 4, 5, 3, 2).contiguous().view(B*N, -1, H, W)# 计算逆sigmoidcoords3d = inverse_sigmoid(coords3d)# 计算位置嵌入coords_position_embeding = self.position_encoder(coords3d)# 返回位置嵌入和掩码return coords_position_embeding.view(B, N, self.embed_dims, H, W), coords_mask

鲁棒性分析(Robustness Analysis):

对PETRv2进行详细的鲁棒性分析,考虑了包括相机外参噪声、相机缺失和时间延迟等多种噪声情况,以评估和提高系统在现实世界条件下的性能和可靠性。
在这里插入图片描述
外参误差:外参误差在现实中很常见,例如汽车碰撞引起的相机抖动或环境力的相机偏移
Rmax = M表示三个轴的最大角度为M。
在这里插入图片描述

相机丢失:当一台相机发生故障或被遮挡时,就会发生相机图像未命中。
在这里插入图片描述

相机时间延迟:由于相机曝光时间,相机时间延迟也是一个挑战,尤其是在夜间。

T ≈ 0.083s
在这里插入图片描述
3D object detection

在这里插入图片描述

BEV segmentation

在这里插入图片描述
3D lane detection

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ASP.Net Core设置接口根路径的方法

使用asp.net core开发微服务项目&#xff0c;需要给每个服务设置不同的根路径&#xff0c;这样既能使用网关转发请求&#xff0c;又方便对单个服务进行测试&#xff0c;保证请求路径的统一。 设置方法需要使用中间件&#xff0c;在Program.cs添加如下代码 app.UsePathBase(&qu…

通过ZRender画一个大屏的顶部样式标题

介绍&#xff1a;通过ZRender画一个大屏项目的顶部样式&#xff0c;在其中放入大屏的标题。ZRender 是二维绘图引擎&#xff0c;它提供 Canvas、SVG、VML 等多种渲染方式。ZRender 也是 ECharts 的渲染器。 一、下载 npm install zrender终端输入以上命令下载包即可。 二、导…

记忆化搜索——1

目录 1.斐波那契数 2.不同路径 3.最长递增子序列 4.猜数字大小2 5.矩阵中的最长递增路径 1.斐波那契数 该题规律很明显&#xff0c;就直接放记忆化搜索的版本了 class Solution { public:int dfs(int n){if(n0||n1)//递归出口{return n;}if(f[n-1]-1)//检查是否已经记忆过…

JVM 加载阶段 Class对象加载位置是在 堆中还是方法区?

在JVM&#xff08;Java虚拟机&#xff09;的类加载过程中&#xff0c;Class对象的加载位置涉及到堆&#xff08;Heap&#xff09;和方法区&#xff08;Method Area&#xff09;两个关键区域。具体来说&#xff0c;类的加载阶段涉及到将类的.class文件中的二进制数据读入到内存中…

黑丝或者白丝,都可以用LoRA(Stable Diffusion进阶篇:ComfyUI 附加网络)

前言 在学习WebUI的那些基础知识点的时候&#xff0c;有一个东西是每一个初学者都绕不开的大山-附加网络。 这个东西对于每一个接触Stable Diffusion的小伙伴来说就像是小学门口小卖部卖的辣条、初中课本上的涂鸦、高中数学卷解不开的最后一道大题。 学习过WebUI里Stable Di…

揭秘亚马逊新手快速成长背后的秘密:从入门到精通

在亚马逊这个充满机遇与挑战的市场平台上&#xff0c;作为一名深耕多年的卖家&#xff0c;我积累了宝贵的经验和见解。随着市场环境的不断变化&#xff0c;我意识到&#xff0c;无论是新加入的创业者还是经验丰富的老手&#xff0c;都需要不断学习和适应&#xff0c;以在这个平…

游戏行业报告(一)| 中国占全球头部上市游戏企业34%,“智能NPC”竞争方向较受关注

近日&#xff0c;伽马数据发布了《2024中国上市/非上市游戏企业竞争力报告》&#xff0c;本篇文章仅采用《2024中国上市/非上市游戏企业竞争力报告》的部分数据。由于文章太长&#xff0c;所以分了下集&#xff0c;大家可以收藏关注~ 企业全球资本市场竞争现状 全球TOP50上市游…

Motionface ai工具有哪些?

Motionface Android/PC 用一张静态含有人脸相片来生成一个能说会唱的虚拟主播。使用简单便捷&#xff0c;极致的流畅度体验超乎您的想象。 免费下载 Respeak PC电脑软件 任意视频一键生成虚拟主播&#xff0c;匹配音频嘴型同步&#xff0c;保留原视频人物神态和动作&#xff0c…

什么是柔性生产?

柔性生产&#xff0c;是一种能够迅速调整生产流程、产品种类及产量&#xff0c;以低成本、高效率响应市场多样化需求的生产方式。它不仅仅是对生产线硬件的升级&#xff0c;更是对生产组织、管理模式及信息技术的全面革新。柔性生产的核心在于“灵活”二字&#xff0c;即企业能…

JVM(面试用)

目录 一、JVM运行时数据区 二、JVM类加载 类加载过程 1、加载&#xff08;loading&#xff09; 2、验证&#xff08;Verification&#xff09; 3、准备&#xff08;Perparation&#xff09; 4、解析&#xff08;Resolution&#xff09; 5、初始化&#xff08;Initializ…

秒懂C++之deque及反向迭代器

目录 前言 一.deque的常用接口 二.deque的原理 2.1 vector与list的优缺点 2.2 deque的原理 三.反向迭代器 四.全部代码 前言 秒懂C之List-CSDN博客 秒懂C之vector&#xff08;下&#xff09;-CSDN博客 本文后面关于反向迭代器的操作会涉及到前面的文章~ 一.deque的常用接…

uni-app封装组件实现下方滑动弹出模态框

子组件 <template><div class"bottom-modal" :class"{show: showModal}"><div class"modal-content" :class"{show: showModal}"><!-- 内容区域 --><slot></slot></div></div></…

【JAVA多线程】AQS,JAVA并发包的核心

目录 1.概述 1.1.什么是AQS 1.2.AQS和BlockQueue的区别 1.3.AQS的结构 2.源码分析 2.1.CLH队列 2.2.模板方法的实现 2.2.1.独占模式 1.获取资源 2.释放资源 2.2.2.共享模式 1.概述 1.1.什么是AQS AQS非常非常重要&#xff0c;可以说是JAVA并发包&#xff08;java.…

案例开发-日程管理2第一期(超详细教程、配备图文和源代码注释,没学过也能看懂)

文章目录 一、 项目前期准备1.数据库准备2.导入依赖3.pojo包处理4.dao包处理5.service包处理6.controller包处理7.加密工具类的使用8.页面文件的导入 总结 一、 项目前期准备 1.数据库准备 创建schedule_system数据库并执行如下语句 SET NAMES utf8mb4; SET FOREIGN_KEY_CHE…

WPF学习(4)- VirtualizingStackPanel (虚拟化元素)+Canvas控件(绝对布局)

VirtualizingStackPanel虚拟化元素 VirtualizingStackPanel 类&#xff08;虚拟化元素&#xff09;和StackPanel 类在用法上几乎差不多。其作用是在水平或垂直的一行中排列并显示内容。它继承于一个叫VirtualizingPanel的抽象类&#xff0c;而这个VirtualizingPanel抽象类继承…

大数据-68 Kafka 高级特性 物理存储 日志存储概述

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

Java之SpringBoot入门(含Spring Mvc)

1.Spring Boot Helper的安装 首先我们要装好Spring Boot Helper 但是由于直接在IDEA中下的是收费版&#xff0c;在学习阶段我们可以去官网下载一些免费版使用 Spring Boot Helper - IntelliJ IDEs Plugin | Marketplace&#xff08;点击即可进入官网&#xff09; 然后在IDEA…

【practise】删除有序数组中的重复项

关于博主&#xff1a; 今天分享一道简单的关于“双指针”算法的题目。算是双指针中非常基础的题目&#xff0c;有兴趣可以借鉴一波~ 目录 1.题目介绍2.题解思路&#xff1a;双指针法3.代码示例 1.题目介绍 题目链接&#xff1a;LINK 本题要求是&#xff1a;对给定的有序数组…

回溯分割+子集篇--代码随想录算法训练营第二十二天| 131.分割回文串,93.复原IP地址,78.子集,90.子集II

131.分割回文串 题目链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 讲解视频&#xff1a;131.分割回文串 题目描述&#xff1a; 给你一个字符串 s&#xff0c;请你将 s 分割成一些子串&#xff0c;使每个子串都是回文串 。返回 s 所有可能的分割方案。 示例 …

sql二次注入实战--2018年网顶杯

网址&#xff1a;BUUCTF在线评测 (buuoj.cn) 当我们进入后显示这个页面&#xff1a; 当我们第一次点击发帖的时候就会跳转到登陆页面&#xff0c;上面有提示&#xff0c;告诉我们账号为zhangwei,密码为zhangwei***&#xff1a; 这里我们可以使用bp抓包工具来进行暴力破解密码&…