【三维目标检测】CenterPoint(二)

news2024/11/15 11:09:35

     CenterPoint数据和源码配置调试过程请参考上一篇博文:https://blog.csdn.net/suiyingy/article/details/128002709。本文主要详细介绍CenterPoint网络结构及其运行中间状态。

1 CenterPoint模型总体过程

        CenterPoint模型的整体结构如下图所示,由最初的一阶段模型扩展为了两阶段模型。第二阶段负责对第一阶段的检测结果进行微调修正,与基于候选框的两阶段目标检测思想基本一致。这里重点介绍CenterPoint的第一个阶段,并且单阶段的CenterPoint可直接完成对三维目标的检测。

 

2 主要模块解析

2.1 体素化

        体素化是指对三维空间进行划分成等间隔的立体网格。CenterPoint通过体素化来完成对点云的采样,并且均匀间隔有利于后续进行三维卷积操作。该体素化过程将体素在x、y、z方向上的尺度分别设置为0.075m、0.075m、0.2m,每个体素中最多保留10个点,并且训练阶段体素数量最多为90000个。按照单位体素尺度直接进行计算得到体素总数量为85017600,而实际保留的90000个仅占千分之一左右,因此保留的体素相对整个体素空间来说是稀疏的。

        源码中用于实现体素化的入口函数为self.voxelize(points),具体实现函数为Voxelization(voxel_size=[0.075, 0.075, 0.2], point_cloud_range=[-54, -54, -5.0, 54, 54, 3.0], max_num_points=10, max_voxels=(90000, 120000), deterministic=True)。函数输入分别为:

        (1)points,Nx5,原始点云,N表示点云数量,5表示特征维度,特征为坐标x、y、z、反射强度和激光雷达线束序号(0~31,32线激光雷达)。

        (2)voxel_size:单位体素的尺寸,x、y、z方向上的尺度分别为0.075m、0.075m、0.2m。

        (3)point_cloud_range:x、y、z方向的距离范围,结合(2)中体素尺寸可以得到总的体素数量为1440x1440x41,即85017600。

        (4)max_num_points:定义每个体素中取值点的最大数量,取值为10。

        (5)max_voxels:表示含有点云的体素最大数量,训练时最大值为90000,推理时最大值设置为120000。

        (6)deterministic:取值为True时,表示每次体素化的结果是确定的,而不是随机的。

        体素化结果输出保存在pts_feats中,主要包含三部分:

        (1)voxels:Mx10x5,体素中各个点的原始坐标和反射强度,M(M≤90000)个体素,每个体素最多10个点。

        (2)num_points:Mx1,每个体素中点的数量,最小数量为1,最大数量为10。

        (3)coors_batch:体素自身坐标,坐标值为整数,表示体素的按照单位尺度得到的坐标,Mx4,[batch_id, x, y, z]

2.2 体素特征提取VFE(voxel_encoder)

        在voxelnet中,体素特征通过SVFE层提取,即连续两层VFE,其中VFE层提取体素特征用的是PointNet网络。而在该源码中,VFE层被进行了简化HardSimpleVFE(voxel_encoder),即对每个体素中的点求平均值,用平均值作为体素特征,取平均时点的数量由num_points决定。Mx10x5的voxels经过VFE后的维度为Mx5(voxel_features),即在第二个维度点的数量上进行了平均。体素特征提取相当于用新的5个维度特征来表示体素内一组点的共同特征。体素特征提取的入口函数为self.pts_voxel_encoder(voxels, num_points, coors)。

