3. 点云数据基础

点云是三维感知系统最原始、最通用的数据形态。无论是激光雷达扫描、结构光重建,还是多视图立体匹配,最终都会落到一组离散的三维点上。理解点云的表示方式、存储格式、邻域关系与法向量估计,是后续配准、滤波、分割与融合的前提。本节从数据结构出发,逐步过渡到几何属性计算与工程工具链。

一、点云的表示:从无序集合到有序结构

最基础的点云表示是一个 N×3 的浮点矩阵,每行对应一个点的 (x, y, z) 坐标。若携带强度、颜色、法向量或时间戳,则扩展为 N×(3+k) 的属性矩阵。这种表示称为无序点云,点与点之间没有拓扑连接,顺序也不携带几何含义。

当点云来自深度相机或激光雷达的规则扫描时,可以保留其成像结构,形成有序点云(organized point cloud)。例如深度图对应的点云可视为 H×W 的二维网格,每个像素位置对应一个三维点。有序点云的优势在于邻域查询可以直接通过行列索引完成,无需构建空间索引,速度极快;缺点是对遮挡和无效深度敏感,且不适用于任意来源的点云。

此外,点云还可以附加多种属性:反射强度(intensity)、RGB 颜色、法向量(normal)、曲率(curvature)、标签(label)等。这些属性在分割、分类和配准中往往比坐标本身更具判别力。

二、存储格式:PCD、PLY、LAS 与二进制取舍

点云存储格式众多,选择时需权衡可读性、体积、属性支持与生态兼容性。下表对比几种常见格式:

格式类型属性支持典型场景
PCDASCII / Binary / BinaryCompressedxyz、强度、RGB、法向量、自定义字段PCL 生态、算法调试
PLYASCII / Binaryxyz、颜色、法向量、面片三维重建、网格与点云混合
LAS / LAZBinary(LAZ 压缩)xyz、强度、回波、分类、GPS 时间测绘、机载激光雷达
BINBinary通常为 xyz + 强度KITTI 等自动驾驶数据集
CSV / TXTASCII仅坐标或简单属性快速交换、小规模数据

工程中常见的误区是:为了“方便查看”而全部使用 ASCII 格式。实际上,百万级点云的 ASCII 文件体积可达二进制的 3~5 倍,读写速度也显著更慢。建议在算法内部使用二进制或压缩格式,仅在调试和交换时导出 ASCII。

PCD 文件头中的 FIELDS、SIZE、TYPE、COUNT 四个字段共同描述了每个点的内存布局。读取自定义点云时,务必先解析文件头,否则会出现属性错位。

三、邻域关系:KNN 与半径搜索

点云没有显式的连接关系,因此“邻域”必须通过几何距离定义。最常用的两种查询是:

  • K 近邻(KNN):给定查询点,返回距离最近的 K 个点。K 固定,邻域大小随密度变化。
  • 半径搜索(Radius Search):返回距离小于 r 的所有点。半径固定,邻域点数随密度变化。

直接暴力搜索的复杂度为 O(N²),无法接受。实际系统普遍采用KD-Tree或Octree建立空间索引,将查询复杂度降到 O(log N) 量级。KD-Tree 适合低维、静态点云;Octree 更适合动态更新和体素化操作。

邻域选择直接影响后续法向量、曲率和特征描述子的质量。K 太小,法向量对噪声敏感;K 太大,会跨越几何边缘,导致法向量被“平均”掉。经验上,K 取 10~30,或半径取点云平均间距的 2~3 倍,是较稳健的起点。

四、法向量估计:PCA 与方向一致性

法向量描述局部表面的朝向,是点云配准、分割和渲染的核心属性。最常用的估计方法是主成分分析(PCA):对查询点的邻域点集去质心后计算协方差矩阵,其特征值最小的特征向量即为法向量方向。

设邻域点集为 {p₁, …, p_k},质心为 p̄,协方差矩阵为:

C = (1/k) Σ (p_i - p̄)(p_i - p̄)^T

对 C 做特征分解,得到三个特征值 λ₀ ≤ λ₁ ≤ λ₂ 及对应特征向量。λ₀ 对应的特征向量即法向量;曲率可近似为 λ₀ / (λ₀+λ₁+λ₂)。

PCA 得到的法向量存在符号二义性:n 与 -n 都满足几何条件。解决方法是统一朝向视点或传感器原点,即若 n·(viewpoint - p) < 0,则翻转 n。多视角融合时,还需在配准后重新统一法向量方向。

法向量估计对邻域半径非常敏感。在薄壁、边缘和噪声区域,PCA 结果可能严重偏离真实表面。建议先做统计滤波去噪,再估计法向量,并在边缘处使用更小的邻域。

五、常见开源库与工具链

点云处理生态中,以下几个库最为常用:

  • PCL(Point Cloud Library):C++ 点云算法库,覆盖滤波、配准、分割、特征、可视化,是点云领域的“标准库”。
  • Open3D:Python/C++ 双接口,API 简洁,适合快速原型与教学,内置法向量估计、ICP、体素下采样等。
  • PDAL:面向激光雷达数据管道的工具,擅长 LAS/LAZ 处理与坐标转换。
  • LASzip / LAStools:LAS/LAZ 压缩与批处理工具链。
  • PyTorch3D / MinkowskiEngine:面向深度学习的点云与稀疏卷积框架。

下面是一个使用 Open3D 读取点云、估计法向量并保存的典型流程:

import open3d as o3d

pcd = o3d.io.read_point_cloud("scene.pcd")
pcd = pcd.voxel_down_sample(voxel_size=0.02)
pcd.estimate_normals(
    search_param=o3d.geometry.KDTreeSearchParamHybrid(
        radius=0.1, max_nn=30))
pcd.orient_normals_towards_camera_location(
    camera_location=[0, 0, 0])
o3d.io.write_point_cloud("scene_normals.pcd", pcd)

该流程体现了本节的核心链路:读取 → 下采样 → 邻域查询 → 法向量估计 → 方向统一 → 写出。每一步的参数都会影响最终几何质量,实际项目中应结合点云密度和噪声水平反复调试。

点云数据基础:表示 → 存储 → 邻域 → 法向量 → 工具链 点云表示 无序 N×3 矩阵 有序 H×W 网格 属性:强度/RGB/法向 存储格式 PCD / PLY LAS / LAZ / BIN ASCII vs 二进制 邻域关系 KNN / 半径搜索 KD-Tree / Octree K=10~30 或 r=2~3×间距 法向量估计 PCA 协方差分解 λ₀ 对应法向 朝向视点统一符号 常见开源库与工具链 PCL · Open3D · PDAL · LASzip · PyTorch3D · MinkowskiEngine 典型处理链路 读取 下采样 邻域查询 法向量估计 写出 参数:voxel_size、radius、max_nn、朝向视点

掌握上述五个环节后,点云就不再是“一堆散点”,而是一个可索引、可计算、可交换的几何数据结构。后续的配准、分割与融合,都建立在这些基础操作之上。