当前位置: 首页 > news >正文

OpenPCDet系列 | 4.2 DataAugmentor点云数据增强模块解析

文章目录

  • DataAugmentor模块解析
  • 1. gt_sampling
  • 2. random_world_flip
  • 3. random_world_rotation
  • 4. random_world_scaling
  • 5. limit_period

DataAugmentor模块解析

在pointpillars算法中,具体的数据增强方法配置是在yaml中的DATA_CONFIG.DATA_AUGMENTOR进行配置,pointpillars的参考配置如下所示:

DATA_AUGMENTOR:DISABLE_AUG_LIST: ['placeholder']   # 禁用该数据增强AUG_CONFIG_LIST:                    # 启用的数据增强列表- NAME: gt_samplingUSE_ROAD_PLANE: True    # 启用道路平面信息,将gt中心位置移动到道路平面上(abcd表示一个平面方程)DB_INFO_PATH:- kitti_dbinfos_train.pkl   # 存储训练集每个类别的对象信息,每个类别用列表来存储,应该与INFO_PATH对应PREPARE: {    # gt的具体采样操作filter_by_min_points: ['Car:5', 'Pedestrian:5', 'Cyclist:5'],  # 表示过滤低于5个点的gt,需要int型赋值filter_by_difficulty: [-1],    # 过滤的困难等级列表}# USE_SHARED_MEMORY: False    # 默认不设置共享内存,若开启需要设置DB_DATA_PATHSAMPLE_GROUPS: ['Car:15','Pedestrian:15', 'Cyclist:15']NUM_POINT_FEATURES: 4DATABASE_WITH_FAKELIDAR: FalseREMOVE_EXTRA_WIDTH: [0.0, 0.0, 0.0]   # 将采样box扩张大小长度LIMIT_WHOLE_SCENE: False- NAME: random_world_flipALONG_AXIS_LIST: ['x']- NAME: random_world_rotationWORLD_ROT_ANGLE: [-0.78539816, 0.78539816]- NAME: random_world_scalingWORLD_SCALE_RANGE: [0.95, 1.05]

在data_augmentor模块初始化后,在进行前向传播的数据准备时,也就是batch = next(dataloader_iter)的时候,会在kitti_dataset的__getitem__函数进行数据的准备,随机获取一个点云帧场景索引,准备好当前点云帧的点特征、gt boxes、gt类别名称、坐标系转换类calib、道路信息road_plane等数据,构建成一个data_dict传入基类的prepare_data函数中,进行数据的进一步处理,形成训练的batch数据。此外,在__getitem__函数中还会困难进行FOV点云视角的范围裁剪,也就是将全方位的点云场景只保留前视图的点云,在这一步之后当前点云帧场景的点云数量会大大降低。

在基类的prepare_data函数中,即会依次进行data_augmentor部分、point_feature_encoder部分、以及data_processor部分三大部分的数据处理,最后形成最终的batch数据输入到模型中进行训练,下面分别对着data_augmentor部分进行记录介绍。在pointpillars配置文件中,数据增强部分就包含了gt_sampling、random_world_flip、random_world_rotation、random_world_scaling四种方法。下面对其进行分别记录。

在数据增强基类DataAugmentor中提供了一些列的数据增强的方法,在初始化阶段会依次添加配置文件中制定的数据增强方式进入队列中,随后在forward函数中对data_dict数据进行依次处理。由于队列先进先出的特性,所以在配置文件中靠前的部分会按顺序优先处理。

def forward(self, data_dict):      # 在prepare_data中进行"""Args:data_dict:points: (N, 3 + C_in)gt_boxes: optional, (N, 7) [x, y, z, dx, dy, dz, heading]gt_names: optional, (N), string...Returns:"""# 遍历增强队列,逐个增强器做数据增强for cur_augmentor in self.data_augmentor_queue:data_dict = cur_augmentor(data_dict=data_dict)......

1. gt_sampling

在pointpillars的数据增强方法中首要的就是gt_sampling方法。对于gt的信息格式存储在db_infos字典中,具体是在database_sampler中进行处理,对于每个类别的每个内容如下所示:
在这里插入图片描述

在pcdet.datasets.augmentor.database_sampler.py文件中提供了DataBaseSampler类来完成这一模块,在__init__初始化类阶段首先会对训练集数据的全部gt样本进行读取,对每个gt的点云数量较少或者是困难等级的gt进行过滤。随后对每个类别的gt重新统计信息,包含采样数量、过滤后的gt数量(变化)、以及重新分配索引(从0开始分配)。这部分的gt过滤操作通过DATA_AUGMENTOR.PREPARE部分来进行设置。以上即设置了两个过滤操作。分别是:filter_by_min_points、filter_by_difficulty。