2.3 中间特征提取 middle_encoder

        类比VoxelNet中的CML(Convolutional Middle Layer)层,voxelnet中直接用三维卷积进行特征提取,而CenterPoint则采用了连续三维稀疏卷积进行特征提取,函数入口为self.pts_middle_encoder(voxel_features, coors, batch_size)。三维稀疏卷积只是普通三维卷积的一种快速计算方法。因而,其卷积过程可完全当作普通卷积操作去理解。根据卷积移动计算过程,卷积结果通常是使特征图尺寸按照步长设置保持不变或逐渐减小,另一方面通道数也会随着网络深度逐步增加。整体效果可看作用更小的特征图、更多的维度(通道数量)来表征原来的目标属性。

        以下三维稀疏卷积用SPConv(C1,C2,K)表示,C1表示输入通道,C2表示输出通道,K表示卷积步长。为了进行稀疏卷积操作,原始特征需要进行稀疏表征。稀疏表征包含两个关键部分,即稀疏点特征和特征网格。稀疏点特征维度为MxC,M表示点的数量,C表示特征为维度,一般由输出通道数决定。特征网格维度为DxHxW,稀疏点最终需要对应到稀疏网格的具体位置,即网格特征不为零的点。稀疏网格也就是体素经过三维卷积后产生的特征图,可类比二维图像像素进行理解。因而,输出特征维度为(CxD)xHxW,在DxHxW大小的特征图之中只有M个点是非零特征,其它地方的特征均为零。CenterPoint提取的空间特征spatial_features维度为256x180x180,具体稀疏卷积提取过程如下。

voxel_features,Mx5, 41x1440x1440 -> SPConv(5, 16, 1) Mx16,41x1440x1440,x
 -> SPConv(16, 16, 1)、SPConv(16, 16, 1)、SPConv(16, 32, 2) M1x32,21x720x720,x1
 -> SPConv(32, 32, 1)、SPConv(32, 32, 1)、SPConv(32, 64, 2) M2x64,11x360x360,x2
 -> SPConv(64, 64, 1)、SPConv(64, 64, 1)、SPConv(64, 128, 2) M3x128,5x180x180,x3
 -> SPConv(128, 128, 1)、SPConv(128, 128, 1) M4x128,5x180x180,x4
 -> SPConv(128, 128, [2, 1, 1]) M5x128,2x180x180,即128x2x180x180
 -> Resshape,256x180x180,spatial_features

2.4 主干网络特征提取backbone

        CenterPoint的主干网络采用的是SECOND结构,通过两条通道提取两种不同尺度的特征图。第一条通路是空间特征spatial_features 256x180x180经连续6个3x3二维卷积得到128x180x180维度的特征,记为out1。第二条通路是out1继续经过连续6个3x3二维卷积(其中第一个步长为2)得到256x90x90维度的特征,记为out2。out1和out2为主干网络输出结果。主干网络关键入口函数为self.pts_backbone(x)。

out1:256x180x180 -> 128x180x180
Sequential(
  (0): Conv2d(256, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
  (1): BatchNorm2d(128, eps=0.001, momentum=0.01, affine=True, track_running_stats=True)
  (2): ReLU(inplace=True)
  (3): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
  (4): BatchNorm2d(128, eps=0.001, momentum=0.01, affine=True, track_running_stats=True)
  (5): ReLU(inplace=True)
  (6): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
  (7): BatchNorm2d(128, eps=0.001, momentum=0.01, affine=True, track_running_stats=True)
  (8): ReLU(inplace=True)
  (9): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
  (10): BatchNorm2d(128, eps=0.001, momentum=0.01, affine=True, track_running_stats=True)
  (11): ReLU(inplace=True)
  (12): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
  (13): BatchNorm2d(128, eps=0.001, momentum=0.01, affine=True, track_running_stats=True)
  (14): ReLU(inplace=True)
  (15): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
  (16): BatchNorm2d(128, eps=0.001, momentum=0.01, affine=True, track_running_stats=True)
  (17): ReLU(inplace=True)
)
Out2:128x180x180 -> 256x90x90
Sequential(
  (0): Conv2d(128, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)
  (1): BatchNorm2d(256, eps=0.001, momentum=0.01, affine=True, track_running_stats=True)
  (2): ReLU(inplace=True)
  (3): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
  (4): BatchNorm2d(256, eps=0.001, momentum=0.01, affine=True, track_running_stats=True)
  (5): ReLU(inplace=True)
  (6): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
  (7): BatchNorm2d(256, eps=0.001, momentum=0.01, affine=True, track_running_stats=True)
  (8): ReLU(inplace=True)
  (9): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
  (10): BatchNorm2d(256, eps=0.001, momentum=0.01, affine=True, track_running_stats=True)
  (11): ReLU(inplace=True)
  (12): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
  (13): BatchNorm2d(256, eps=0.001, momentum=0.01, affine=True, track_running_stats=True)
  (14): ReLU(inplace=True)
  (15): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)
  (16): BatchNorm2d(256, eps=0.001, momentum=0.01, affine=True, track_running_stats=True)
  (17): ReLU(inplace=True)
)
Out = [out1, out2] [128x180x180, 256x90x90]

