OpenPCDet系列 | 4.4 DataProcessor点云数据处理模块解析

news2025/1/24 1:36:45

文章目录

  • DataProcessor模块解析
  • 1. mask_points_and_boxes_outside_range
  • 2. shuffle_points
  • 3. transform_points_to_voxels

DataProcessor模块解析

在对batch_data的处理中,经过了point_feature_encoder模块处理后,就轮到了进行data_processor处理。在data_processor的forward流程中比较简单,就是依次经过队列各模块处理即可,如下所示:

def forward(self, data_dict):
    """
    Args:
        data_dict:
            points: (N, 3 + C_in)
            gt_boxes: optional, (N, 7 + C) [x, y, z, dx, dy, dz, heading, ...]
            gt_names: optional, (N), string
            ...

    Returns:
    """
    # 依次进行各类数据处理,不断更新data_dict
    for cur_processor in self.data_processor_queue:
        data_dict = cur_processor(data_dict=data_dict)

其中,这里的data_dict保留了是否启动某些数据增强的相关信息,以及具体确定的随机参数:

在这里插入图片描述

在pointpillars中主要进行3种数据处理,分别是:mask_points_and_boxes_outside_range、shuffle_points、transform_points_to_voxels;下面对别对着几个函数进行记录。


1. mask_points_and_boxes_outside_range

给定点云场景的一个限制范围limit_range: [minx, miny, minz, maxx, maxy, maxz],现在对超过这个范围的点进行过滤,同时对gt中心点在这个范围外也进行过滤。那么得到的结果是gt的部分点可能会因为这个范围限制而被截取。

核心函数与核心代码如下所示:

# 功能: 限制点云在限制范围集中,返回的是每个点云是否符合范围的掩码(布尔变量)
def mask_points_by_range(points, limit_range):
    """
    Args:
        points: (N, 4) 点云特征
        limit_range: [minx, miny, minz, maxx, maxy, maxz]
    """
    mask = (points[:, 0] >= limit_range[0]) & (points[:, 0] <= limit_range[3]) \
           & (points[:, 1] >= limit_range[1]) & (points[:, 1] <= limit_range[4])
    return mask
    
# 功能:移除范围外的gt
def mask_boxes_outside_range_numpy(boxes, limit_range, min_num_corners=1, use_center_to_filter=True):
    """
    Args:
        boxes: (N, 7) [x, y, z, dx, dy, dz, heading, ...], (x, y, z) is the box center
        limit_range: [minx, miny, minz, maxx, maxy, maxz]
        min_num_corners: 1
        use_center_to_filter: True 是否利用gt中心店来进行采样
    Returns:

    """
    if boxes.shape[1] > 7:
        boxes = boxes[:, 0:7]   # 这里去除最后一位的类别id
    if use_center_to_filter:
        box_centers = boxes[:, 0:3]     # 提取xyz中心位置信息
        mask = ((box_centers >= limit_range[0:3]) & (box_centers <= limit_range[3:6])).all(axis=-1)  # 中心点是否在限制范围内
    return mask

2. shuffle_points

随后根据点数量构建一个随机顺序的索引序列,然后根据这个随机的索引序列对点云进行重新编排点顺序,核心代码如下所示:

# 训练过程打乱,测试过程不打乱
if config.SHUFFLE_ENABLED[self.mode]:
    points = data_dict['points']
    shuffle_idx = np.random.permutation(points.shape[0])    # 生成随机序列索引
    points = points[shuffle_idx]    # 根据索引重新编排点顺序
    data_dict['points'] = points

3. transform_points_to_voxels

这部分的具体执行代码调用了sponv进行稀疏卷积,将点场景转换为voxel场景,核心代码如下所示:

