Simple-BEV的bilinear_sample 作为view_transformer的解析,核心是3D-2D关联点生成

文件路径models/view_transformers

父类 是class BiLinearSample(nn.Module)基于https://github.com/aharley/simple_bev。

函数解析

  • 函数bev_coord_to_feature_coord的功能

鸟瞰图3D坐标通过多相机(针孔/鱼眼)内外参投影图像特征平面,生成归一化采样坐标与有效掩码,实现多视角特征的空间对齐与融合筛选。
代码

def bev_coord_to_feature_coord(self, features, block_idxs, extrin_camera_to_ego, intrinsic, dist, ida, dist_type='KB'):...

首先:函数接收多个参数,包括特征、块索引、外参、内参、畸变参数等。
然后:处理不同相机类型(针孔和鱼眼)的索引
然后:生成3D点(通过gridcloud3d()函数实现,非均匀空间采样),将记忆坐标系中的点转换到自我车辆坐标系(get_bevgrid()matrix_mem_egocar)。并通过外参矩阵转换到相机坐标系。对于针孔相机,计算投影点,并进行畸变校正,然后将坐标转换到特征图的比例。对于鱼眼相机,处理类似,但使用了不同的畸变模型。
最后:合并两种相机的结果,并根据块索引屏蔽某些相机的特征。

这里面核心的是“对于针孔/鱼眼相机,计算投影点”。
首先,生成相机索引

pinhole_index = torch.cat([torch.arange(num_cams_pinhole) + self.num_cams * i for i in range(B)])
fisheye_index = torch.cat([torch.arange(num_cams_pinhole, num_cams_pinhole+ num_cams_fisheye) + self.num_cams * i for i in range(B)])

操作演示,num_cams_pinhole有1个,num_cams_fisheye有4个,num_cams 是5个。
在这里插入图片描述
然后用pinhole_index 和fisheye_index 索引取get_bevgrid()生成的3D点。
然后用内外参数将3D点转换到图像2D点

        # 投影3D点到2D图谱 (原始图像尺寸是 2160x3840)外参逆矩阵 = 外参矩阵.inverse()2D图像的点 = (内参矩阵 @ 外参逆矩阵)@ 3D点  # 尺寸是(BN,4,K)2D图像的点 = 2D图像的点.transpose(2, 1)  #  尺寸是(BN, k, 4)2D深度检测Mark = (2D图像的点[:, :, 2] > 0.0).bool() # 投影点的深度(z坐标)是否为正值,排除位于相机后方的点(不可见)# (X, Y, Z, 1)-> (X/Z, Y/Z, 1, 1)2D图像的点 = 2D图像的点[0:2]/2D图像的点[2]# 增加一个维度2D图像的点 = torch.cat(2D图像的点,ones)# 通过 ida_pinhole(图像坐标系转移矩阵)将归一化坐标映射到图像像素坐标。该矩阵通常包含焦距和主点偏移,完成从相机坐标系到图像平面的投影。2D图像的点 = 图像坐标系转移矩阵 @ 2D图像的点# 缩放2D图像的点 = 2D图像的点/下采样系数# 滤除无效区域的Mark2D的X轴检测Mark = (2D图像的点> -0.5).bool() & (2D图像的点< float(宽度 - 0.5)).bool()2D的Y轴检测Mark = (2D图像的点> -0.5).bool() & (2D图像的点< float(宽度 - 0.5)).bool()有效性Mark = (2D深度检测Mark& 2D的X轴检测Mark & 2D的Y轴检测Mark)

对于鱼眼相机

3D相机的点 = 外参逆矩阵 @ 3D点  # 
内参矩阵的仿射部分 = 内参[:2,:2]  # (焦距和轴间缩放),用于将归一化坐标映射到图像平面
内参矩阵中的主点坐标 = 内参[0:2, 2](图像中心偏移),用于投影时的平移校正。
计算径向距离 =+ Y² 的平方根
入射角  = torch.atan2(3D相机的点, 计算径向距离)
径向畸变系数 = self.polyval(畸变系数, 入射角, Kannala-Brandt模型) # 根据入射角 theta 计算径向畸变系数 rho
归一化的3D点 = 3D相机的点 × rho ÷ 计算径向距离
2D鱼眼点 = (内参矩阵的仿射部分 @ 归一化的3D点) + 内参矩阵中的主点坐标# 通过 ida_fisheye(图像坐标系转移矩阵)将归一化坐标映射到图像像素坐标。该矩阵通常包含焦距和主点偏移,完成从相机坐标系到图像平面的投影。
2D鱼眼点 = ida_fisheye @ 2D鱼眼点 # 从相机坐标系到图像平面的投影
2D鱼眼点 = 鱼眼点/下采样系数# 和针孔相机一样
有效性Mark = (2D深度检测Mark& 2D的X轴检测Mark & 2D的Y轴检测Mark)