2.5 上采样拼接 self.neck

        Neck网络分别对out1、out2通过二位逆卷积操作进行上采样,out1的维度从128x180x180转换为256x180x180,out2的维度也从256x90x90转换为256x180x180,两者维度完全相同。out1和out2拼接后得到Neck网络的输出结果,即pts_feats,维度为512x180x180。拼接的主要目的是进行特征融合,实现深层特征和浅层特征融合。深层特征通常特征图尺度较小,总体卷积视野更广。浅层特征通常尺度较大,更能反映局部特征。这种特征融合将局部特征与其周围的语义特征进行了融合。函数入口为 self.pts_neck(x),返回的特征为extract_pts_feat函数最终结果,即pts_feats。

分别对out1、out2进行上采样:
out1:128x180x180 -> 256x180x180
out2:256x90x90 -> 256x180x180
拼接out:256x180x180、256x180x180 -> 512x180x180 (pts_feats)

2.6 CenterHead

        程序中选择了10个类别的数据,并将他们重新归为如下6个大类。算法预测对每个大类建立一个预测分支,即task。每个task负责预测一个大类的目标,包括目标的xy位置偏移、高度、尺寸、角度、速度和热力图等6种属性结果。CenterPoint为每一个大目标类别设置了一个Head结果,主要原因在于同一个热力图特征只能预测一个类别,多个类别需要不同的热力图特征。由于输入数据被分为了6个大类,且每个热力图仅预测一类目标,因而模型预测Head也被分为6个子任务。每个子任务的Head分别预测相应类别目标的位置偏移(reg,2x180x180)、高度(height,1x180x180)、尺寸(dim,3x180x180)、偏航角(rot,2x180x180)、速度(vel,2x180x180)、热力图(heatmap,Kx180x180)。其中,热力图维度中的K表示每个大类下的子类别个数,进步确定一个热力图只能预测一个类别。CenterPoint Head的函数入口为self.pts_bbox_head(pts_feats)。

        Neck结构提取后的特征pts_neck(512x180x180)会再次通过一次卷积Conv2d(512, 64)操作,特征维度降为64x180x180。新的特征则分别经过卷积操作得到各个Head的预测结果,分别如下所示。

  1. 位置偏移reg:Conv2d(64,64)、Conv2d(64,2)  -> 2x180x180
  2. 高度height:Conv2d(64,64)、Conv2d(64,1)  -> 1x180x180
  3. 尺寸dim:Conv2d(64,64)、Conv2d(64,3)  -> 3x180x180
  4. 偏航角正余弦rot:Conv2d(64,64)、Conv2d(64,2)  -> 2x180x180
  5. 速度vel:Conv2d(64,64)、Conv2d(64,2)  -> 2x180x180
  6. 热力图heatmap:Conv2d(64,64)、Conv2d(64,K)  -> Kx180x180

        6个任务的Head中除热力图的第二个卷积通道维度会随着对应大类中小类数目的变化有所差异,其它卷积维度和运算过程完全一致。

2.7 损失函数

        CenterPoint损失主要包括热力图损失和回归损失两大部分,并且分别针对6个task进行计算与合并。热力图用于预测目标中心,而自身与类别相关。因而,热力图决定了目标的有无和分类。热力图的损失函数为GaussianFocalLoss。位置偏移、高度、尺寸、角度和速度等其它预测值的损失函数为L1Loss,并且速度损失权重为0.2,其它权重均为1.0。损失计算的函数入口为self.pts_bbox_head.loss(*loss_inputs)。

        在计算回归损失时,CenterPoint仅计算正样本对应的特征图位置的预测特征,并且将正样本的最大数量限制为500,即每个点云中最多包含500个目标。