随后,在具体的数据准备过程中具体调用的DataBaseSampler的__call__方法,这相当于是继承nn.Module时调用的forward方法,即运行对象。在训练集各类别中随机采样与当前帧点云不重叠的gt,作为当前帧额外的独立采样gt,并添加到当前的点云帧场景中,相当于是一个copy paste操作。而挑选不重叠的gt过程的挑选相当于是一个碰撞测试,避免影响到当前点云帧的原始gt,从而实现gt样本的增多,即数据增强的效果。

具体将采样的gt与当前点云帧场景进行结合,并将gt移动到道路平面上具体操作是有DataBaseSampler.add_sampled_boxes_to_scene方法实现的。主要作用就是将gt移动到道路平面上,首先去除原始的gt(这里还会将原始的gt扩张)内的点云,然后将采样的gt点云与背景点点云拼接构造成新的场景。

在对训练集gt样本进行具体体的随机才样操作是通过sample_with_fixed_number函数来具体实现,主要的实现方法是获取打乱顺序后的indices前 sample_num 个db_infos。所以,总的来说gt_sampling这一部分就是围绕着gt的采样来实现。比如对gt进行限制过滤,然后采样其他场景的gt来添加到当前点云帧场景,前提是通过碰撞测试,从而实现数据增强,类似的一个copy paste的思路。具体实现上还有FOV的范围筛选,道路平面的转移等操作细节。核心代码如下所示:

# 将采样的box扩大,sampler_cfg.REMOVE_EXTRA_WIDTH即为dx,dy和dz的放大长度
large_sampled_gt_boxes = box_utils.enlarge_box3d(sampled_gt_boxes[:, 0:7], extra_width=self.sampler_cfg.REMOVE_EXTRA_WIDTH
)# 核心代码:更新当前点云场景信息
points = box_utils.remove_points_in_boxes3d(points, large_sampled_gt_boxes)    # 只保留背景点,去除前景点
points = np.concatenate([obj_points[:, :points.shape[-1]], points], axis=0)    # 将采样+原始gt点云与放大后保留的背景点拼接,组成新的点云
gt_names = np.concatenate([gt_names, sampled_gt_names], axis=0)     # 将类别拼接
gt_boxes = np.concatenate([gt_boxes, sampled_gt_boxes], axis=0)     # 将box拼接

在进行gt‘采样后的数据增强时,data_dict数据字典中只保留了4个有效键值对,如下所示。分别是当前点云帧索引,gt类别名称,gt boxes以及加入采样gt后的新点云场景points
在这里插入图片描述


2. random_world_flip

对点云和gt沿x轴或者y轴按一定分布概率进行随机反转,具体的实现函数是在augmentor_utils中。

  • 沿x轴进行反转的核心代码:
if enable is None:enable = np.random.choice([False, True], replace=False, p=[0.5, 0.5])   # 一半的概率选择是否翻转
if enable:gt_boxes[:, 1] = -gt_boxes[:, 1]    # y坐标翻转gt_boxes[:, 6] = -gt_boxes[:, 6]    # 方位角翻转,直接取负数,因为方位角定义为与x轴的夹角(这里按照顺时针的方向取角度)points[:, 1] = -points[:, 1]        # 点云y坐标翻转
  • 沿y轴进行反转的核心代码:
if enable is None:enable = np.random.choice([False, True], replace=False, p=[0.5, 0.5])   # 一半的概率选择是否翻转
if enable:gt_boxes[:, 0] = -gt_boxes[:, 0]    # x坐标翻转gt_boxes[:, 6] = -(gt_boxes[:, 6] + np.pi)  # 方位角加pi后,取负数(这里按照顺时针的方向取角度)points[:, 0] = -points[:, 0]        # 点云x坐标取反

通过设置ALONG_AXIS_LIST来进行xy轴的反转设置,如果确定反转,会在data_dict中对反转的轴进行保留。


3. random_world_rotation

对点云和gt进行随机旋转,具体的实现函数是在augmentor_utils中,其会调用common_utils.rotate_points_along_z函数来实现沿z轴进行点云场景的旋转。

对于点云的旋转来说,一般都是利用旋转角度构建成沿z轴旋转的旋转矩阵来与坐标进行相乘,随后将旋转后的点云坐标再与原始的反射特征强度进行拼接,拼接成原来的点云特征维度(dim=4)。在函数实现中,这里是实现对batch数据进行数据增强操作,batch内的每帧数据都会分配一个随机选择angle,然后构建成一个batch的旋转矩阵。

  • 沿z轴进行旋转的核心代码:
