1. 点云数据基础:什么是点云、点云数据格式、点云可视化基础
大家好,我是你们的老朋友。今天咱们正式开讲《点云滤波降噪与特征提取实战》的第一章。说实话,每次带新人入门,我都要先问一个问题:你手里拿到的那个「点云」,到底是个什么东西?
很多人觉得点云就是一堆三维坐标,没什么好讲的。嗯,这话对了一半。它确实是一堆坐标,但背后藏着的信息量,比你想象的大得多。我当年刚接触激光雷达时,打开第一个PCD文件,看到满屏的数字,第一反应是「这玩意儿能看出啥?」后来踩了不少坑,才慢慢摸清门道。
1.1 什么是点云
点云,说白了就是三维空间里一群点的集合。每个点通常包含XYZ坐标,有时候还带着颜色、强度、法向量等信息。你可以把它想象成用无数个「像素」拼出来的三维世界。
举个例子。你拿手机拍一张照片,得到的是二维像素阵列。但如果你用激光雷达扫一圈,得到的就是三维点云。每个点都对应着真实物体表面上的一个采样点。
核心概念:点云是三维世界的「数字化快照」。它不连续,但足够密的时候,就能还原出物体的几何形状。
为什么会用到点云?因为很多场景下,相机不够用。比如自动驾驶,纯视觉在黑夜、逆光、雨雾天气下容易翻车。激光雷达就不一样,它主动发射激光,不受光照影响。我在做园区无人车项目时,就遇到过傍晚强逆光导致视觉SLAM直接崩掉的情况,换成激光雷达+点云,稳得很。
1.2 常见的点云数据格式
点云格式五花八门,但最常用的就三种:PCD、PLY、LAS。我一个个说。
1.2.1 PCD格式
PCD是Point Cloud Library(PCL)的亲儿子。它最大的优点是简单、灵活。文件头里写明了点云有多少个点、每个字段是什么类型、数据是二进制还是ASCII。
一个典型的PCD文件长这样:
# .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 4294967295
0.234 0.567 0.890 4278190335
...
我个人习惯用PCD做中间格式。因为它读写快,而且PCL原生支持,调试起来特别方便。但要注意,PCD的二进制版本和ASCII版本混用时会出问题——我曾经因为没注意DATA字段写成了ascii,结果程序读二进制流,直接崩了半小时才找到原因。
1.2.2 PLY格式
PLY(Polygon File Format)是图形学领域的常客。它比PCD多了一个优势:可以存储多边形网格信息。也就是说,你不仅有点,还能存三角面片。
PLY的文件结构分两部分:头部和数据。头部定义属性,数据部分逐点或逐面填写。
ply
format ascii 1.0
element vertex 8
property float x
property float y
property float z
property uchar red
property uchar green
property uchar blue
element face 6
property list uchar int vertex_indices
end_header
0 0 0 255 0 0
1 0 0 0 255 0
...
如果你做三维重建,最后输出模型时,PLY是首选。我做过一个古建筑扫描项目,甲方要求交付PLY格式,因为他们的建模软件只认这个。
1.2.3 LAS格式
LAS是测绘和遥感领域的标准格式。它由美国摄影测量与遥感学会(ASPRS)制定。LAS格式最大的特点是:分类信息。每个点可以标记为地面、植被、建筑、水体等。
LAS文件是二进制的,不能直接文本打开。但它的头部信息非常丰富,包含坐标参考系、点记录格式、飞行轨迹等元数据。
| 格式 | 主要应用领域 | 是否支持颜色 | 是否支持分类 | 是否支持网格 |
|---|---|---|---|---|
| PCD | 机器人、SLAM | 是 | 否 | 否 |
| PLY | 计算机图形学、三维重建 | 是 | 否 | 是 |
| LAS | 测绘、遥感、林业 | 是(部分版本) | 是 | 否 |
我的建议:做SLAM和机器人,优先用PCD。做三维重建和渲染,用PLY。做测绘和地理信息,用LAS。别混用,格式转换会损失精度。
1.3 点云可视化基础
光看数字没意思,得把点云画出来。可视化是调试点云算法的第一步。我见过太多人算法写完了,一可视化发现点云都是歪的——坐标系搞反了。
1.3.1 用Open3D可视化
Open3D是我现在最常用的工具。它轻量、Python友好、API设计得也合理。装好之后,几行代码就能看点云。
import open3d as o3d
# 读取点云
pcd = o3d.io.read_point_cloud("example.pcd")
# 可视化
o3d.visualization.draw_geometries([pcd])
就这么简单。你运行后会弹出一个窗口,可以用鼠标拖拽旋转、滚轮缩放。Open3D默认会给点云上色,如果没有颜色信息,就显示成灰色。
如果你想加点花样,比如显示坐标轴、调整点的大小:
# 创建可视化窗口
vis = o3d.visualization.Visualizer()
vis.create_window()
# 添加点云
vis.add_geometry(pcd)
# 设置渲染选项
opt = vis.get_render_option()
opt.point_size = 2.0 # 点的大小
opt.background_color = [0, 0, 0] # 黑色背景
# 显示坐标轴
vis.add_geometry(o3d.geometry.TriangleMesh.create_coordinate_frame())
vis.run()
vis.destroy_window()
注意:Open3D的坐标系是右手系,X向右,Y向上,Z朝向自己。如果你从其他软件导出的点云看着是歪的,先检查坐标系。
1.3.2 用PCL可视化
PCL是C++的经典库,虽然学习曲线陡一点,但功能极其强大。PCL的可视化模块叫pcl::visualization。
#include <pcl/io/pcd_io.h>
#include <pcl/visualization/pcl_visualizer.h>
int main() {
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::io::loadPCDFile("example.pcd", *cloud);
pcl::visualization::PCLVisualizer viewer("点云可视化");
viewer.addPointCloud(cloud, "cloud");
viewer.setBackgroundColor(0, 0, 0);
viewer.addCoordinateSystem(1.0);
while (!viewer.wasStopped()) {
viewer.spinOnce();
}
return 0;
}
PCL的PCLVisualizer支持键盘回调、鼠标拾取、点云着色等高级功能。我在做点云配准时,经常用它来手动选取对应点。
1.3.3 可视化时的常见坑
嗯,这里要重点说一下。可视化看起来简单,但坑不少。
- 点太多会卡死:几百万个点全画出来,你的显卡会哭。建议先下采样再可视化。
- 颜色显示不对:RGB字段的顺序可能是BGR,也可能是RGB。Open3D默认是RGB,但有些传感器给的是BGR。
- 深度错觉:没有颜色信息时,纯几何点云很难判断远近。可以加颜色映射,按Z值着色。
我曾经在调试一个激光雷达数据时,怎么都看不出点云的形状。后来发现是点云里混了大量NaN值,可视化时这些点被渲染到了原点,把整个画面搅乱了。所以,可视化之前,先做一步滤波,把无效点去掉。
1.4 本章知识体系
下面这张图总结了本章的核心内容,帮你快速建立知识框架:
这张图把本章的三个核心模块串起来了。你想想看,从理解点云是什么,到掌握三种主流格式,再到学会用工具把它画出来,这就是你入门点云处理的第一步。
课后小练习:去网上下一个PCD格式的点云文件(比如斯坦福兔子的点云),用Open3D读进来,试着改改点的大小和背景颜色。看看你能不能一眼看出兔子的耳朵在哪。
好了,第一章就到这里。内容不多,但都是基础中的基础。下一章我们会深入点云滤波,聊聊怎么把噪声去掉、把地面分离出来。到时候见。
公众号:蓝海资料掘金营,微信deep3321