2.8 顶层结构

        顶层结构主要包含以下三部分:

        (1)特征提取:self.extract_feat,包括体素化、体素特征提取、中间特征提取、主干特征提取以及Neck上采样特征拼接,得到512x180x180特征pts_feats。

        (2)损失计算:包括Head和损失计算,得到6个任务分支的全部损失。

#img_feats为图像特征,仅使用点云时则不作考虑
def forward_train(self, points=None, img_metas=None, gt_bboxes_3d=None, gt_labels_3d=None, gt_labels=None, gt_bboxes=None, img=None, proposals=None, gt_bboxes_ignore=None):
    img_feats, pts_feats = self.extract_feat(points, img=img, img_metas=img_metas)
    losses = dict()
    if pts_feats:
        losses_pts = self.forward_pts_train(pts_feats, gt_bboxes_3d, gt_labels_3d, img_metas, gt_bboxes_ignore)
        losses.update(losses_pts)
    return losses

3 训练命令

python tools/train.py configs/centerpoint/centerpoint_0075voxel_second_secfpn_4x8_cyclic_20e_nus.py

4 运行结果​​​​​​​

【python三维深度学习】python三维点云从基础到深度学习_Coding的叶子的博客-CSDN博客_python点云拼接从三维点云基础知识到深度学习,将按照以下目录持续进行更新。更新完成的部分可以在三维点云专栏中查看。含数据与python源码。https://blog.csdn.net/suiyingy/article/details/124017716

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

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

相关文章

50 jhat 中 java.lang.String 的实例占用空间为什么是 28 bytes ?

前言 此问题是 多个 classloader 加载的同类限定名的Class 在 jhat 中显示不全d 同一时期发现的问题 大致的情况是 看到了 jhat 中统计的各个 oop 的占用空间 似乎是不太能够对的上 比如 java.lang.String, 在 64bit vm 上面 开启了 UseCompressedOops 之后, 应该是占用 …

Gram矩阵+Gram矩阵和协方差矩阵的关系

目录Gram矩阵简介协方差矩阵Gram矩阵 和 协方差矩阵的关系Gram Matrix代码Gram矩阵简介 gram矩阵是计算每个通道 i 的feature map与每个通道 j 的feature map 的内积 gram matrix的每个值可以说是代表 i 通道的feature map和 j 通道的 feature map的互相关程度。 参考博客 GAT…

小程序开发---02认识宿主环境

小程序依赖于微信提供宿主环境 小程序可以借助宿主环境提供的能力,可以完成许多普通网页无法完成的功能,如:微信扫码,微信支付,微信登录,定理定位,etc…等 小程序宿主环境包含以下内容&#xf…

关闭不同型号的 ESP 芯片的 ROM Code 上电启动日志的流程

【说明】 芯片 ROM Code 上电启动日志,不会对应用固件产生任何影响。通过 ROM Code 上电日志能够判断芯片启动模式是处于什么状态。若关闭此日志打印,当芯片进入下载模式或进入 Flash 启动模式等都不会有任何日志提示,不利于检查芯片状态&am…

操作系统学习笔记(V):设备管理

目录 1 设备 1.1 设备的概念 1.2 设备的分类 2 I/O控制器 2.1 I/O控制器 1.定义 2.功能 3.组成 2.2 I/O控制方式 1.程序直接控制方式 2.中断驱动方式 3.DMA方式 4.通道控制方式 5.对比 2.3 I/O软件层次结构 1.用户层软件 2.设备独立性软件 3.设备驱动程序 4…

Windows ssh免密访问Linux服务器

文章目录1.在Windows上生成公钥和私钥2.将公钥中的内容复制到linux服务器3.确认linux服务器开启了允许SSH免密登录4.确认免密登录配置成功ssh提供了安全的身份认证的策略,在免密登录之前,首先需要一对公钥和私钥。客户端拿着私钥,服务端拿着公…

【计算机网络】超详细——华为eNSP的安装教程

网络工程师小白或初次接触计算机网络的学生,网络相关的书本学习起来枯燥乏味,这时需要仿真模拟器来加深对网络知识的理解。目前提供网络仿真平台有cisco、华为等,若您英语基础薄弱建议选华为,英语阅读能力较强的直接上cisco的模拟…

