第一章:点云数据读取与可视化

各位同学好,我是你们这门课的主讲。做了这么多年点云处理,我始终觉得——可视化是理解点云的第一步。你想想看,一堆三维坐标点,光看数字能看出什么名堂?只有把它渲染出来,你才能真正感知到数据的结构、噪声、密度分布。

这一章,我们就从最基础的操作开始:用Open3D读取点云文件,然后把它显示在屏幕上。嗯,别小看这一步,我见过不少新手在这上面栽跟头。

1.1 点云文件格式:PCD vs PLY

先聊聊文件格式。目前最常用的两种就是PCD和PLY。

特性 PCD PLY
发明者 Point Cloud Library (PCL) Stanford Graphics Lab
存储方式 ASCII / 二进制 ASCII / 二进制
支持颜色 ✅ 支持 ✅ 支持
支持法向量 ✅ 支持 ✅ 支持
文件大小 相对较小 相对较大
常见场景 机器人、SLAM 计算机图形学、3D扫描

我个人习惯用PCD,因为PCL生态里它最顺手。但如果你做图形学相关的工作,PLY会更常见。其实Open3D对两者支持都很好,你不需要纠结太多。

小技巧: 如果你不确定文件是ASCII还是二进制,用文本编辑器打开看一眼就行。ASCII版本能看到一堆数字,二进制版本全是乱码。

1.2 用Open3D读取点云

代码其实就一行。但这一行背后,Open3D帮你做了很多事:文件格式检测、数据解析、内存分配。

import open3d as o3d

# 读取PCD文件
pcd = o3d.io.read_point_cloud("data/room.pcd")

# 读取PLY文件
pcd = o3d.io.read_point_cloud("data/bunny.ply")

print("点云加载完成")

我在项目中遇到过一个问题:读取一个几百兆的PCD文件,程序直接卡死了。后来发现是文件用了ASCII格式,数据量太大。所以如果你处理大文件,记得用二进制格式存储。

注意: 文件路径不要包含中文!Open3D底层用的是C++的fstream,对中文路径支持不太好。我曾经因为这个排查了半天,最后发现是路径里有个"测试"两个字。

1.3 点云的基本属性

读取完点云,我们得看看它长什么样。说白了,就是查几个关键属性。

# 获取点数
num_points = len(pcd.points)
print(f"点数: {num_points}")

# 获取坐标范围
points = np.asarray(pcd.points)
x_min, x_max = points[:, 0].min(), points[:, 0].max()
y_min, y_max = points[:, 1].min(), points[:, 1].max()
z_min, z_max = points[:, 2].min(), points[:, 2].max()
print(f"X范围: [{x_min:.2f}, {x_max:.2f}]")
print(f"Y范围: [{y_min:.2f}, {y_max:.2f}]")
print(f"Z范围: [{z_min:.2f}, {z_max:.2f}]")

# 检查是否有颜色信息
if pcd.has_colors():
    colors = np.asarray(pcd.colors)
    print(f"颜色范围: R[{colors[:,0].min():.2f}, {colors[:,0].max():.2f}]")
else:
    print("该点云没有颜色信息")

这里有个坑:Open3D的颜色值范围是0到1,不是0到255。如果你从别的工具导出的PLY文件颜色是0-255,记得归一化。我刚开始用的时候,显示出来的点云一片漆黑,还以为是代码写错了。

1.4 点云可视化基础

终于到了最激动人心的部分——把点云显示出来。

# 最简单的可视化
o3d.visualization.draw_geometries([pcd])

# 带窗口控制的可视化
vis = o3d.visualization.Visualizer()
vis.create_window(window_name="我的第一个点云", width=800, height=600)
vis.add_geometry(pcd)

# 设置渲染选项
opt = vis.get_render_option()
opt.background_color = np.array([0.1, 0.1, 0.1])  # 深灰色背景
opt.point_size = 2.0  # 点的大小

vis.run()
vis.destroy_window()

你运行这段代码,会看到一个3D窗口。鼠标操作很简单:左键旋转、滚轮缩放、右键平移。嗯,这里要注意,如果你用的是Mac的触摸板,可能需要调整一下鼠标设置。

1.5 颜色渲染:让点云更好看

默认情况下,Open3D会用一种统一的颜色渲染所有点。但很多时候,我们需要根据某些属性给点上色。

# 根据Z轴高度上色
points = np.asarray(pcd.points)
z_values = points[:, 2]
z_min, z_max = z_values.min(), z_values.max()

# 归一化到[0, 1]
z_norm = (z_values - z_min) / (z_max - z_min)

# 创建颜色:低处蓝色,高处红色
colors = np.zeros((len(points), 3))
colors[:, 0] = z_norm      # 红色通道
colors[:, 2] = 1 - z_norm  # 蓝色通道

pcd.colors = o3d.utility.Vector3dVector(colors)
o3d.visualization.draw_geometries([pcd])

这种高度着色法,我在做地形扫描数据时经常用。一眼就能看出哪里是高地、哪里是洼地,比看数字直观多了。

核心要点:
  • Open3D的颜色范围是[0, 1],不是[0, 255]
  • 可视化窗口支持鼠标交互:旋转、平移、缩放
  • 可以通过修改render_option控制显示效果
  • 颜色渲染是理解点云结构的重要手段

1.6 本章知识体系

下面这张图,是我梳理的本章核心逻辑。你跟着这个流程走,基本不会出错。

第一章:点云数据读取与可视化 - 知识体系 文件格式 PCD / PLY 读取点云 read_point_cloud() 基本属性 点数 / 坐标 / 颜色 可视化 draw_geometries() 颜色渲染 高度着色 / 自定义 窗口控制 旋转 / 缩放 / 平移 核心目标:掌握点云数据的读取、属性查看与可视化

这张图把本章的知识点串起来了。你从文件格式开始,一路走到可视化,每一步都有对应的Open3D函数。我个人建议你按照这个流程,自己动手跑一遍代码。光看是学不会的,得亲手敲。

避坑指南: 我曾经在可视化时遇到窗口一闪而过的情况。后来发现是忘了加 vis.run()vis.destroy_window()。如果你也遇到这个问题,检查一下是不是少了这两行。

好了,第一章的内容就到这里。你学会了怎么读取点云、查看属性、可视化、做颜色渲染。这些是后续所有章节的基础,一定要练熟。


公众号:蓝海资料掘金营,微信deep3321