Drivestduio 代码笔记与理解

Rigid Node: 表示 car或者trucks
Deformable Node : 表示一些 分布之外的 non-rigid 的运动物体, 比如远处的行人等和Cyclist。

load_objects 会读取每一个 dynamic objects 的 'bounding box’的信息,具体如下:
frame_instances 记录了每一帧都有哪些 instance, 以及对应 每一帧 其 位姿信息等;
instances_info 包含每一帧 对于哪些 instance 是可见的。

1. 读取 Bounding Box 的基本信息

逻辑是先遍历场景的 instance, 然后 再每一个 instance 的信息。
## 存放每一帧 的instance 的pose
instances_pose = np.zeros((num_full_frames, num_instances, 4, 4))for k, v in instances_info.items():instances_model_types[int(k)] = OBJECT_CLASS_NODE_MAPPING[v["class_name"]]for frame_idx, obj_to_world, box_size in zip(v["frame_annotations"]["frame_idx"], v["frame_annotations"]["obj_to_world"], v["frame_annotations"]["box_size"]):# the first ego pose as the origin of the world coordinate system.obj_to_world = np.array(obj_to_world).reshape(4, 4)obj_to_world = np.linalg.inv(ego_to_world_start) @ obj_to_worldinstances_pose[frame_idx, int(k)] = np.array(obj_to_world)instances_size[frame_idx, int(k)] = np.array(box_size)

根据 per_frame_instance_mask来得到 每一帧对于哪些instance 是可见的。

  per_frame_instance_mask = np.zeros((num_full_frames, num_instances))for frame_idx, valid_instances in frame_instances.items():per_frame_instance_mask[int(frame_idx), valid_instances] = 1

2. 使用Bounding Box 的信息初始化高斯

这里需要介绍一个 dynamic vehicle 非常重要的坐标系,物体坐标系(Object系),其通常位于汽车的车辆中心。所以任何一帧的 Lidar 通过 w2o 矩阵可以将Lidar 点转换到 canonical space, 完成对于多帧 Lidar 的聚集

将 Lidar 点 (世界坐标系下面的) 通过 转化矩阵 w2o 转换到 Object 坐标系下面 , 然后 根据 Bounding Box 的 Size 去保留 在 BBX 内部的点云,准备进行初始化。

 o2w = self.pixel_source.instances_pose[fi, ins_id]o_size = self.pixel_source.instances_size[ins_id]# convert the lidar points to the instance's coordinate systemw2o = torch.inverse(o2w)o_pts = transform_points(lidar_pts, w2o)# 将BBX 之外的点通过 Mask 滤除,这一步是在局部 Object 坐标系下面进行的mask = ((o_pts[:, 0] > -o_size[0] / 2)& (o_pts[:, 0] < o_size[0] / 2)& (o_pts[:, 1] > -o_size[1] / 2)& (o_pts[:, 1] < o_size[1] / 2)& (o_pts[:, 2] > -o_size[2] / 2)& (o_pts[:, 2] < o_size[2] / 2))valid_pts = o_pts[mask]valid_colors = self.lidar_source.colors[lidar_dict["lidar_mask"]][mask]
通过 比较 在 instances_pose 的pose (O2W系) 移动,仅仅对于 动态的 instance 进行保留 。

因为车辆的移动其实可以看成是 O2W坐标系的移动。 相当于车辆是静止的,但是环境是运动的

if only_moving:# consider only the instances with non-zero flowslogger.info(f"Filtering out the instances with non-moving trajectories")new_instance_dict = {}for k, v in instance_dict.items():if v["num_pts"] > 0:  ## 仅仅考虑有点的 instance# flows = v["flows"]# if flows.norm(dim=-1).mean() > moving_thres:#     v.pop("flows")#     new_instance_dict[k] = v#     logger.info(f"Instance {k} has {v['num_pts']} lidar sample points")frame_info = self.pixel_source.per_frame_instance_mask[:, k]instances_pose = self.pixel_source.instances_pose[:, k]instances_trans = instances_pose[:, :3, 3]valid_trans = instances_trans[frame_info]traj_length = valid_trans[1:] - valid_trans[:-1]traj_length = torch.norm(traj_length, dim=-1).sum()if traj_length > traj_length_thres:new_instance_dict[k] = vlogger.info(f"Instance {k} has {v['num_pts']} lidar sample points")instance_dict = new_instance_dict

