点云算法整理与常用计算模块:从数据到模型,再到工程与量化

在接触智能驾驶算法之前,对"感知"的理解往往更多来自图像世界:图像是规则的二维网格,像素密集、连续,卷积网络天然适配。

而当真正进入 3D 感知、多传感器融合、BEV 表达以及工程落地之后,点云成了一个绕不开的核心对象,也成了很多复杂问题的源头。

本文梳理了从「会用点云模型」到「逐步理解点云数据、算法结构与工程落地」这一阶段的点云算法认知。希望读完后,能形成一张清晰可复用的点云算法认知地图:点云是什么、为什么难、主流路线怎么选、模块怎么串、工程和量化哪里最容易翻车。


1. 点云是什么?先把"数据本身"讲清楚

1.1 点云的本质:三维世界的离散采样

点云(Point Cloud)可以看成:

一组在 3D 空间中的离散点,用来刻画真实世界的几何结构。

在自动驾驶里,点云主要来自 LiDAR。每个点至少包含:

  • x, y, z:三维坐标(在某个坐标系下)

常见还会带:

  • intensity(反射强度)
  • timestamp(时间戳/相位)
  • ring(激光线号)

工程里最常见的张量形状是:

复制代码
[N, C]  (例如 [N, 4]:x,y,z,intensity)

N 是点的数量,且 N 每帧都可能变化。

1.2 点云 vs 图像:不是"稀疏图像",而是另一种数据范式

这是理解点云算法的第一道坎。

维度 图像 点云
数据结构 规则网格 (H×W×C) 无序点集 (N×C)
密度 高且均匀 稀疏且不均
连续性 强 弱
空白区域 背景也有意义 大量"什么都没有"
关键难点 表达纹理/语义 表达几何/结构

一句话总结:图像是规则空间上的信号,点云是不规则空间中的几何采样。因此 CNN 不能直接"吃"原始点云。

1.3 点云在自动驾驶里为什么重要?

它天然提供:

  • 真实深度(不是估计出来的)
  • 高精度几何结构(距离、尺寸、形状)
  • 对光照不敏感

很多系统的分工逐渐变成:

  • 图像:语义/纹理/类别
  • 点云:几何/距离/空间结构
  • BEV:统一的空间中间表示(融合/检测都方便)

2. 点云算法到底在做什么?------核心矛盾与第一步"结构化"

点云算法的根本矛盾只有一个:

不规则、稀疏、动态点数的点集,如何变成规则、可计算、可部署的结构?

所以点云网络最关键的不是"backbone 多深",而是最开始那几步:

  • 点怎么分桶(voxel/pillar)
  • 同一个桶里点怎么聚合
  • 聚合后的特征怎么回到 BEV 网格

可以把点云 pipeline 粗暴理解成:

复制代码
点云(无序) → 结构化(有序) → BEV(规则网格) → 2D 检测头

3. 三条主流路线:Point / Voxel / Pillar(先建立全景图)

3.1 Point-based:直接处理点(PointNet 系)

  • 思路:对每个点做 MLP + 聚合
  • 优点:概念直观,保留几何细节
  • 缺点:点数大时很吃算力,工程落地难
  • 在自动驾驶主流 3D 检测里用得不算多(更多出现在局部模块或研究里)

3.2 Voxel-based:体素化(VoxelNet / SparseConv)

思路:把 XYZ 切成三维网格(体素 voxel),体素内聚合点,形成稀疏 3D 特征,再做 3D / Sparse 计算。

典型信息流:

复制代码
点云 → XYZ voxelize → voxel feature → 3D Conv / SparseConv → 沿 Z collapse → BEV
  • 优点:高度信息被显式建模,表达能力强
  • 代价:3D / 稀疏算子复杂,动态稀疏结构对部署要求高

3.3 Pillar-based:PointPillars(工程常用)

思路:只在 XY 平面划网格,Z 不切层,一个柱子覆盖整根高度。柱内点做 PointNet/MLP 聚合,再直接 scatter 到 BEV。

典型信息流:

复制代码
点云 → XY pillarize → pillar feature → scatter → BEV → 2D backbone
  • 优点:避免 3D 卷积,2D 友好,工程效率高
  • 代价:高度结构没有显式网格,只能靠"隐式编码进通道"

4. 认知分水岭:scatter → BEV vs collapse → BEV(必须讲透)

