1. 点云基础与3D世界:从数据到可视化

各位同学,欢迎来到《点云处理与模型匹配》的第一章。

说实话,每次开课我都很期待讲这一节。因为点云这个东西,听起来高大上,但说白了——它就是一堆三维空间里的点。你想想看,我们人眼看世界,看到的是颜色、纹理、形状。而机器呢?它看到的就是这些密密麻麻的坐标点。

我个人习惯把点云叫做“3D世界的像素”。就像一张照片由像素组成,一个三维场景就由点云组成。只不过每个点不光有位置,还可能带着颜色、强度这些附加信息。

1.1 点云数据到底是什么?

点云(Point Cloud),就是在同一空间参考系下,表达目标空间分布和表面特性的海量点集合。每个点通常包含三维坐标 (X, Y, Z),有些还会带上 RGB 颜色、激光反射强度、法向量等信息。

核心概念:点云 = 三维坐标 + 可选属性(颜色、强度、分类标签等)

我在做自动驾驶项目时,经常要处理上亿个点的激光雷达数据。刚开始觉得这数据量太吓人了,后来发现——其实大部分点都是冗余的。嗯,这里要注意,点云处理的第一步往往不是“怎么用”,而是“怎么删”。

属性 说明 典型应用
XYZ坐标 必选,描述点在三维空间的位置 所有点云处理的基础
RGB颜色 可选,来自相机或扫描仪 三维重建、纹理映射
反射强度 可选,LiDAR特有 地物分类、路面检测
法向量 可选,通过邻域计算 曲面重建、特征提取

1.2 点云是怎么来的?

获取点云的方式,我把它分成两大类:主动式和被动式。说白了,一个自己发光去照,一个靠别人给光。

1.2.1 LiDAR(激光雷达)

LiDAR 的工作原理很简单:发射激光束,打到物体上反射回来,根据飞行时间算出距离。转一圈,扫一片,就得到一圈点云。

我记得第一次接触 Velodyne 的 64 线激光雷达,那家伙转起来嗡嗡响,每秒能出 130 万个点。当时我就在想,这数据量,CPU 扛得住吗?后来发现——扛不住也得扛,这就是工业界的现实。

  • 机械式LiDAR:多线旋转扫描,精度高,但贵、有机械磨损
  • 固态LiDAR:无旋转部件,靠光学相控阵或闪光,成本低,视场角有限
  • 单线LiDAR:只扫一条线,常用于避障、SLAM

1.2.2 深度相机

深度相机是另一种常见来源。它不像 LiDAR 那样扫一圈,而是像普通相机一样拍一张“深度图”,每个像素的值就是距离。

常用的技术有结构光(比如 Kinect v1)、ToF(比如 Kinect v2/Azure Kinect)、双目立体视觉。我踩过最大的坑就是双目——你以为两个摄像头就能算出深度?光照不好、纹理不够,出来的点云全是洞。

避坑指南:我曾经在室内用双目相机做三维重建,结果白墙区域全是空洞。后来换成结构光才解决问题。记住——深度相机对光照、纹理、反射面都很敏感,选型时一定要看场景。

获取方式 典型设备 精度 有效距离 适用场景
机械式LiDAR Velodyne、Hesai ±2cm 100-300m 自动驾驶、测绘
固态LiDAR Livox、Ouster ±3cm 50-200m 机器人、无人机
结构光相机 Kinect v1、Intel RealSense ±1mm 0.5-5m 室内重建、人机交互
ToF相机 Kinect v2、Azure Kinect ±5mm 0.5-10m 室内、AR/VR
双目立体 ZED、Intel RealSense T系列 ±1cm 0.5-20m 室外、弱光环境

1.3 常见的点云格式

格式这东西,说白了就是数据怎么存。我见过不下二十种点云格式,但常用的就那么几个。你想想看,要是每换一个设备就学一种新格式,那还干不干活了?

1.3.1 PCD(Point Cloud Data)

PCL 库的亲儿子。PCD 格式是 Point Cloud Library 定义的,也是我个人最常用的格式。它支持 ASCII 和二进制两种存储方式,头部信息清晰,扩展性好。