将所有帧的 Lidar Aggregated 到 Canonical Space 下面,如图所示:
在这里插入图片描述

静态高斯的初始化

静态的 高斯初始化 = Lidar_samples + 半球内的随机采样点。 随机采样点是 PVG 这篇文章所介绍的, 在 球内部 和 球外面进行均匀采样。

Rigid 高斯的初始化

Canonical Space 累计的 点云进行 高斯的各项属性的初始化, 读取 点云的 坐标和颜色,然后进行初始化。 并记录了 每个bbx 的大小以及 每个instance 在每一帧的可见性,分别用 self.instances_size self.instances_fv表示。

## (num_instances, 3) BBX 的大小self.instances_size = torch.stack(instances_size).to(self.device) # # (num_frame, num_instances) instance 在每一帧的可见性
self.instances_fv = torch.cat(instances_fv, dim=1).to(self.device) 

值得注意的是, Drivestudio 将每一帧的每一个 instance 的 BBX 的 的 pose 也作为参数去考虑优化:

 # (num_frame, num_instances, 4)  四元数self.instances_quats = Parameter(self.quat_act(instances_quats))# (num_frame, num_instances, 3) 平移
self.instances_trans = Parameter(instances_trans)             

高斯参数的优化器设置:

所有的 Rigid Nodes 会把放进一个 优化字典当中,然后一起优化,并不是每个 instance 去独立的优化

Rigid 的每一个GS 都是像原始的 3DGS 一样,配置 每一个属性的 学习率去进行优化的。

groups.append({'params': params,'name': params_name,'lr': optim_cfg.lr,'eps': optim_cfg.eps,'weight_decay': optim_cfg.weight_decay})

groups 构建好之后,全部一起当作字典丢进 Adam 优化器去进行优化

self.optimizer = torch.optim.Adam(groups, lr=0.0, eps=1e-15)

Sky Model

Drivestudio 使用场景的 Environment map 来对于 天空的颜色进行建模. Sky 被建模成一个 长方体 cube, 然后使用基于光线方向(Opengl系)来在 environment cube 上进行纹理查询。这个 environment map 虽然没有任何网络,但是其本身的参数也是需要被优化的。 对应的 Code 如下

class EnvLight(torch.nn.Module):def __init__(self,class_name: str,resolution=1024,device: torch.device = torch.device("cuda"),**kwargs):super().__init__()self.class_prefix = class_name + "#"self.device = deviceself.to_opengl = torch.tensor([[1, 0, 0], [0, 0, 1], [0, -1, 0]], dtype=torch.float32, device="cuda")## 需要被优化的 environment mapself.base = torch.nn.Parameter(0.5 * torch.ones(6, resolution, resolution, 3, requires_grad=True),)def forward(self, image_infos):l = image_infos["viewdirs"]l = (l.reshape(-1, 3) @ self.to_opengl.T).reshape(*l.shape)l = l.contiguous()prefix = l.shape[:-1]if len(prefix) != 3:  # reshape to [B, H, W, -1]l = l.reshape(1, 1, -1, l.shape[-1])light = dr.texture(self.base[None, ...], l, filter_mode='linear', boundary_mode='cube')light = light.view(*prefix, -1)return light

开始训练:

针对每一个 Node 提取出场景的N 个动态对象高斯。 如果是 Rigid 物体的高斯,前面的代码是采用 Object系存储的,需要转换到 World系,然后提取出来。

平移变化来分析:

首先我们有 frame_id 标记 我们训练的是哪一帧,取出这一帧的所有 instance 对应的 旋转和 rot_cur_frame 平移trans_cur_frame . 假设我们有M个动态点,将这M个动态点 和 应用在M个旋转和平移向量上,同时得到了这个所有动态类别在场景frame_id对应的位置和坐标。