cosa = torch.cos(angle)
sina = torch.sin(angle)
zeros = angle.new_zeros(points.shape[0])    # [0]
ones = angle.new_ones(points.shape[0])      # [1]
rot_matrix = torch.stack((  # 根据旋转角构造沿z轴旋转的旋转矩阵cosa,  sina, zeros,-sina, cosa, zeros,zeros, zeros, ones
), dim=1).view(-1, 3, 3).float()
points_rot = torch.matmul(points[:, :, 0:3], rot_matrix)    # 对点云坐标进行旋转 (B, N, 3)
points_rot = torch.cat((points_rot, points[:, :, 3:]), dim=-1) 

此外,这里的旋转角度是从给点的阈值范围内进行均匀分布而产生,增加了随机性。随机产生的旋转角度也会记录在data_dict中。


4. random_world_scaling

对点云和gt进行随机缩放,具体实现函数是在augmentor_utils中。

具体的缩放操作比较简单,直接将点云坐标与gt坐标和尺寸与缩放因子进行相乘即可。随机产生的缩放大小也会记录在data_dict中。核心代码如下所示:

if scale_range[1] - scale_range[0] < 1e-3:  # 如果缩放的尺度过小,则直接返回原来的box和点云return gt_boxes, points
noise_scale = np.random.uniform(scale_range[0], scale_range[1]) # 在缩放范围内随机产生缩放尺度
points[:, :3] *= noise_scale
gt_boxes[:, :6] *= noise_scale  # [:, :6]表示xyz,dxdydz均进行缩放

在进行了以上多种数据增强方式后,相关的记录都会记录在data_dict字典中,其中的gt boxes和points点云特征会不断进行更新,处理后的键值对如下所示:
在这里插入图片描述


5. limit_period

由于在gt的方向中存在大于π的偏移,这里额外将方位角限制在[-pi, pi],方位角定义为与x轴的夹角(这里按照顺时针的方向取角度)

# 功能: 将方位角限制在[-pi, pi],方位角定义为与x轴的夹角(这里按照顺时针的方向取角度)
# common_utils.py
def limit_period(val, offset=0.5, period=np.pi):val, is_numpy = check_numpy_to_torch(val)   # 格式转换,其中val表示的角度ans = val - torch.floor(val / period + offset) * period  # 将方位角限制在[-pi, pi]return ans.numpy() if is_numpy else ans# 将方位角限制在[-pi,pi]
# data_augmentor.py
data_dict['gt_boxes'][:, 6] = common_utils.limit_period(data_dict['gt_boxes'][:, 6], offset=0.5, period=2 * np.pi
)

在保存限制方位角后的gt,此时的data_dict即更新完毕,即将送入下一个模块中。


相关文章:

OpenPCDet系列 | 4.2 DataAugmentor点云数据增强模块解析

文章目录 DataAugmentor模块解析1. gt_sampling2. random_world_flip3. random_world_rotation4. random_world_scaling5. limit_period DataAugmentor模块解析 在pointpillars算法中&#xff0c;具体的数据增强方法配置是在yaml中的DATA_CONFIG.DATA_AUGMENTOR进行配置&#…...

精准测试之过程与实践 | 京东云技术团队

作者&#xff1a;京东工业 宛煜昕 一、怎样的技术 •百度百科&#xff1a; 精准测试是一套计算机测试辅助分析系统。 精准测试的核心组件包含的软件测试示波器、用例和代码的双向追溯、智能回归测试用例选取、覆盖率分析、缺陷定位、测试用例聚类分析、测试用例自动生成系统…...

类ChatGPT逐行代码解读(1/2):从零实现Transformer、ChatGLM-6B

前言 最近一直在做类ChatGPT项目的部署 微调&#xff0c;关注比较多的是两个&#xff1a;一个LLaMA&#xff0c;一个ChatGLM&#xff0c;会发现有不少模型是基于这两个模型去做微调的&#xff0c;说到微调&#xff0c;那具体怎么微调呢&#xff0c;因此又详细了解了一下微调代…...

车道线检测

前言 目前&#xff0c;车道线检测技术已经相当成熟&#xff0c;主要应用在自动驾驶、智能交通等领域。下面列举一些当下最流行的车道线检测方法&#xff1a; 基于图像处理的车道线检测方法。该方法是通过图像处理技术从摄像头传回的图像中提取车道线信息的一种方法&#xff0c…...

云渲染靠谱吗,使用云渲染会不会被盗作品?