最后返回的是:有效性Mark

补充:Kannala-Brandt模型介绍–点击这里
在这里插入图片描述在这里插入图片描述

  • 函数gridcloud3d()功能是:

函数通过非均匀采样生成三维网格点云,每个网格位置对应一个点,但不同区域的点密度可能不同。具体来说:

  • 函数forward_kestrel(),功能是:

该函数通过多相机特征采样与体素聚合,将鸟瞰图特征映射到3D空间并压缩生成统一表征。

    def forward_kestrel(self, input):# 获得Neck传过来的特征features = input["bev_neck_features"]# features 复制Z次并在通道维度拼接features = torch.cat([features] * Z, 1)# 特征尺寸调整features = features.reshape(self.num_cams * Z, -1, 60, 128)# 得到 unproject_image_to_mem() 计算的xyz_pix 和 有效性Markxyz_pix , valid_mask= ...# 将2D特征映,通过xyz_pix ,利用GridSampleFuction映射函数,映射到3D特征trans_feats = self.GridSampleFuction().apply(features, xyz_pix, "bilinear","zeros", None)# 有效性Mark 删除values = trans_feats* valid_mask# 特征被重塑values = values.reshape(B, self.num_cams, -1, X, Y)# 通道相加feat_mem = torch.sum(values, dim=1)# 通过 conv_norm 压缩成鸟瞰图特征feat_bev = self.bev_z_compressor(feat_mem)return feat_bev

首先是:输入的features被复制Z次并在通道维度拼接,使用reshape将特征调整为(num_cams * Z, -1, 60, 128),这里num_cams可能代表相机数量,Z是体素深度层数。
然后:GridSampleFuction应用双线性采样,将特征映射到新的坐标,生成trans_feats。
然后:特征被重塑为(B, num_cams, -1, X, Y)。feat_mem 是将多个相机视角的3D特征沿相机数量维度(dim=1)求和后的融合特征,目的是整合不同视角的信息,得到feat_mem。
最后: 最后通过bev_z_compressor压缩成鸟瞰图特征feat_bev。

  • 函数unproject_image_to_mem(),功能是:得到xyz_pix, valid_mask,用于后续的GridSampleFuction采用。
    def unproject_image_to_mem(self, features, block_idxs, extrinsic, intrinsic, dist_mat, dist_type, ida_mat, X, Y, Z):BN, C, H, W = features.shape# get proj point on the feature map and then normalize to [-1, 1]xyz_feat, valid_mask = self.bev_coord_to_feature_coord(features, block_idxs, extrinsic, intrinsic, dist_mat, ida_mat, dist_type)x, y = xyz_feat[:, :, 0], xyz_feat[:, :, 1]x_norm, y_norm = self.normalize_grid2d(x, y, W, H)xyz_pix = torch.stack([x_norm, y_norm], axis=1)#import pdb; pdb.set_trace()xyz_pix = rearrange(xyz_pix, "n d (x y z) -> n (z d) x y", x=X, y=Y, z=Z)valid_mask = rearrange(valid_mask, "n (x y z) -> n z x y", x=X, y=Y, z=Z)return xyz_pix, valid_mask

首先通过 bev_coord_to_feature_coord()得到 2D点和有效性Mark
按照前述分析 2D 尺寸应该是类似(bn, k, 2),这里bn是批处理大小,k是栅格的数量(通过gridcloud3d()获得),2是xy坐标。
对2D点的x和y进行归一化到[-1,1],分别除以宽和高,组成新的 2D点。
最后,将三维空间中的点按高度(Z轴)分层,每层对应一个二维网格(X-Y平面)

问文心一言的问题:LSS(Lift-Splat-Shoot)和BEVDepth在3D点处理上有以下核心区别

回答:

LSS(Lift-Splat-Shoot)和BEVDepth在3D点处理上有以下核心区别:

LSS的3D点

  • 全体视锥体栅格:LSS将图像特征提升到整个相机视锥体对应的3D体素网格中,覆盖所有可能的深度层(如0-100米,按固定间隔分层)。
  • 概率分布:每个像素的特征会被分配到多个深度层,形成概率分布(通过深度预测或几何计算),而非单一深度值。
  • 目的:构建全局3D场景表示,适用于复杂场景理解(如多物体遮挡、非地面目标检测)。

