4. 点云基础与表示
RGB-D相机输出的是一张彩色图加一张深度图,而机器人真正用于定位、避障、抓取和重建的,往往是三维点云。点云可以理解为“空间中一组带属性的离散点”,每个点至少包含三维坐标 (x, y, z),还可以附带颜色、法线、强度、时间戳等属性。本章围绕点云的数据结构、深度图转点云、滤波、降采样、法线估计以及常用点云库展开,帮助你把二维深度信息稳定地转换为可计算的三维表示。
一、点云的数据结构与表示
点云最直观的存储方式是“点数组”,即每个点按固定字段排列。工程中常见两种组织方式:一种是无序点云,点之间没有拓扑关系,适合滤波、配准和分割;另一种是有序点云,通常由深度图直接生成,保留行列结构,能快速访问邻域,也便于恢复图像与三维点的对应关系。
从内存布局看,点云库通常采用结构体数组或连续缓冲区。以 PCL 为例,pcl::PointXYZ 只存坐标,pcl::PointXYZRGB 额外存颜色,pcl::PointNormal 再存法线。字段越多,单点占用越大,传输和滤波成本也越高。因此,在算法链路中应尽量按需选择点类型,避免全程使用“大而全”的结构。
核心理解:点云不是“图像”,也不是“网格”。它没有面片和纹理坐标,只有离散采样点。它的优势是获取直接、表达灵活;劣势是数据量大、邻域关系弱、对噪声和遮挡敏感。
二、深度图转点云:从像素到三维坐标
深度图转点云是 RGB-D 视觉中最基础的一步。对于针孔相机模型,已知像素坐标 (u, v)、深度值 d、相机内参 fx、fy、cx、cy,则三维点可表示为:
z = d / depth_scale
x = (u - cx) * z / fx
y = (v - cy) * z / fy
其中 depth_scale 是深度单位换算系数,常见为 1000(毫米转米)或 5000。若相机有畸变,还需先做去畸变,再代入上式。若使用 RGB-D 相机,通常还会把彩色图对应像素的 RGB 值赋给点,形成 PointXYZRGB。
实际工程中,深度图常存在无效值(0 或 NaN),转换时要先过滤。否则这些点会落在相机原点附近或产生极端坐标,污染后续滤波和配准。一个稳健的流程是:读取深度图 → 无效值剔除 → 坐标反投影 → 颜色绑定 → 组织为有序点云。
三、点云滤波与降采样
原始点云通常包含三类问题:范围外背景、离群噪声、密度过高。滤波和降采样分别解决“去什么”和“留多少”的问题。
- 直通滤波:按 x、y、z 某一维设定上下限,快速裁掉工作区外的点,例如只保留机械臂前方 0.3~1.2 m 的点。
- 统计滤波:统计每个点到最近 k 个邻居的平均距离,剔除明显偏离均值的离群点,适合去除飞点。
- 半径滤波:若某点在半径 r 内的邻居数少于阈值,则视为噪声。它对稀疏区域更敏感。
- 体素滤波:把空间划分为固定边长 leaf_size 的体素,每个体素用质心或中心点代替,实现降采样。
降采样不是越狠越好。leaf_size 过大,桌面边缘、物体棱角会被抹平,配准和抓取位姿都会变差;leaf_size 过小,数据量仍然很大,实时性不足。工程上常从 0.005~0.02 m 开始试,结合场景尺度和算力调整。
经验法则:先直通滤波裁范围,再统计滤波去飞点,最后体素滤波降密度。顺序反过来也能跑,但先裁范围能显著减少后续计算量。
四、法线估计与常用点云库
法线描述局部表面的朝向,是点云配准、平面分割、抓取规划的重要输入。估计方法通常是:对每个点取 K 近邻或半径邻域,用 PCA 拟合局部平面,最小特征值对应的特征向量即为法线方向。由于法线有正负两个方向,还需要统一朝向,例如让法线指向相机视点或一致朝外。
法线估计对邻域大小很敏感。邻域太小,法线抖动大;邻域太大,细节被平滑。对于桌面、墙面等平面,邻域可稍大;对于边缘和曲面,邻域应适当缩小。若点云已经降采样,法线估计通常更快,但过稀的点云会导致邻域不足。
| 点云库 | 语言/生态 | 典型能力 | 适用场景 |
|---|---|---|---|
| PCL | C++,Python 绑定 | 滤波、配准、分割、法线、重建 | 机器人离线处理与算法验证 |
| Open3D | Python/C++ | 点云读写、可视化、配准、重建 | 快速原型、教学、科研 |
| ROS perception_pcl | C++/ROS | 点云消息转换、滤波节点 | ROS 机器人实时感知链路 |
| OpenCV RGB-D | C++/Python | 深度图处理、反投影 | 轻量级深度转点云 |
五、案例与常见误区
假设一台 RGB-D 相机以 640×480 输出深度图,我们要抓取桌面上一个杯子。一个可用的处理链路是:读取深度图并剔除 0 值;用内参反投影得到有序点云;直通滤波保留 z 在 0.3~1.0 m 的点;统计滤波去除飞点;体素滤波 leaf_size=0.008 m;估计法线;最后做平面分割提取桌面,再对桌面上的点聚类得到杯子点云。
常见误区有四个:第一,忽略深度单位,导致点云尺度差 1000 倍;第二,不做无效值过滤,点云在原点附近堆积;第三,降采样过度,杯子边缘和把手消失;第四,法线方向不统一,配准和抓取方向随机翻转。复盘时应优先检查内参、深度尺度、无效值比例和 leaf_size 这四个参数。
排障提示:如果点云看起来“糊成一团”,先看深度图是否大面积无效;如果点云尺度明显不对,检查 depth_scale;如果配准总失败,检查法线是否统一、降采样是否过狠。
掌握点云基础后,后续的配准、分割、位姿估计和三维重建才有稳定的数据基础。点云表示的核心不是“点越多越好”,而是“在保留任务所需几何信息的前提下,让数据量、噪声和计算量达到平衡”。