云渲染靠谱吗、安全吗&#xff1f;如果使用 云渲染会不会被盗作品......Renderbus瑞云渲染作为一个正经的云渲染平台&#xff0c;也时不时会收到这类疑问&#xff0c;首先&#xff0c;瑞云渲染是肯定靠谱的,各位可以放心使用。另外小编也将在本篇教你如何辨别云渲染平台是否安全…...

什么是FPGA?关于FPGA基础知识 一起来了解FPGA lattice 深力科 MachXO3系列 LCMXO3LF-9400C-5BG256C

什么是FPGA&#xff1f;关于FPGA基础知识 一起来了解FPGA lattice 深力科 MachXO3系列 LCMXO3LF-9400C-5BG256C FPGA基础知识&#xff1a;FPGA是英文Field&#xff0d;Programmable Gate Array的缩写&#xff0c;即现场可编程门阵列&#xff0c;它是在PAL、GAL、CPLD等可编程器…...

有什么好用的云渲染?

在CG制作流程中&#xff0c;离线渲染一直是必要且耗时的环节。你的场景越复杂&#xff0c;渲染出现问题的可能性就越大&#xff0c;尤其是当你独自工作&#xff0c;没有人给你建议的时候&#xff0c;灯光、模型、场景任何一个环节渲染时出现问题都可能让你焦头烂额&#xff0c;…...

什么是医学影像PACS系统?PACS系统功能有哪些?作用有哪些?对接哪些设备?业务流程是什么?

一、什么是医学影像PACS系统 PACS&#xff1a;为Picture Archive and CommunicationSystem的缩写&#xff0c;是图象归档和通讯系统。PACS系统应用在医院影像科室的系统&#xff0c;主要的任务就是把日常产生的各种医学影像&#xff08;包括核磁&#xff0c;CT&#xff0c;超声…...

分布式缓存:什么是它以及为什么需要它?

前言 随着网络的快速发展&#xff0c;分布式应用变得越来越普遍。这种类型的应用程序需要访问多个组件和服务&#xff0c;而这些组件可能分散在不同的物理位置上。在这种情况下&#xff0c;由于网络通信的高延迟和低带宽&#xff0c;性能问题变得尤为明显。为解决这一问题&…...

MySQL基础(二十二)逻辑架构

1.逻辑架构剖析 1.1 第1层&#xff1a;连接层 系统&#xff08;客户端&#xff09;访问MySQL服务器前&#xff0c;做的第一件事就是建立TCP连接。 经过三次握手建立连接成功后&#xff0c;MySQL服务器对TCP传输过来的账号密码做身份认证、权限获取。 用户名或密码不对&#…...

《Kubernetes证书篇:使用TLS bootstrapping简化kubelet证书制作》

一、背景 Master apiserver启用TLS认证后&#xff0c;Node节点kubelet和kube-proxy要与kube-apiserver进行通信&#xff0c;必须使用CA签发的有效证书才可以&#xff0c;当Node节点很多时&#xff0c;这种客户端证书颁发需要大量工作&#xff0c;同样也会增加集群扩展复杂度。 …...

vue+elementui+nodejs机票航空飞机航班查询与推荐

语言 node.js 框架&#xff1a;Express 前端:Vue.js 数据库&#xff1a;mysql 数据库工具&#xff1a;Navicat 开发软件&#xff1a;VScode )本系统主要是为旅客提供更为便利的机票预定方式&#xff0c;同时提高民航的预定机票的工作效率。通过网络平台实现信息化和网络化&am…...

将ssh发布密钥添加到服务器的ssh授权密钥中,但是为什么我仍然无法ssh登录到此服务器?

我已经将ssh发布密钥添加到服务器的ssh授权密钥中&#xff0c;但是为什么我仍然无法ssh登录到此服务器&#xff1f; 即使将ssh公钥添加到服务器的授权密钥中&#xff0c;您也可能无法通过SSH登录到服务器&#xff0c;这有几个原因: 1.服务器的authorized_keys文件的权限不正确…...

LeetCode——子串能表示从 1 到 N 数字的二进制串

1016. 子串能表示从 1 到 N 数字的二进制串 - 力扣&#xff08;Leetcode&#xff09; 目录 一、题目 二、题目解读 三、代码 一、题目 给定一个二进制字符串 s 和一个正整数 n&#xff0c;如果对于 [1, n] 范围内的每个整数&#xff0c;其二进制表示都是 s 的 子字符串 &…...

看火山引擎DataLeap如何做好电商治理(二):案例分析与解决方案

