1. 三维感知基础:传感器原理与点云数据
各位同学,欢迎来到《场景重建与点云配准》的第一章。我是这门课的主讲,在三维视觉和点云处理领域摸爬滚打了十来年。今天咱们先打好地基——聊聊三维感知的那些传感器,以及点云数据到底长什么样。
你可能会问:为什么一上来就讲传感器?说白了,后面所有的配准、重建、分割,都依赖传感器采集的原始数据。传感器选错了,后面算法再牛也白搭。我在项目里见过太多这样的坑了。
1.1 主流三维传感器
目前市面上主流的深度传感器,我按原理分成三类:激光雷达、结构光/双目深度相机、ToF(飞行时间)相机。它们各有各的脾气。
| 传感器类型 | 工作原理 | 典型代表 | 测距范围 | 精度 | 适用场景 |
|---|---|---|---|---|---|
| 激光雷达(LiDAR) | 脉冲激光飞行时间 | Velodyne、Ouster、禾赛 | 10m ~ 200m+ | cm级 | 自动驾驶、大场景测绘 |
| 结构光深度相机 | 投射编码光斑 + 三角测量 | Kinect v1、Intel RealSense | 0.1m ~ 5m | mm级 | 室内、人脸、物体扫描 |
| ToF 相机 | 连续波调制光相位差 | Kinect v2、PMD、索尼 | 0.3m ~ 10m | cm级 | 室内、手势交互、SLAM |
| 双目立体相机 | 双视角图像匹配 + 三角测量 | ZED、MYNT EYE | 0.5m ~ 20m | 随距离退化 | 室内外、视觉SLAM |
我的经验之谈:选传感器别只看参数表。激光雷达在雨雾天性能下降严重,结构光在强阳光下基本失效。我曾经在户外用 Kinect v1 做重建,结果光斑被太阳光淹没,点云全是空洞。后来换了 ToF 相机,虽然精度差点,但至少能出数据。
1.1.1 激光雷达(LiDAR)
激光雷达的原理其实很简单:发射一束激光,打到物体表面反射回来,测量飞行时间,距离 = 光速 × 时间 / 2。再配合旋转扫描,就能得到一圈一圈的点云。
嗯,这里要注意:激光雷达分机械式和固态式。机械式有旋转部件,寿命有限;固态式用光学相控阵或微振镜,体积小但视场角受限。我建议做室外大场景重建,优先考虑 32 线以上的机械式 LiDAR,点云密度够用。
1.1.2 深度相机(结构光 & ToF)
深度相机是室内重建的主力。结构光相机投射已知图案,通过图案变形计算深度。ToF 相机则测量发射光和反射光之间的相位差。
你想想看,结构光在近距离精度极高,但有个致命弱点——多路径干扰。在墙角、凹面等位置,反射光会多次弹跳,导致深度测量偏大。ToF 相机也有问题,它的测量值容易受环境光中的红外成分干扰。
避坑指南:我曾经用 ToF 相机在阳光直射的窗边做重建,点云里出现了一大片飞点。后来发现是太阳光中的红外分量干扰了相位测量。解决办法是加装带通滤光片,或者干脆拉上窗帘。
1.2 点云数据格式
传感器采集到的原始数据,最终要存成文件。市面上常见的点云格式有 PCD、PLY、LAS 三种。我个人的习惯是:做算法原型用 PCD,做可视化用 PLY,做测绘地理信息用 LAS。
| 格式 | 全称 | 特点 | 适用场景 |
|---|---|---|---|
| PCD | Point Cloud Data | PCL 原生格式,支持 ASCII 和二进制,可自定义字段 | 算法开发、PCL 库使用 |
| PLY | Polygon File Format | 支持点云和三角网格,可带颜色和法向量 | 可视化、3D 打印、Mesh 重建 |
| LAS | LASer file format | 工业标准,支持分类、强度、回波次数等属性 | 测绘、GIS、LiDAR 点云处理 |
1.2.1 PCD 格式
PCD 是 Point Cloud Library(PCL)的亲儿子。它的文件头包含点云的基本信息:点数、字段名、大小、类型、宽度/高度(有序点云才有)。
# .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 12345
HEIGHT 1
VIEWPOINT 0 0 0 1 0 0 0
POINTS 12345
DATA ascii
0.123 0.456 0.789 4294967295
0.234 0.567 0.890 4278190335
...
我个人建议:数据量小(百万点以内)用 ASCII 格式方便调试;数据量大用二进制格式,读写速度快 10 倍以上。
1.2.2 PLY 格式
PLY 格式比 PCD 更通用,Blender、MeshLab 等工具都支持。它既可以存点云,也可以存三角网格。PLY 的文件头用 element 关键字定义顶点和面。
ply
format ascii 1.0
element vertex 12345
property float x
property float y
property float z
property uchar red
property uchar green
property uchar blue
element face 0
property list uchar int vertex_indices
end_header
0.123 0.456 0.789 255 0 0
0.234 0.567 0.890 0 255 0
...
注意:PLY 的二进制格式分 little endian 和 big endian,跨平台读写时一定要检查字节序。我曾经在 Windows 上写了一个 PLY 文件,拿到 Linux 上读出来全是乱码,折腾了半天才发现是字节序问题。
1.2.3 LAS 格式
LAS 是测绘行业的金标准。它除了存 xyz 坐标,还存了强度值、回波次数、分类标签(地面、建筑、植被等)。LAS 1.2 和 LAS 1.4 是主流版本,后者支持更多字段。
做测绘项目时,我建议直接用 LAS 格式,因为下游的 GIS 软件(ArcGIS、QGIS)都原生支持。PCD 和 PLY 在测绘领域反而水土不服。
1.3 坐标系与变换
点云数据本身只是一堆三维坐标,但这些坐标是在哪个坐标系下定义的?这就引出了坐标系变换的问题。
常见的坐标系有:
- 传感器坐标系:以传感器光心为原点,z 轴指向拍摄方向
- 世界坐标系:固定的全局参考系,通常用东北天(ENU)或北东地(NED)
- 相机坐标系:与传感器坐标系类似,但通常 x 向右、y 向下、z 向前
- 图像像素坐标系:二维的 u-v 坐标,原点在左上角
坐标系之间的变换,核心就是旋转 + 平移,用 4×4 齐次变换矩阵表示:
| R t |
| 0 1 |
其中 R 是 3×3 旋转矩阵,t 是 3×1 平移向量。注意:旋转矩阵必须是正交矩阵,行列式为 +1。
我的经验:坐标系变换是三维重建中最容易出错的地方。我见过太多人把旋转矩阵的转置和逆搞混,或者把平移向量加反了。我的建议是:每次做变换前,先画个坐标系示意图,标清楚原点方向和变换顺序。
1.4 本章知识体系
下面这张图总结了本章的核心内容,帮你建立整体框架:
学习建议:本章内容偏基础,但非常重要。我建议你动手做两件事:一是用 PCL 或 Open3D 读取一个 PCD 文件,打印出点云信息;二是写一个小程序,把点云从传感器坐标系变换到世界坐标系。只有亲手写过代码,才能真正理解坐标系变换的含义。