def transform_means(self, means: torch.Tensor) -> torch.Tensor:"""transform the means of instances to world spaceaccording to the pose at the current frame"""assert means.shape[0] == self.point_ids.shape[0], \"its a bug here, we need to pass the mask for points_ids"quats_cur_frame = self.instances_quats[self.cur_frame] # (num_instances, 4)rot_cur_frame = quat_to_rotmat(self.quat_act(quats_cur_frame))                                                          # (num_instances, 3, 3)## 求出每个点的旋转rot_per_pts = rot_cur_frame[self.point_ids[..., 0]]        # (num_points, 3, 3)trans_cur_frame = self.instances_trans[self.cur_frame] # (num_instances, 3)## 求出每个点的平移trans_per_pts = trans_cur_frame[self.point_ids[..., 0]]# transform the means to world spacemeans = torch.bmm(rot_per_pts, means.unsqueeze(-1)).squeeze(-1) + trans_per_ptsreturn means

之后使用 gsplat作为渲染的框架,执行渲染, 这里的动态和静态实际上都是转换到 世界系的 高斯 然后一起渲染的。 为了渲染 动态物体,将场景高斯的 动态物体的 Opacity设置为0, 其他的属性不用改变。

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

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

相关文章

《算法笔记》10.5小节——图算法专题->最小生成树 问题 E: Jungle Roads

题目描述 The Head Elder of the tropical island of Lagrishan has a problem. A burst of foreign aid money was spent on extra roads between villages some years ago. But the jungle overtakes roads relentlessly, so the large road network is too expensive to mai…

【音视频】SDL简介

官网&#xff1a;官网 文档&#xff1a;文档 SDL&#xff08;Simple DirectMedia Layer&#xff09;是一套开放源代码的跨平台多媒体开发库&#xff0c;使用C语言写成。SDL提供数种控制图像、声音、输出入的函数&#xff0c;让开发者只 要用相同或是相似的代码就可以开发出跨多…

SpringBoot + SSE 实时异步流式推送

前言 在当今数字化时代&#xff0c;实时数据处理对于企业的决策和运营至关重要。许多业务场景需要及时响应数据库中的数据变化&#xff0c;例如电商平台实时更新库存、金融系统实时监控交易数据等。 本文将详细介绍如何通过Debezium捕获数据库变更事件&#xff0c;并利用Serv…

ADS1299模拟前端(AFE)代替芯片——LHE7909

在现代医疗科技的飞速发展中&#xff0c;精确的生物电势测量设备变得越来越重要。领慧立芯推出的LHE7909&#xff0c;是一款专为心电图&#xff08;ECG&#xff09;和其他生物电势测量设计的低噪声24位模数转换器&#xff08;ADC&#xff09;&#xff0c;为医疗设备制造商提供了…

如何实现Redis和Mysql中数据双写一致性

一、引言 今天我们来聊聊一个在分布式系统中非常常见但又十分棘手的问题——Redis与MySQL之间的双写一致性。我们在项目中多多少少都遇到过类似的困扰&#xff0c;缓存是用Redis&#xff0c;数据库是用MySQL&#xff0c;但如何确保两者之间的数据一致性呢&#xff1f;接下来我…

面试篇 - Transformer前馈神经网络(FFN)使用什么激活函数?

1. FFN结构分解 原始Transformer的FFN层 FFN(x) max(0, xW₁ b₁)W₂ b₂ # 原始论文公式 输入&#xff1a;自注意力层的输出 x&#xff08;维度 d_model512&#xff09; 扩展层&#xff1a;xW₁ b₁&#xff08;扩展为 d_ff2048&#xff09; 激活函数&#xff1a;Re…

基于Python Flask的深度学习电影评论情感分析可视化系统(2.0升级版,附源码)

博主介绍&#xff1a;✌IT徐师兄、7年大厂程序员经历。全网粉丝15W、csdn博客专家、掘金/华为云//InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&#x1f3…

前端vue2修改echarts字体为思源黑体-避免侵权-可以更换为任意字体统一管理

1.下载字体 npm install fontsource/noto-sans-sc 不知道为什么我从github上面下载的不好使&#xff0c;所以就用了npm的 2.引用字体 import fontsource/noto-sans-sc; 在入口文件-main.js中引用 3.设置echats模板样式 import * as echarts from echarts; // 在import的后…

51c自动驾驶~合集37