# 功能:将点云转换为voxel,调用spconv的VoxelGeneratorV2
def transform_points_to_voxels(self, data_dict=None, config=None):
    # 初始化确认网格大小与体素大小
    if data_dict is None:
        grid_size = (self.point_cloud_range[3:6] - self.point_cloud_range[0:3]) / np.array(config.VOXEL_SIZE)   # 网格数量
        self.grid_size = np.round(grid_size).astype(np.int64)   # 四舍五入取整
        self.voxel_size = config.VOXEL_SIZE      # 从配置文件中获取指定的体素大小
        # just bind the config, we will create the VoxelGeneratorWrapper later,
        # to avoid pickling issues in multiprocess spawn
        return partial(self.transform_points_to_voxels, config=config)

    if self.voxel_generator is None:
        self.voxel_generator = VoxelGeneratorWrapper(
            vsize_xyz=config.VOXEL_SIZE,   # 体素大小 [0.16, 0.16, 4]
            coors_range_xyz=self.point_cloud_range,     # 场景范围 [0, -39.68, -3, 69.12, 39.68, 1]
            num_point_features=self.num_point_features, # 每个点特征数量 4
            max_num_points_per_voxel=config.MAX_POINTS_PER_VOXEL,   # 每个voxel最大点云数 32
            max_num_voxels=config.MAX_NUMBER_OF_VOXELS[self.mode],  # 场景的最大voxel数 训练模式是 16000
        )

    # 调用spconv的voxel_generator的generate方法生成体素
    points = data_dict['points']
    voxel_output = self.voxel_generator.generate(points)
    voxels, coordinates, num_points = voxel_output
    """
        voxels: (num_voxels, max_points_per_voxel, 3 + C)  表示每个体素中有32个点云,每个点有3+C(4)和特征维度
        coordinates: (num_voxels, 3)     在点云场景中voxel的位置信息,pointpillars算法这里的voxel就是pillars,所以只有平面上的2d坐标,没有z维度切分
        num_points: (num_voxels)         表示每个voxel内的有效点数量
    """
    
    ......

在data_process模块处理完后,单帧点云场景的数据处理流程就此结束了,剩下的就是就是收集batch_size各如此的单帧点云数据构建成一个batch数据,然后对batch数据进行处理。


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

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

相关文章

django路由(多应用配置)

一、配置全局路由 在应用下&#xff0c;定义视图函数views.py from django.http import HttpResponse from django.shortcuts import render# Create your views here.def get_order(request):return HttpResponse("orders应用下的路由") 在项目的urls路由配置中&…

Qt事件传递及相关的性能问题

在使用Qt时&#xff0c;我们都知道能通过mousePressEvent&#xff0c;eventFilter等虚函数的重写来处理事件&#xff0c;那么当我们向一个界面发送事件&#xff0c;控件和它的父控件之间的事件传递过程是什么样的呢&#xff1f; 本文将以下图所示界面为例&#xff0c;结合源码介…

【sentinel】热点规则详解及源码分析

何为热点&#xff1f;热点即经常访问的数据。很多时候我们希望统计某些热点数据中访问频次最高的Top K数据&#xff0c;并对其访问进行限制。 比如&#xff1a; 商品ID为参数&#xff0c;统计一段时间内最常购买的商品ID并进行限制用户ID为参数&#xff0c;针对一段时间内频繁…

【linux】init进程的详解

文章目录 概述init进程完成从内核态向用户态的转变&#xff08;1&#xff09;一个进程先后两种状态&#xff08;2&#xff09;init进程在内核态下的工作内容&#xff08;3&#xff09;init进程在用户态下的工作内容&#xff08;4&#xff09;init进程如何从内核态跳跃到用户态 …

springboot+vue高校社团管理系统(源码+文档)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的高校社团管理系统。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 &#x1f495;&#x1f495;作者&#xff1a;风…

Linux快速安装Erlang和RabbitMQ单机版

环境 CentOS7Xshell6XFtp6Erlang 21.3RabbitMQ 3.8.4 安装方式 同一个软件有很多种安装方式&#xff0c;在Linux系统有几种常见的软件安装方式&#xff1a; 源码编译安装&#xff1a;一般需要解压&#xff0c;然后使用make、make install等命令RPM&#xff08;RedHat Packa…

从物业管理到IT互联网精英,月薪11k的她几经辗转,终得偿所愿!

所谓“男怕入错行”&#xff0c;其实对女生来说也是一样&#xff0c;不同行业对人生的改变太大&#xff0c;想要找到满意的工作&#xff0c;就要不断去尝试。 西安的学员小文&#xff0c;大学毕业后从事的本专业&#xff08;物业管理&#xff09;工作&#xff0c;但不是很喜欢…

条款1:理解模板类型推导

现代C中被广泛应用的auto是建立在模板类型推导的基础上的。而当模板类型推导规则应用于auto环境时&#xff0c;有时不如应用于模板中那么直观。由于这个原因&#xff0c;真正理解auto基于的模板类型推导的方方面面非常重要。 在c中声明一个模板函数的伪代码基本如下&#xff1…

JVM 直接内存(Direct Memory)

直接内存概述 不是虚拟机运行时数据区的一部分&#xff0c;也不是<<Java 虚拟机规范>> 中定义的内存区域直接内存是Java 堆外的、直接向系统申请的内存区间来源于 NIO&#xff0c;通过存在堆中的 DirectByteBuffer 操作 Native 内存访问直接内存的速度会优于 Java…