4.1 scatter → BEV(PointPillars)

  • 不建立 Z 维网格
  • 同一 XY 位置的所有高度信息,最终被压进一个 pillar embedding
  • 高度关系是隐式的(点的 z/统计量进入通道)
  • 得到的是原生 2D 的 BEV

4.2 collapse → BEV(VoxelNet / SparseConv)

  • Z 维被切成层(体素高度层)
  • 先在 3D 空间里学习"上下(高度)结构"
  • 再沿 Z 折叠成 BEV(sum/max/learned collapse)
  • 得到的是"压扁后的 3D"

4.3 一句话总结

scatter 是"先放弃高度,再用网络弥补";collapse 是"先理解高度,再做信息压缩"。

为什么这影响精度?因为复杂场景里同一 XY 位置可能出现多层结构(桥下/车顶/地面等)。"高度结构"建模得越早、越显式,模型越容易学对。


5. CenterPoint 到底是什么?它在体系里扮演什么角色?

很多人把 CenterPoint 当作"点云网络",其实更准确地说:

CenterPoint 是 BEV 上的检测范式(head 思想),不是点云编码方式。

它做的事是:

  • 在 BEV 上预测中心点 heatmap
  • 回归尺寸、方向、速度等属性

它前面接什么都可以:

  • PointPillars 输出的 BEV
  • VoxelNet/SparseConv collapse 后的 BEV

所以应该这样理解组织关系:

复制代码
(点云编码方式:Pillars / Voxels / Sparse) → BEV feature → (检测范式:CenterPoint head)

6. 常用计算模块地图:从点到 BEV 的关键桥梁

下面这几类模块,在阅读任何点云工程代码时都会反复遇到。

6.1 Voxelization / Pillarization(分桶)

关键超参:

  • 点云范围(x_min..x_max 等)
  • voxel/pillar size(网格分辨率)
  • 每格最大点数(max_points_per_voxel)
  • 最大 voxel 数(max_voxels)

它们直接决定:精度、速度、内存三者取舍。

6.2 Pillar/Voxel Feature Encoder(桶内聚合)

常见做法:

  • 对点做相对坐标(相对 pillar 中心/均值)
  • 拼接强度、距离等
  • MLP + max/mean 聚合

很多实现的本质就是:一个轻量版 PointNet。

6.3 Scatter / BEV Pooling(稀疏 → 稠密)

这一步决定了能否"像 2D 一样做检测"。

  • 输入:M, C 的稀疏桶特征 + 坐标
  • 输出:B, C, H, W 的 BEV 伪图像

这也是工程和量化最容易翻车的模块。


7. 重头戏:PointPillarsScatter 两种写法(原始实现 vs 优化实现)

在 PointPillars 中,Scatter 是一个工程分水岭模块。算法上它只做一件事:把稀疏 pillar 特征铺回规则 BEV 画布。

7.1 输入输出先讲明白

  • voxel_features: M, C(全 batch 的 pillar 拼接)
  • coors: M, 4,常见 batch_id, z, y, x
  • 输出:canvas: B, C, H, W

7.2 原始直观实现:手写 scatter(容易理解,但工程不友好)

python 复制代码
import torch
import torch.nn as nn
from typing import List

class NaivePointPillarsScatter(nn.Module):
    def __init__(self, num_input_features: int, output_shape: List[int]):
        super().__init__()
        self.nchannels = num_input_features
        self.ny = int(output_shape[0]) # H
        self.nx = int(output_shape[1]) # W

    def forward(self, voxel_features: torch.Tensor, coors: torch.Tensor, batch_size: int):
        H, W = self.ny, self.nx
        C = self.nchannels

        # flat_index = b*(H*W) + y*W + x
        flat_indices = coors[:, 0] * (H * W) + coors[:, 2] * W + coors[:, 3]
        flat_indices = flat_indices.to(torch.long)

        # flat canvas: [B*H*W, C]
        canvas = torch.zeros(
            batch_size * H * W,
            C,
            dtype=voxel_features.dtype,
            device=voxel_features.device,
        )

        canvas[flat_indices] = voxel_features

        # -> [B, C, H, W]
        canvas = canvas.view(batch_size, H, W, C).permute(0, 3, 1, 2).contiguous()
        return canvas

7.3 为什么原始实现工程代价很高?

  • BHW*C 巨大,但绝大多数格子是空的(全 0)
  • canvasindices = ... 是典型不规则写入(高级索引/scatter),对很多平台不友好
  • 会引入大中间张量、动态图不稳定
  • 量化时 observer 统计容易被稀疏零分布拖偏