# .PCD v0.7 - Point Cloud Data file format
VERSION 0.7
FIELDS x y z rgb
SIZE 4 4 4 4
TYPE F F F F
COUNT 1 1 1 1
WIDTH 640
HEIGHT 480
VIEWPOINT 0 0 0 1 0 0 0
POINTS 307200
DATA ascii
0.123 0.456 0.789 16711680
0.234 0.567 0.890 65280
...

1.3.2 PLY(Polygon File Format)

PLY 格式最早是斯坦福大学搞出来的,后来成了三维扫描领域的通用格式。它比 PCD 多了面片信息,适合做网格模型。我一般在做三维重建输出时用 PLY,因为可以直接导入 MeshLab 看效果。

1.3.3 XYZ / XYZRGB

最朴素的格式,没有之一。就是一行一个点,空格或逗号分隔。XYZ 只有坐标,XYZRGB 多了颜色。简单粗暴,但文件体积大,没有头部信息。

我的建议:做算法原型时用 XYZ 格式,方便调试;做工程部署时用 PCD 二进制格式,速度快、体积小;做最终成果展示时用 PLY,兼容性好。

格式 优点 缺点 典型用途
PCD 头部信息丰富、支持多种数据类型 PCL生态外兼容性一般 PCL处理、算法开发
PLY 支持网格、颜色、法向量 二进制/ASCII混用容易混淆 三维重建、可视化
XYZ 简单、通用、易解析 无头部信息、文件大 快速原型、数据交换
LAS/LAZ 行业标准、支持分类 解析复杂 测绘、地理信息

1.4 点云可视化基础

做点云处理,可视化是基本功。你看不到数据长什么样,怎么知道算法对不对?我刚开始学的时候,就吃了这个亏——写了半天滤波代码,结果可视化一看,参数设错了,点全滤没了。

1.4.1 用 PCL Visualizer 可视化

PCL 自带的可视化工具,简单好用。几行代码就能把点云显示出来。

#include <pcl/visualization/cloud_viewer.h>

pcl::visualization::CloudViewer viewer("点云查看器");
viewer.showCloud(cloud);
while (!viewer.wasStopped()) {
    // 保持窗口打开
}

1.4.2 用 Open3D 可视化

Open3D 的 API 更现代,交互也更友好。我个人现在做原型验证时,越来越喜欢用 Open3D。

import open3d as o3d

pcd = o3d.io.read_point_cloud("example.pcd")
o3d.visualization.draw_geometries([pcd],
                                  window_name="点云可视化",
                                  width=800, height=600)

1.4.3 可视化时的常见问题

  • 点太多看不清:用体素下采样,先降采样再看
  • 颜色不对:检查 RGB 字段的编码方式,PCD 里 RGB 是 float 打包的
  • 视角转不动:检查是否开启了交互模式
  • 点云显示为空:先打印点数,再检查坐标范围,可能是离相机太远

我曾经踩过的坑:有一次怎么都显示不出点云,折腾了两小时。最后发现是点云的坐标值太大(几十万米),相机默认在原点,根本看不到。把坐标归一化到 [-1, 1] 就好了。所以——先看数据范围,再看可视化。

1.5 本章知识体系

下面这张图,是我自己梳理的点云基础知识框架。你可以把它当成一张地图,后面每学一章,都能在这张图上找到位置。

点云基础与3D世界 · 知识体系 点云数据 核心概念 获取方式 格式与可视化 XYZ坐标 RGB颜色 反射强度 法向量 LiDAR 深度相机 结构光 ToF 双目立体 PCD PLY XYZ LAS/LAZ 核心要点 点云 = 三维坐标 + 可选属性 | 获取方式决定数据质量 | 格式选择影响处理效率

这张图把本章的核心内容串起来了。从点云的概念出发,到怎么获取、用什么格式存、怎么可视化看——这就是我们后面所有章节的基础。

好了,第一章就到这里。记住一句话:点云不神秘,它就是三维世界里的像素。后面我们会一步步深入,从滤波、配准到模型匹配,把这块硬骨头啃下来。