BEVDepth的栅格

  • BEV平面聚焦:BEVDepth通常将特征投影到鸟瞰图(BEV)平面的栅格中(如地面区域),每个栅格对应一个位置,深度预测用于确定该位置是否存在有效特征。
  • 单一深度假设:每个栅格可能仅保留最可能的深度值(如通过深度网络预测),或基于几何投影选择有效层。
  • 目的:高效生成BEV空间特征,尤其适合自动驾驶中地面目标检测(如车辆、行人),减少计算冗余。

栅格点数量减少

  • LSS:在全体视锥体空间生成三维体素网格(如 100 层深度 × X×Y),覆盖整个相机视野的 3D 空间。
  • BEVDepth:将特征投影到二维 BEV 平面栅格(如地面区域),仅保留与地面感知相关的位置,深度维度被压缩为单层(通过深度预测或几何投影筛选)。
  • 结论:BEVDepth 的栅格点数量显著减少(从三维到二维),降低了显存占用和计算复杂度。

总结:

  • LSS的3D点是全体视锥体的分层栅格,强调3D空间的完整建模。
  • BEVDepth的栅格是BEV平面的深度预测结果,侧重地面区域的紧凑表示。
  • 两者均可结合使用(如BEVDepth可能用LSS作为 backbone),但核心差异在于对3D空间的覆盖范围和深度建模方式。

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

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

相关文章

HTTP长连接与短连接的前世今生

HTTP长连接与短连接的前世今生 大家好&#xff01;作为一名在互联网摸爬滚打多年的开发者&#xff0c;今天想跟大家聊聊HTTP中的长连接和短连接这个话题。 记得我刚入行时&#xff0c;对这些概念一头雾水&#xff0c;希望这篇文章能帮助新入行的朋友少走些弯路。 什么是HTTP…

在Mac M1/M2芯片上完美安装DeepCTR库:避坑指南与实战验证

让推荐算法在Apple Silicon上全速运行 概述 作为推荐系统领域的最经常用的明星库&#xff0c;DeepCTR集成了CTR预估、多任务学习等前沿模型实现。但在Apple Silicon架构的Mac设备上&#xff0c;安装过程常因ARM架构适配、依赖库版本冲突等问题受阻。本文通过20次环境搭建实测…

c#知识点补充4

1.发布者订阅模式 发布者 订阅者 俩者直接的关联使用

3. 轴指令(omron 机器自动化控制器)——>MC_SetOverride

机器自动化控制器——第三章 轴指令 12 MC_SetOverride变量▶输入变量▶输出变量▶输入输出变量 功能说明▶时序图▶重启运动指令▶多重启动运动指令▶异常 MC_SetOverride 变更轴的目标速度。 指令名称FB/FUN图形表现ST表现MC_SetOverride超调值设定FBMC_SetOverride_instan…

Cocos Creator Shader入门实战(五):材质的了解、使用和动态构建

引擎&#xff1a;3.8.5 您好&#xff0c;我是鹤九日&#xff01; 回顾 前面的几篇文章&#xff0c;讲述的主要是Cocos引擎对Shader使用的一些固定规则&#xff0c;这里汇总下&#xff1a; 一、Shader实现基础是OpenGL ES可编程渲染管线&#xff0c;开发者只需关注顶点着色器和…

体育直播模板nba英超直播欧洲杯直播模板手机自适应

源码名称&#xff1a;体育直播模板nba英超直播欧洲杯直播模板手机自适应帝国cms 7.5模板 开发环境&#xff1a;帝国cms7.5 空间支持&#xff1a;phpmysql 带软件采集&#xff0c;可以挂着自动采集发布&#xff0c;无需人工操作&#xff01; 模板特点&#xff1a; 程序伪静态…

python基于spark的心脏病患分类及可视化(源码+lw+部署文档+讲解),源码可白嫖!

摘要 时代在飞速进步&#xff0c;每个行业都在努力发展现在先进技术&#xff0c;通过这些先进的技术来提高自己的水平和优势&#xff0c;汽车数据分析平台当然不能排除在外。本次我所开发的心脏病患分类及可视化系统是在实际应用和软件工程的开发原理之上&#xff0c;运用Pyth…

SAP 附件增删改查与文件服务器交互应用

【需求背景】 非SAP标准附件应用&#xff0c;自定义一套&#xff0c;跟公司内部文档服务器交互&#xff0c;支持各个应用场景的附件增删改查等。 每个附件在文件服务器上都有一个文件唯一ID作为关键字。 应用分两块&#xff1a;SAP GUI端&#xff0c;跟WDA Portal端应用 GU…

Linux__之__基于UDP的Socket编程网络通信