智慧停车APP系统开发 停车取车缴费智能搞定

生活水平的提高让车辆成为很多人出行主要的代步工具&#xff0c;很多家庭现在已经不止拥有一辆汽车了&#xff0c;所以城市建设中关于停车场的规划管理也是很重要的部分。不过现在出门很多时候还是会碰到找不到停车场&#xff0c;没有车位、收费不合理、乱收费等现象。智慧停车…

调试和优化遗留代码

1. 认识调试器 1.1 含义 一个能让程序运行、暂停、然后对进程的状态进行观测甚至修改的工具。 在日常的开发当中使用非常广泛。(PHP开发者以及前端开发者除外) 1.2 常见的调试器 Go语言的自带的 delve 简写为 “dlv”GNU组织提供的 gdbPHP Xdebug前端浏览器debug 调试 1.3…

DNS投毒

定义 DNS缓存投毒又称DNS欺骗,是一种通过查找并利用DNS系统中存在的漏洞,将流量从合法服务器引导至虚假服务器上的攻击方式。与一般的钓鱼攻击采用非法URL不同的是,这种攻击使用的是合法URL地址。 DNS缓存中毒如何工作 在实际的DNS解析过程中,用户请求某个网站,浏览器首…

English Learning - L3 作业打卡 Lesson1 Day6 2023.5.10 周三

English Learning - L3 作业打卡 Lesson1 Day6 2023.5.10 周三 引言&#x1f349;句1: The expression was first used in America at the beginning of the twentieth century .成分划分弱读连读爆破语调 &#x1f349;句2: It probably comes from the fact that many babies…

分享一组有意思的按钮设计

先上效果图&#xff1a; 一共16个&#xff0c;每个都有自己不同的样式和效果&#xff0c;可以用在自己的项目中&#xff0c;提升客户体验~ 再上代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8">&l…

非Autosar软件手动集成XCP协议栈

文章目录 前言XCP发送XCP接收Xcp初始化Xcp主函数Xcp Event总结前言 最近项目由于各种原因没有直接采用基于Autosar工具生成的代码。只使用了NXP的MCAL。Demo需求实现XCP功能。本文记录手动集成XCP协议的过程,基于CAN总线。集成的前提过程是已有了XCP的静态代码和配置代码。可…

数据结构pta第一天: 堆中的路径 【用数组模拟堆的操作】

这道题其实就涉及两个堆操作&#xff0c; 一个是插入&#xff0c;一个是通过从底到根的遍历 堆的插入&#xff1a;其实就是从下面往上&#xff0c;一个一个比较&#xff0c;&#xff08;因为上面的节点里的值越来越小&#xff0c;如果插入的值比上面的节点小那么就要向上推&am…

基于AT89C51单片机的电子时钟设计与仿真

点击链接获取Keil源码与Project Backups仿真图&#xff1a; https://download.csdn.net/download/qq_64505944/87779867?spm1001.2014.3001.5503 源码获取 主要内容&#xff1a; 使用DS1302芯片作为计时设备&#xff0c;用6个7段LED数码管或者LCD162作为显示设备&#xff0c…

【软考七】面向对象技术--UML、设计模式(分数重,刷题刷题)

建议UML和设计模式去听听课&#xff0c;内容多&#xff0c;还需要记。这一部分内容较多&#xff0c;下半年的考生可以慢慢看&#xff0c;上半年的就去刷题吧。 该博客不适合学习UML和设计模式&#xff0c;只适合考试。要学的不要在这浪费时间&#xff0c;切记切记 在5月13号忽然…

MD-MTSP:孔雀优化算法POA求解多仓库多旅行商问题(提供MATLAB代码,可以修改旅行商个数及起点)

一、多仓库多旅行商问题 多旅行商问题&#xff08;Multiple Traveling Salesman Problem, MTSP&#xff09;是著名的旅行商问题&#xff08;Traveling Salesman Problem, TSP&#xff09;的延伸&#xff0c;多旅行商问题定义为&#xff1a;给定一个&#x1d45b;座城市的城市集…

Midjourney8种风格极其使用场景

目录 ​编辑 引言 等距动画 场景 分析性绘图 场景 着色书 场景 信息图画 场景 双重曝光 场景 图示性绘画 场景 二维插图 场景 图解式画像 场景 总结&#xff1a; 八种风格箴言&#xff1a; 引言 我相信大家都或多或少玩过Midjourney&#xff0c;但是要形…