我自己的原文哦~ https://blog.51cto.com/whaosoft/13878933 #DETR->DETR3D->Sparse4D 走向长时序稀疏3D目标检测 一、DETR 图1 DETR架构 DETR是第一篇将Transformer应用到目标检测方向的算法。DETR是一个经典的Encoder-Decoder结构的算法&#xff0c;它的骨干网…

【MongoDB篇】MongoDB的集合操作!

目录 引言第一节&#xff1a;集合的“诞生”——自动出现还是手动打造&#xff1f;&#x1f914;第二节&#xff1a;集合的“查阅”——看看这个数据库里有哪些柜子&#xff1f;&#x1f4c2;&#x1f440;第三节&#xff1a;集合的“重命名”——给文件柜换个名字&#xff01;…

Goland终端PowerShell命令失效

Goland终端Terminal的PowerShell不能使用&#xff0c;明明windows上升级了PowerShell 7设置了配置文件&#xff0c;但是只能在windows终端下使用&#xff0c;goland终端下直接失效报错&#xff0c;安装升级PowerShell请看Windows11终端升级PowerShell7 - HashFlag - 博客园 问…

简单分析自动驾驶发展现状与挑战

一、技术进展与市场渗透 技术分级与渗透率 当前量产乘用车的自动驾驶等级以L2为主&#xff08;渗透率约51%&#xff09;&#xff0c;L3级处于初步落地阶段&#xff08;渗透率约20%&#xff09;&#xff0c;而L4级仍处于测试和示范运营阶段&#xff08;渗透率约11%&#xff09;2…

【C++类和数据抽象】消息处理示例(1):从设计模式到实战应用

目录 一、数据抽象概述 二、消息处理的核心概念 2.1 什么是消息处理&#xff1f; 2.2 消息处理的核心目标 三、基于设计模式的消息处理实现 3.1 观察者模式&#xff08;Observer Pattern&#xff09; 3.2 命令模式&#xff08;Command Pattern&#xff09; 四、实战场景…

【统计方法】交叉验证:Resampling, nested 交叉验证等策略 【含R语言】

Resampling (重采样方法) 重采样方法是从训练数据中反复抽取样本&#xff0c;并在每个&#xff08;重新&#xff09;样本上重新调整模型&#xff0c;以获得关于拟合模型的附加信息的技术。 两种主要的重采样方法 Cross-Validation (CV) 交叉验证 &#xff1a; 用于估计测试误…

常见的 CSS 知识点整理

1. 盒模型&#xff08;Box Model&#xff09;是什么&#xff1f;标准盒模型和 IE 盒模型的区别&#xff1f; 答案&#xff1a; CSS 盒模型将元素视为一个盒子&#xff0c;由内容&#xff08;content&#xff09;、内边距&#xff08;padding&#xff09;、边框&#xff08;bor…

Educational Codeforces Round 178 div2(题解ABCDE)

A. Three Decks #1.由于最后三个数会相等&#xff0c;提前算出来和&#xff0c;%3判断&#xff0c;再判前两个数是否大于 #include<iostream> #include<vector> #include<stdio.h> #include<map> #include<string> #include<algorithm> #…

如何创建一个导入模板?全流程图文解析

先去找到系统内可以上传东西的按钮 把你的模板上传上去,找到对应的fileName 图里的文字写错了,是复制粘贴"filePath"到URL才能下载

通信原理第七版与第六版区别附pdf

介绍 我用夸克网盘分享了「通信原理 第7版》樊昌信」&#xff0c;链接&#xff1a;https://pan.quark.cn/s/be7c5af4cdce 《通信原理&#xff08;第7版&#xff09;》是在第6版的基础上&#xff0c;为了适应当前通信技术发展和教学需求&#xff0c;并吸取了数十所院校教师的反…

Mysql唯一性约束

唯一性约束&#xff08;Unique Constraint&#xff09;是数据库设计中用于保证表中某一列或多列组合的值具有唯一性的一种规则。它可以防止在指定列中插入重复的数据&#xff0c;有助于维护数据的完整性和准确性。下面从几个方面为你详细解释 作用 确保数据准确性&#xff1a…

测试基础笔记第十六天

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、UI自动化介绍1.认识UI自动化测试2.实施UI自动化测试前置条件3.UI自动化测试执行时机4.UI自动化测试核心作用和劣势 二、认识Web自动化测试工具-Selenium021.Sel…