接上篇&#xff0c;以短视频优质项目为例&#xff0c;火山引擎DataLeap平台治理团队会去对每天发布的这种挂购物车车短视频打上标签&#xff0c;识别这些短视频它是优质的还是低质的&#xff0c;以及具体原因。一个视频经过这个模型识别之后&#xff0c;会给到奖惩中心去做相应…...

MySQL笔记-多表查询

本文标签 : 多表查询 事务四大特性 并发事务问题 事务隔离级别 文章目录 目录 文章目录 一、多表查询 1.多表关系 2.多表查询概念 3.多表查询的分类 4.内连接 5.外连接 6.自连接 7.联合查询 8.子查询 1.标量子查询 2.列子查询 3.行子查询 4.表子查询 9.多表查询案例练习 二…...

如何用100天时间,让CSDN的粉丝数从0狂飙到10000

2022年10月7日&#xff0c;正式开通了CSDN账号。但因为工作忙的原因&#xff0c;一直没有时间写博客文章&#xff0c;也没有投入精力在CSDN上。理所当然的&#xff0c;我的粉丝数量很稳定&#xff0c;一直保持着0的记录。 2023年春节假期过后&#xff0c;有点空闲时间了&#x…...

各种同质图神经网络模型的理论和节点表征学习任务的集合包rgb_experiment

诸神缄默不语-个人CSDN博文目录 最近更新时间&#xff1a;2023.5.10 最早更新时间&#xff1a;2023.5.10 本文仅考虑同质图setting下的模型。 对于异质图场景&#xff0c;可以参考我写的另一篇博文&#xff1a;异质图神经网络&#xff08;持续更新ing…&#xff09; node2ve…...

【C++进阶之路】类和对象(中)

文章目录 前言六大默认成员函数 一.构造函数性质默认构造函数构造函数(需要传参) 二.析构函数性质默认析构函数练习 三.拷贝构造函数基本性质&#xff1a;形参必须是引用默认拷贝构造浅拷贝深拷贝自定义类型 四.赋值运算符重载函数基本特征全局的运算符重载函数局部的运算符重载…...

AIMD 为什么收敛(tcp reno/cubic 为什么好)

TCP 拥塞控制目标是缓解并解除网络拥塞&#xff0c;让所有流量公平共享带宽&#xff0c;合在一起就是公平收敛。 AIMD(几乎所有与拥塞控制相关的协议或算法都有 AIMD 的影子&#xff0c;包括 RoCE&#xff0c;BBRv2) 为什么收敛&#xff1f;我一般会给出下面的老图&#xff1a;…...

[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解

突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 ​安全措施依赖问题​ GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案

问题描述&#xff1a;iview使用table 中type: "index",分页之后 &#xff0c;索引还是从1开始&#xff0c;试过绑定后台返回数据的id, 这种方法可行&#xff0c;就是后台返回数据的每个页面id都不完全是按照从1开始的升序&#xff0c;因此百度了下&#xff0c;找到了…...

定时器任务——若依源码分析

分析util包下面的工具类schedule utils&#xff1a; ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类&#xff0c;封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz&#xff0c;先构建任务的 JobD…...

MVC 数据库

MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

3403. 从盒子中找出字典序最大的字符串 I

3403. 从盒子中找出字典序最大的字符串 I 题目链接&#xff1a;3403. 从盒子中找出字典序最大的字符串 I 代码如下&#xff1a; class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...

HashMap中的put方法执行流程(流程图)

1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中&#xff0c;其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下&#xff1a; 初始判断与哈希计算&#xff1a; 首先&#xff0c;putVal 方法会检查当前的 table&#xff08;也就…...

C++.OpenGL (20/64)混合(Blending)

混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...

从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障

关键领域软件测试的"安全密码"&#xff1a;Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力&#xff0c;从金融交易到交通管控&#xff0c;这些关乎国计民生的关键领域…...

论文阅读:LLM4Drive: A Survey of Large Language Models for Autonomous Driving

地址&#xff1a;LLM4Drive: A Survey of Large Language Models for Autonomous Driving 摘要翻译 自动驾驶技术作为推动交通和城市出行变革的催化剂&#xff0c;正从基于规则的系统向数据驱动策略转变。传统的模块化系统受限于级联模块间的累积误差和缺乏灵活性的预设规则。…...

Modbus RTU与Modbus TCP详解指南

目录 1. Modbus协议基础 1.1 什么是Modbus? 1.2 Modbus协议历史 1.3 Modbus协议族 1.4 Modbus通信模型 🎭 主从架构 🔄 请求响应模式 2. Modbus RTU详解 2.1 RTU是什么? 2.2 RTU物理层 🔌 连接方式 ⚡ 通信参数 2.3 RTU数据帧格式 📦 帧结构详解 🔍…...