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 本章知识体系
下面这张图,是我自己梳理的点云基础知识框架。你可以把它当成一张地图,后面每学一章,都能在这张图上找到位置。
这张图把本章的核心内容串起来了。从点云的概念出发,到怎么获取、用什么格式存、怎么可视化看——这就是我们后面所有章节的基础。
好了,第一章就到这里。记住一句话:点云不神秘,它就是三维世界里的像素。后面我们会一步步深入,从滤波、配准到模型匹配,把这块硬骨头啃下来。