前言 本篇博客旨在使用Linux系统接口进行网络通信, 帮助我们更好的熟悉使用socket套接字网络通信, 学会了socket网络通信, 就能发现所谓网络, 不过都是套路而已, 话不多说, 让我们直接进入代码编写部分. 1. 事先准备 今天我们先来模拟实现一个echo demo, 也就是客户端向服务…

【Agent】Dify Docker 安装问题 INTERNAL SERVER ERROR

总结&#xff1a;建议大家选择稳定版本的分支&#xff0c;直接拉取 master 分支&#xff0c;可能出现一下后面更新代码导致缺失一些环境内容。 启动报错 一直停留在 INSTALL 界面 我是通过 Docker 进行安装的&#xff0c;由于项目开发者不严谨导致&#xff0c;遇到一个奇怪的…

unity开发效率提升笔记

本文将记录提升Unity开发效率的若干细节&#xff0c;持续更新 一.VSCode文件标签多行显示 1.File->Preference->Settings (快捷键Ctrl 逗号) 2.搜索workbench.editor.wrapTabs 3.勾选上这个单选开关 若依然不是多行 4.搜索workbench.editor.tabSizing,选择fi…

python每日十题(6)

列表操作函数有&#xff08;假设列表名为ls&#xff09;&#xff1a; len(ls)&#xff1a;返回列表ls的元素个数&#xff08;长度&#xff09;。min(ls)&#xff1a;返回列表ls的最小元素。max(ls)&#xff1a;返回列表ls的最大元素。list(x)&#xff1a;将x转变为列表类型。使…

【Java】TCP网络编程:从可靠传输到Socket实战

活动发起人小虚竹 想对你说&#xff1a; 这是一个以写作博客为目的的创作活动&#xff0c;旨在鼓励大学生博主们挖掘自己的创作潜能&#xff0c;展现自己的写作才华。如果你是一位热爱写作的、想要展现自己创作才华的小伙伴&#xff0c;那么&#xff0c;快来参加吧&#xff01…

使用HAI来打通DeepSeek的任督二脉

一、什么是HAI HAI是一款专注于AI与科学计算领域的云服务产品&#xff0c;旨在为开发者、企业及科研人员提供高效、易用的算力支持与全栈解决方案。主要使用场景为&#xff1a; AI作画&#xff0c;AI对话/写作、AI开发/测试。 二、开通HAI 选择CPU算力 16核32GB&#xff0c;这…

mysql——第二课

学生表 CREATE TABLE student (id int(11) NOT NULL AUTO_INCREMENT,name varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,sex varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,age int(11) DEFAULT NULL,c_id int(10) DEFAULT NULL,PRIMARY KEY (id),KEY c_id (c_id),CONSTR…

单播、广播、组播和任播

文章目录 一、单播二、广播三、组播四、任播代码示例&#xff1a; 五、各种播的比较 一、单播 单播&#xff08;Unicast&#xff09;是一种网络通信方式&#xff0c;它指的是在网络中从一个源节点到一个单一目标节点对的传输模式。单播传输时&#xff0c;数据包从发送端直接发…

1-1 MATLAB深度极限学习机

本博客来源于CSDN机器鱼&#xff0c;未同意任何人转载。 更多内容&#xff0c;欢迎点击本专栏目录&#xff0c;查看更多内容。 参考[1]魏洁.深度极限学习机的研究与应用[D].太原理工大学[2023-10-14].DOI:CNKI:CDMD:2.1016.714596. 目录 0.引言 1.ELM-AE实现 2.DE…

头歌 数据采集概述答案

问题1&#xff1a;以下哪个不是Scrapy体系架构的组成部分&#xff1f; 正确答案&#xff1a;B. 支持者(Support) 解释&#xff1a;Scrapy的主要组成部分包括&#xff1a; 爬虫(Spiders)&#xff1a;定义如何爬取网站和提取数据 引擎(Engine)&#xff1a;负责控制数据流在系统中…

【uniapp】记录tabBar不显示踩坑记录

由于很久没有使用uniapp了&#xff0c;官方文档看着又杂乱&#xff0c;底部tab导航栏一直没显示&#xff0c;苦思许久&#xff0c;没有发现原因&#xff0c;最后网上搜到帖子&#xff0c;list里的第一个数据&#xff0c;pages 的第一个 path 必须与 tabBar 的第一个 pagePath 相…

JVM 知识点梳理

JDK 、JRE、JVM JDK&#xff08; Java Development Kit &#xff09; Java开发工具包 JRE 开发命令工具&#xff08;运行java.exe、编译javac.exe、javaw.exe&#xff09; JRE&#xff08; Java Runtime Environment &#xff09;Java运行环境 JVM Java核心类库&#xff08;l…