想象你是一位大型仓库的理货员,面前散落着几千个快递包裹,每个包裹上都印着空间坐标和面单反光强度。这些包裹有的堆在一起,有的零散分布在角落,形状大小各不相同。现在客户要求你立刻找出哪些包裹属于同一订单,并在仓库俯视图中圈出来——这就像激光雷达点云中的 3D 目标检测。PointPillars 的做法非常巧妙:你在地上铺一层网格纸,把每个格子想象成一口垂直的“邮筒”,散落的包裹先滑进对应的邮筒;接着给每个邮筒写一份“住户清单”,统计每个包裹相对筒心和仓库中心的位置;再把整个仓库变成一张可以快速扫描的“俯视图”,最后用一台高速扫描仪(2D 卷积网络)在地图上框出每单货。整个过程避开昂贵的三维卷积,却能在自动驾驶场景中实时稳定地检测车辆、行人和骑行者。本文将带你从零看懂这张“网格纸-邮筒-扫描仪”图景背后的算法细节。
对 AI 从业者的职业价值:PointPillars 是自动驾驶和机器人实时 3D 感知的经典基线,掌握它等于掌握“稀疏数据结构化 + 高效部署”的关键技能,能让你快速上手工业级点云检测项目,而不是只会在 demo 里跑模型。
可视化演示
动态演示PointPillars点云的核心机制,通过采集/分析/决策/反馈四种模式展示关键概念与交互流程。
本节配有交互动效(进入视口后自动加载,约 3KB)。
PointPillars点云:Poin PointPillars设计理 Pillar柱体编码与点特征提 核心机制可视化 PointPillars点云整体架构与关键组件
任务与难点
假如你是仓库理货员,面前的地面就像一个巨大的点云:几千个包裹散乱分布,有些挤在一团,有些相隔很远,你无法一眼看清几米外的东西是什么形状。如果挨个翻找,效率极低;如果先按三维立方体重新堆垛,又会浪费大量时间和空间。这正是点云 3D 目标检测的第一道坎——数据本身无序、稀疏且规模巨大。
PointPillars 要处理的是激光雷达点云,每帧通常包含数万到十几万个点,每个点有三维坐标和反射强度。点云不像图像那样有规整的像素排列,所以不能直接套用 2D 卷积。3D 目标检测必须从这些点中推断出物体的中心位置、长宽高和朝向角,形成一个“三维框”。
传统做法之一是体素法:把空间切成一个个小立方体,再用 3D 卷积处理。可 3D 卷积计算量极大,在空旷地区大量网格是空的,白白浪费算力。PointPillars 的核心思路是:不把空间切成三维方块,而是在 X-Y 平面上划分二维网格,让每个网格在垂直方向无限延伸,从而把“逐点处理”限制在垂直柱体内,再转成 2D 伪图像,彻底绕开昂贵的 3D 卷积。
无论用哪种方法,最终输出的都是一个七元组,它就像订单规格一样,告诉理货员应该圈出多大的方框:
小结一下:理货员要先知道订单长什么样(3D 框参数),之后才谈得上整理包裹。任务明确了,接下来就是如何用“网格纸”高效组织这些散落包裹。
- 中心坐标 \((x, y, z)\)物体在三维空间中的几何中心,是检测框的定位基础。
- 三维尺寸 \((w, l, h)\)分别表示宽度、长度和高度,用来框住车辆、行人等实际外型。
- 朝向角 \(\theta\)物体绕竖直轴的航向角,例如车头所指方向。
柱体采样
理货员在地上铺一张网格纸,每个格子垂直向上拉成一个没有顶盖的“邮筒”。包裹无论多高都能放进去,而地面上的位置决定了它进入哪个邮筒。这个动作在 PointPillars 中叫做柱体化:只在 X-Y 平面划分网格,每个网格单元对应一根贯穿整个高度范围的柱体(Pillar)。
点云中的每个点,根据它的 \(x\) 和 \(y\) 坐标,就能确定它属于哪个柱体。因为柱体在垂直方向不做切分,所以不需要维护三维索引,也不需要关心 z 轴边界;高度信息则通过后续点特征中的 z 坐标继续保留。这一步把无序的三维点云变成了“带二维位置标签”的点集合。
不过激光雷达点云密度极不均匀,近处可能一平方米有几百个点,远处可能一个点也没有。PointPillars 采用动态柱状采样:一帧最多保留 \(P\) 个非空柱体(例如 12000 个),每个柱体最多保留 \(T\) 个点(例如 100 个),超出部分直接丢弃。这样既避免极端帧点数过多导致计算爆炸,也让输入形状固定,方便 GPU 批量处理。
某个点究竟进入哪个邮筒,可以用下面的公式表达:
网格纸铺好以后,每个邮筒里都有若干包裹。下一件事,就是给每个邮筒填写一张能反映包裹相对关系的“住户清单”。
- 二维网格索引 \(i, j\)表示点在 X-Y 平面上的第几行第几列,决定它进入哪个邮筒。
- 坐标范围 \(x_{\min}, y_{\min}\)预先指定的检测区域左下角,用来对坐标做偏移。
- 柱体边长 \(d\)网格分辨率,比如 0.16 米;数值越小,空间细节越丰富,但伪图像尺寸也会变大。
- 向下取整 \(\lfloor \cdot \rfloor\)将连续坐标离散成整数格子编号。
特征编码
理货员给邮筒写清单时,不会只记录包裹的绝对位置,还会记下它离邮筒中心有多远、离整个仓库中心有多远。这样就能快速判断同一个小区域里包裹之间的相对关系,也能知道这个区域在整片仓库中的大致位置。
PointPillars 对柱体中的每个点构造一个 9 维特征向量:先取原始坐标 \(x, y, z\) 和反射强度 \(r\),再加上该点相对整帧点云中心的偏移 \((x_c, y_c, z_c)\),以及相对所在柱体中心的偏移 \((x_p, y_p)\)。因为柱体没有在 z 轴上切分,所以高度方向的 z 坐标仍然完整保留了下来。
得到 9 维输入后,PointPillars 用一个共享的全连接网络(PointNet 的简化版)把每个点映射成 64 维特征,再在同一个柱体内对所有点做最大池化,得到该柱体的特征向量。最大池化不关心柱体内点的数量,也不要求点有固定顺序,天然适合无序点云。
这一过程可以写成:
每个邮筒的住户清单写好了,整片仓库就被压缩成一张表格。下一步,把这些清单按邮筒位置放回网格,铺成一张可以快速浏览的俯视地图。
- 原始点属性 \((x_i, y_i, z_i, r_i)\)点的三维坐标和激光雷达反射强度,是所有特征的基础。
- 云中心偏移 \((x_i^c, y_i^c, z_i^c)\)该点相对整帧点云平均位置的偏移,让网络感知全局上下文。
- 柱心偏移 \((x_i^p, y_i^p)\)该点相对所在柱体中心的水平偏移,用来描述柱内局部相对位置。
- 逐点映射与最大池化每个点通过 PointNet 升维,再在同一柱体内逐通道取最大值,得到柱特征向量。
骨干网络
理货员把每一份住户清单贴回对应的网格位置,每个格子只保留一张汇总卡片,整片仓库就变成了一张“俯视地图”。地图上每个格子不再是一堆散乱包裹,而是一串浓缩后的统计特征。
在 PointPillars 中,这一步叫做 Scatter(散列):把每个非空柱体的特征向量,按它的网格坐标写入一个二维数组的对应位置。空柱体位置补零。最终得到形状为 \(H \times W \times C\) 的伪图像,其中 C 是柱特征维度,比如 64。它被称为“伪图像”,是因为它看起来像一张二维图,但每个“像素”实际是一个特征向量,而不是颜色值。
有了规整的伪图像,就可以直接使用成熟的 2D 卷积骨干网络。PointPillars 采用类似 VGG 的多个 2D 卷积模块,逐层下采样并增加通道数,生成多尺度特征图。这些多尺度特征随后融合,交给检测头。2D 卷积在 GPU 上的优化程度远高于稀疏 3D 卷积,这也是 PointPillars 速度快的重要原因。
伪图像的生成过程可以理解为:
俯视地图铺好以后,高速扫描仪终于可以上场。它会在图上迅速移动,遇到可疑区域就画出一个线框,并标注这是“车”还是“人”。
- 伪图像张量 \(\mathbf{A}\)形状为 \(H \times W \times C\) 的二维网格,每个网格单元是一个 C 维向量。
- 柱特征 \(\mathbf{f}_k\)由一个非空柱体聚合得到的特征向量,被写入对应格子的通道维。
- 空柱补零 \(\mathbf{0}\)没有点的格子统一用零向量,保证输入形状固定。
检测头
扫描仪在地图上移动时,每看到一个像订单的区域,就画一个红色线框,同时记录这单货的种类、大小和朝向。PointPillars 使用类似 SSD 的检测头:在 2D 特征图的每个位置放置若干锚框,每个锚框负责预测物体类别、3D 框参数和方向类别。
由于伪图像来自鸟瞰视角,检测头主要在 X-Y 平面上做密集预测。对于每一个锚框,网络输出相对锚框的修正量,比如中心坐标差值、尺寸对数差和朝向角差值。这些修正量能让网络不必从零回归绝对坐标,降低学习难度。
为了让角度回归更稳定,PointPillars 还额外引入方向分类。比如 0° 和 180° 在数值上相差很小,但车头方向完全相反;直接回归角度很容易在周期边界处产生突变。方向分类先把角度分成几个区间,再配合正弦差回归,让网络更清楚地判断物体的朝向。
中心修正的核心公式如下:
扫描仪画出的线框不一定准确。为了让理货员越画越准,还需要一套“罚单机制”,让网络在训练中不断纠正错误。
- 中心坐标修正 \(\Delta x, \Delta y, \Delta z\)预测值相对锚框中心的差值,并除以锚框尺寸做归一化。
- 锚框尺寸 \(d_a, h_a\)用锚框的宽度和高度来归一化中心偏移,让回归目标落在稳定范围内。
- 角度修正 \(\Delta \theta\)用两角差的正弦值表示朝向偏差,避免角度周期性带来的梯度跳变。
损失与训练
新手理货员总把线框画歪,师傅于是用三种罚单帮他纠错:认错类别、框没对齐、朝向反了。PointPillars 的总损失也由三部分组成:分类损失、3D 框回归损失和方向分类损失。
分类损失使用 Focal Loss。3D 空间中大部分区域是背景,正样本锚框远少于负样本锚框,Focal Loss 会降低大量简单负样本的权重,让网络把注意力集中在真正困难的样本上。回归损失使用 SmoothL1 Loss,对中心、尺寸和角度修正量做平滑约束。方向分类损失则是一个简单的交叉熵损失,让网络判断物体属于哪个朝向区间。
训练时还会配合数据增强:随机翻转、全局旋转、点云平移和缩放等,让网络见过更多样的姿态和位置。优化器常用 Adam,配合学习率衰减策略。整体训练目标是让三种罚单的总和最小:
三类罚单共同作用下,理货员越来越熟练。可现实中的传送带越跑越快,光会画框还不够,还必须画得足够快。
- 正样本数 \(N_{pos}\)与真实框匹配的锚框数量,用它做平均,避免正样本过少时损失被负样本淹没。
- 分类损失 \(\mathcal{L}_{cls}\)Focal Loss,重点惩罚难分的正样本和困难负样本。
- 回归损失 \(\mathcal{L}_{reg}\)SmoothL1,约束 3D 框的七个参数。
- 方向损失 \(\mathcal{L}_{dir}\)分类角度所属的方向区间,配合角度回归使用。
- 平衡系数 \(\alpha, \beta\)控制回归和方向损失相对分类损失的重要性。
部署与优化
传送带在加速,理货员不能慢慢翻清单。PointPillars 的实时性来自两个设计:一是用“柱体化 + 伪图像 + 2D 卷积”绕过 3D 卷积;二是通过柱体采样,把每帧计算量限制在可控范围内。论文中在单张强劲 GPU 上可以跑到约 62 FPS,远快于早期的 VoxelNet。
在边缘设备上部署时,还可以进一步优化:把模型转换成 TensorRT 或 ONNX,使用 FP16 半精度甚至 INT8 量化推理;调整检测范围与柱体尺寸,减少伪图像尺寸;优化 scatter 操作的 CUDA 内核;剪枝冗余卷积通道;对每帧动态限制点云范围,避开远处无效点。目标是尽量让计算量只依赖“有效点”,而不是固定大小的空间网格。
从工程角度看,一帧点云的处理时间可以拆成几段,哪段最慢就先优化哪段:
优化就像缩短理货员每个动作的时间:哪一步慢就改哪一步。最终,即使传送带速度越来越快,PointPillars 依然能稳稳地接住每一帧点云。
- 总延迟 \(T_{\text{total}}\)一帧点云从输入到输出全部 3D 框所需的时间。
- 柱状编码耗时 \(T_{\text{pillar}}\)点特征升维、柱内聚合、伪图像散列的时间。
- 骨干网络耗时 \(T_{\text{backbone}}\)2D 卷积在多尺度特征上提取信息的时间。
- 检测头耗时 \(T_{\text{head}}\)分类、回归、方向判决等检测头计算的时间。
AI 应用场景
场景1:自动驾驶实时3D检测
阶段:环境感知 / 3D目标检测
解决的问题:L4 级自动驾驶中,激光雷达点云密度高、场景变化快,传统 3D 卷积端到端推理延迟高。PointPillars 将点云柱化后转为伪图像,用 2D 卷积高效处理,能实时检测车辆、行人和骑行者。
具体案例:某自动驾驶公司使用 128 线激光雷达,点云频率 10Hz。引入 PointPillars 后,在车载域控器上单帧 3D 检测延迟约 15ms,雨天仍能稳定框出 70 米内的车辆;相比此前基于体素的方案,延迟降低了约 60%。
场景2:港口无人集卡与矿区卡车
阶段:定位与障碍物感知
解决的问题:港口和矿区扬尘大,摄像头成像容易受影响,需要激光雷达在嵌入式工控机上完成近距离障碍物检测。PointPillars 的柱状采样能严格控制点云规模,2D 卷积便于部署到 TensorRT。
具体案例:某港口无人集卡在雨雾天气下,使用固态激光雷达搭配 PointPillars,检测 5 到 50 米范围内的集装箱和人员;FP16 推理在边缘计算模块上达到约 20ms 每帧,满足低速运行的安全要求。
场景3:路侧感知设备
阶段:车路协同感知
解决的问题:路侧杆装设备算力有限,却需要在路口对行人、车辆做实时 3D 位置告警。PointPillars 不用 3D 卷积,伪图像可以进一步量化编码,很适合部署在路侧工控机上。
具体案例:某智慧交通项目在路口部署 80 线激光雷达,用 PointPillars 检测过街行人和转弯车辆,单帧处理在商用 GPU 上约 25ms,误检率低于可接受阈值,辅助边缘计算单元向过往车辆下发预警。
Python 演示
import numpy as np np.random.seed(42) # 生成模拟激光雷达点云: N x 4 (x,y,z,intensity)def simulate_points(n=5000): obj1 = np.column_stack([ np.random.normal(5, 0.2, n // 2), np.random.normal(0, 0.2, n // 2), np.random.normal(-1, 0.1, n // 2), np.random.uniform(0.2, 0.8, n // 2) ]) obj2 = np.column_stack([ np.random.normal(-4, 0.3, n // 2), np.random.normal(3, 0.3, n // 2), np.random.normal(0.5, 0.2, n // 2), np.random.uniform(0.1, 0.6, n // 2) ]) return np.vstack([obj1, obj2]) def build_pseudo_image(points, grid_range, pillar_size, max_points=100, feature_dim=64): x_min, x_max, y_min, y_max = grid_range d = pillar_size nx = int((x_max - x_min) / d) ny = int((y_max - y_min) / d) # 1. 计算每个点所属柱体 col = ((points[:, 0] - x_min) / d).astype(int) row = ((points[:, 1] - y_min) / d).astype(int) mask = (col >= 0) & (col < nx) & (row >= 0) & (row < ny) valid = points[mask] col, row = col[mask], row[mask] # 2. 构造9维点特征: 原始坐标 + 云中心偏移 + 柱心偏移 cloud_center = valid[:, :3].mean(axis=0) pillar_center = np.stack([ x_min + (col + 0.5) * d, y_min + (row + 0.5) * d, np.zeros_like(valid[:, 0]) ], axis=1) feat = np.concatenate([ valid, valid[:, :3] - cloud_center, valid[:, :3] - pillar_center ], axis=1) # 3. 按柱体排序,便于后续按柱处理 order = np.argsort(row * nx + col, kind='stable') feat = feat[order] col, row = col[order], row[order] cell_id = row * nx + col # 4. 简单PointNet式编码: 线性层 + ReLU + 柱内最大池化 rand_w = np.random.randn(feat.shape[1], feature_dim).astype(np.float32) * 0.1 rand_b = np.random.randn(feature_dim).astype(np.float32) * 0.1 encoded = np.maximum(feat @ rand_w + rand_b, 0.0) # 5. 按柱体聚合得到伪图像 pseudo = np.zeros((ny, nx, feature_dim), dtype=np.float32) for cid in np.unique(cell_id): r, c = divmod(int(cid), nx) in_pillar = encoded[cell_id == cid][:max_points] pseudo[r, c] = in_pillar.max(axis=0) return pseudo if __name__ == "__main__": points = simulate_points() pseudo = build_pseudo_image(points, [-20, 20, -20, 20], 0.4) print("点云点数:", len(points)) print("伪图像尺寸:", pseudo.shape) occupied = int(np.count_nonzero(pseudo.any(axis=2))) print("非空柱体数:", occupied)
col = ((points[:, 0] - x_min) / d).astype(int)计算每个点落在第几列柱体。valid[:, :3] - cloud_center计算每个点相对整帧云中心的坐标偏移。valid[:, :3] - pillar_center计算每个点相对所在柱体中心的坐标偏移。feat = np.concatenate([valid, valid[:, :3] - cloud_center, valid[:, :3] - pillar_center], axis=1)拼接原始坐标、质心偏移和柱心偏移,生成 9 维点特征。cell_id = row * nx + col将二维网格位置转成一维唯一编号,方便按柱体聚合。encoded = np.maximum(feat @ rand_w + rand_b, 0.0)用共享线性层和 ReLU 模拟 PointNet 的逐点编码。pseudo[r, c] = in_pillar.max(axis=0)在柱内做最大池化,并把结果散列到伪图像对应位置。
常见误区
误区PointPillars 不就是把空间切成小方块体素吗?每个 pillar 是有高度限制的三维立方体。
正解实际上 Pillar 只在 X-Y 平面划分网格,垂直方向不切分,所以高度可以贯穿整个点云范围。它不像三维体素那样需要维护第三维索引,因此在存储和索引上更简单,同时也保留了 z 方向信息。
为何常见:很多点云方法都叫“体素法”,术语相近,网络结构图又常把柱体画成立方块,容易让人误以为它和 Voxel 是同一回事。
误区PointPillars 生成的伪图像,就是把点云从上往下投影成一张反射强度灰度图。
正解伪图像的每个“像素”是一个经过 PointNet 编码和最大池化后得到的多通道特征向量,不是简单的强度投影。它更像是一张浓缩了柱内点云语义信息的特征图,只是形状上像二维图像。
为何常见:伪图像和鸟瞰图都是从上往下看的二维网格,视觉上很相似,初学者容易混淆“几何投影”和“特征散列”的区别。
误区既然最终都转成伪图像并交给 2D 卷积了,那就已经是稠密计算,不需要稀疏技巧。
正解PointPillars 在伪图像生成前会限制最大非空柱体数和每柱点数,避免极端帧点云过多导致编码端耗时爆炸。虽然空柱体能作为零向量参与 2D 卷积,但柱体数量过多仍会带来明显的内存和计算开销。
为何常见:看到网络主体是 2D 卷积后,会忽略编码端的稀疏采样设计,而这些设计恰恰是实时性的关键。
误区检测头已经回归了朝向角 theta,再输出方向分类完全是多余的。
正解角度回归存在周期性问题,0° 和 180° 数值上很接近但朝向完全相反,直接回归容易在边界处出错。PointPillars 额外加入方向分类,把角度分成若干区间来消除歧义,能明显提升朝向估计精度。
为何常见:2D 目标检测不需要输出航向角,习惯了 2D 框的工程师很容易忽略角度回归的多值问题。
误区邮筒里的包裹越多,信息就越丰富,不应该限制每柱点数。
正解PointPillars 会对每柱点数设上限(如 100 个),超出部分丢弃。点太多会加大逐点编码的计算量,而且激光雷达点云近密远疏,不限制会造成模型对近处物体过度偏置。固定点数也能让输入形状稳定,方便批量计算。
为何常见:直觉上信息无损最好,但实际工程中必须平衡计算效率、样本均衡和硬件批处理要求。
面试题
Q1. PointPillars 将三维点云转换为可供 2D 卷积处理的伪图像,关键在于把点云组织成什么?
- A.高度不限的垂直柱体← 正确答案
- B.固定大小的三维体素
- C.距离视角的深度图
- D.稀疏的八叉树节点
答案:A。PointPillars 主要在 X-Y 平面上划分网格,每个网格单元在垂直方向无限延伸,因此核心组织方式是“垂直柱体”。三维体素、深度图和八叉树都不是 PointPillars 的核心设计。
Q2. 在柱体采样中,PointPillars 控制计算开销的主要手段是什么?
- A.将所有非空柱和柱内点分别限制上限← 正确答案
- B.对所有点做全局随机降采样
- C.只保留距离原点最近的点
- D.使用 KNN 删除冗余点
答案:A。PointPillars 同时限制最大非空柱体数和每柱最多点数,而不是简单地对全图随机降采样或只保留近处点,这样既控制计算量又保持空间覆盖。
Q3. PointPillars 点特征向量中,通常不会包含以下哪一项?
- A.点到云中心的坐标偏移
- B.点到柱体中心的坐标偏移
- C.点所属物体的类别标签← 正确答案
- D.点的反射强度值
答案:C。输入特征由原始坐标、反射强度、云中心偏移和柱心偏移构成。物体类别是训练时使用的监督标签,不是输入特征。
Q4. PointPillars 中对每个柱体的点云特征进行聚合时,采用哪种操作?
- A.按通道最大池化← 正确答案
- B.按通道平均池化
- C.加权求和池化
- D.双向循环网络
答案:A。PointPillars 使用最大池化对柱内所有点的编码特征逐通道取最大值。最大池化对无序点云和可变点数都很稳定,平均池化或加权求和会削弱显著特征。
Q5. 下面哪些是 PointPillars 检测头需要预测的内容?
- A.物体中心坐标← 正确答案
- B.三维尺寸← 正确答案
- C.航向夹角← 正确答案
- D.点云反射率
答案:ABC。3D 检测头需要输出物体中心、长宽高和航向角,最终组成 3D 框。点云反射率是输入特征,不是检测头的预测目标。
Q6. PointPillars 比纯 3D 体素方法更快,主要原因是什么?
- A.用 2D 卷积替代 3D 卷积← 正确答案
- B.免除了所有卷积层
- C.用随机森林替代神经网络
- D.大幅减小了输入点云规模
答案:A。PointPillars 的核心贡献是把点云编码成伪图像,从而用高效成熟的 2D 卷积代替昂贵的 3D 卷积。它仍然使用了卷积网络,也没有大幅降低点云规模。
Q7. 关于 PointPillars 伪图像,下列说法正确的是?
- A.每个非空柱的特征被散落到网格对应位置← 正确答案
- B.空柱位置会被填充随机的噪声值
- C.伪图像不能使用 2D 卷积处理
- D.伪图像等同于三通道彩色图像
答案:A。柱特征会通过 Scatter 操作写入伪图像对应格子的通道维,空柱位置填零。伪图像是多通道特征图,不是普通 RGB 图像,天然适合 2D 卷积。
Q8. PointPillars 训练中可能使用的损失函数包括哪些?
- A.分类损失← 正确答案
- B.3D 框回归损失← 正确答案
- C.方向分类损失← 正确答案
- D.对抗生成损失
答案:ABC。PointPillars 总损失包含分类损失、3D 框回归损失和方向分类损失。对抗生成损失属于生成模型,不是 PointPillars 检测任务的一部分。
Q9. 为了使 3D 框朝向回归稳定,PointPillars 还会在检测头中额外输出什么?
- A.方向分类← 正确答案
- B.距离分类
- C.类别特征向量
- D.点密度回归
答案:A。角度回归存在周期歧义,0° 和 180° 数值接近但朝向相反。PointPillars 用方向分类来消除这种歧义,让模型更稳定地判断航向角。
Q10. 在边缘设备部署 PointPillars 时,下面哪些优化是可行的?
- A.TensorRT 半精度推理← 正确答案
- B.降低伪图像分辨率← 正确答案
- C.限制柱体与点数上限← 正确答案
- D.去掉全部输出检测头
答案:ABC。TensorRT/FP16 能加速推理,降低伪图像分辨率能减少计算量,限制柱体和点数能控制编码开销。去掉输出检测头会导致模型无法输出 3D 框,不是可行优化。