原始写法适合帮助理解,最终落地通常要"算子化"。

7.4 工程优化实现:算子化 point_pillars_scatter(推荐)

项目推荐使用地平线内部实现(加速了)作为"工程最佳实践",使用示例如下:

python 复制代码
import torch
import torch.nn as nn
from horizon_plugin_pytorch.nn.functional import point_pillars_scatter

class Net(nn.Module):
    def __init__(self, num_input_features, output_shape) -> None:
        super().__init__()
        self.nchannels = num_input_features
        self.nx = output_shape[1]
        self.ny = output_shape[0]

    def forward(self, voxel_features, coords, batch_size):
        out_shape = (batch_size, self.nchannels, self.ny, self.nx)
        batch_canvas = point_pillars_scatter(
            voxel_features, coords, out_shape)

        return batch_canvas

优势不是"代码更短",而是:

  • 避免 Python 层不规则 scatter
  • 形状更稳定、更利于图编译
  • 更适配芯片与量化策略(算子边界清晰)

8. 芯片落地:点云模型真正难在哪?

从工程落地角度,难点通常不在卷积,而在:

  • 索引密集:scatter / gather / pooling
  • 动态稀疏结构:每帧点数、桶数变化
  • 大空间画布:H×W 很大但有效点很少
  • 稀疏算子支持:SparseConv 往往受限于平台能力

这也是为什么很多边缘平台更偏好:

PointPillars + 2D backbone + CenterPoint head,而不是全套 SparseConv。


9. 量化:点云模型为什么更容易"炸"?

点云模型量化的难点通常来自:

9.1 分布极端

  • 空桶很多(大量 0)
  • 少数桶点数很高
  • 少数位置特征幅值很大

这会导致 scale 被极端值拉爆,有效精度下降。

9.2 索引 + 数值混合

Scatter/Pooling 里常见"索引控制数据流",量化边界放错容易出怪问题。

9.3 信息被压得太早

如果高度信息过早被压缩(或被量化误差污染),后续 backbone 再强也补不回来。

工程建议:

  • 先验证浮点中间量分布:pillar 数、稀疏率、Z 分布
  • 再决定哪些模块保持高精度 / 哪些模块量化
  • 对 scatter/pooling 这类模块谨慎设置量化边界
  • 尽量使用平台已优化算子替代手写索引逻辑

10. 结语:点云算法不是"更复杂的 CNN"

点云算法的复杂,不在网络结构,而在"把不规则三维数据变成规则表示"的整条链路。理解 scatter vs collapse,理解桥梁模块(voxel/pillar/scatter/pooling)在何处丢信息、何处放大误差,才算真正开始"看懂点云"。

相关推荐
地平线开发者24 分钟前
点云算法整理与常用计算模块:从数据到模型,再到工程与量化
算法·自动驾驶
陈嘿萌5 天前
ECCV 2026 | CausalDrive:澳门大学×小米汽车,面向自动驾驶的实时因果世界模型
图像处理·人工智能·深度学习·计算机视觉·自动驾驶·学术研究与理论基础
亚远景aspice6 天前
亚远景 - 无方向盘 L4 车辆批量认证,ASPICE 过程证据成制造商安全举证底座
安全·自动驾驶·aspice·研发管理·亚远景科技·过程能力评估·aspice评估
地平线开发者7 天前
CLIP 的训练机制:从对比学习到图文对齐
深度学习·算法·自动驾驶
wdf808810 天前
重型车辆、矿山装备、汽车研发、CAE、自动驾驶和沃尔沃重型车辆研发工作站配置与本地AI部署指南
人工智能·自动驾驶·cfd·creo机械设计
论文复现现场11 天前
BEVFormer训练需要几张GPU?2张A100 80GB够不够,显存与云GPU成本分析
pytorch·自动驾驶·a100·bevformer
地平线开发者12 天前
QAT 实战:从 PyTorch 模型到 J6E 实板精度与延时验证
pytorch·算法·自动驾驶
AiNightVision12 天前
星光级 是什么?——星光级摄像机是什么?0.001Lux 照度门槛与选型真相
人工智能·算法·车载系统·自动驾驶·无人机·视频·智能硬件
Felaim13 天前
【World Model】Drive-WM条件编码-视角分解-扩散与规划全流程详解
自动驾驶·规划·world model·扩散·drive-wm