redis我记不住的那些命令(五)

背景:我记不住那么多命令,又是Linux命令,又是Git命令,又是kubernetes的命令,又是maven命令,又是redis命令。所谓好记性不如烂笔头,记下来吧。 一、set集合 集合的特点是 无序且各不相同的元素…

SpringSecurity(二十二)--OAuth2:实现资源服务器(下)通过redis和缓存实现TokenStore

一、前言 本章将在前面几章基础上进行讲解,所以大家最好尽量先去看一下前几章的内容再来跟进会好很多。那么本章我们将通过redis和本地缓存Caffeine对JdbcTokenStore进行重写,并且讲解资源服务器配置的新方案,使得我们可以不用在资源服务器又…

[附源码]计算机毕业设计springboot校园疫情防范管理系统

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

LeetCode 337. 打家劫舍 III(C++)*

该题也是使用动态规划的思路,主要考虑根节点的最大金额和左右子节点的关系,其中分为两种情况:有该结点有没有偷钱,其次要遵守不报警原则。可得到状态转移方程: f为根节点被选中的最大,g为根节点没被选中的最…

Day17-购物车页面-结算-动态计算已勾选商品的数据和选中状态

1.动态渲染已勾选商品的总数量 我的操作: 1》在 store/cart.js 模块中,定义一个名称为 checkedCount 的 getters,用来统计已勾选商品的总数量: 2》在 my-settle 组件中,通过 mapGetters 辅助函数,将需要的…

[附源码]Python计算机毕业设计Django健身房信息管理

项目运行 环境配置: Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术: django python Vue 等等组成,B/S模式 pychram管理等等。 环境需要 1.运行环境:最好是python3.7.7,…

GIS工具maptalks开发手册(五)01-用JSON载入地图——json格式绘制多个面之基础版

GIS工具maptalks开发手册(五)01-用JSON载入地图——json格式绘制多个面之基础版 效果-json渲染图层基础版 代码 index.html <!DOCTYPE html> <html> <meta charset"UTF-8"> <meta name"viewport" content"widthdevice-width,…

HTML5期末考核大作业,网站——旅游景点。 学生旅行 游玩 主题住宿网页

&#x1f389;精彩专栏推荐&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业…

【网络层】流量控制VS拥塞控制、路由器功能、SDN控制平面

文章目录前言网络层功能流量控制VS拥塞控制拥塞控制路由器功能转发---硬件解决------数据平面---------处理数据各种转发路由选择---软件解决---控制平面----控制网络协议运行-------OSPF、RIP、BGP数据平面控制平面---路由选择传统方法-------每路由器法----------路由选择处理…

[附源码]计算机毕业设计疫苗及注射管理系统Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

Ubuntu20.04 通过deb包方式安装微信

写在前面 写文时间&#xff1a;2022.12.03 周六 自己的系统是Ubuntu20.04.5&#xff0c;安装的是 weixin_2.1.1_amd64.deb。 安装微信 从优麒麟官网下载微信deb安装包。 下载完成后&#xff0c;直接安装即可 sudo dpkg -i weixin_2.1.1_amd64.deb参考链接 [1] 优麒麟官网…

基于HFSS的线阵综合分析

摘要&#xff1a; 常规的阵列天线方向图综合是基于阵因子分析法&#xff0c;且不考虑单元之间电磁耦合的一种快速分析手段。本次推文则简单阐述一个基于HFSS的线阵综合实例。 HFSS中的直线阵 均匀直线阵的基础知识已在前面的推文中进行了多次阐述举例&#xff0c;这里就不赘…

正则表达式中的元字符,量词:贪婪和非贪婪,转义符: \s: 记得使用-z --null-data: 使用ascii码中空字符来替换新行,分组:““,和‘‘

正则表达式的所有内容&#xff1a;&#xff08;每一个解释下面都带一个样例&#xff09; 1.元字符 \&#xff1a;忽略后面一个字符的特殊含义 [a-b]&#xff1a;对a到b之间的任何字符进行匹配 ^&#xff1a;在每行的开始进行匹配 $ &#xff1a;在每行的末尾进行匹配 . .&…