4. 点云可视化基础:Open3D可视化窗口配置、点云颜色与大小设置、多窗口与多视角可视化

点云处理这行,有个很实在的道理——看不见,就调不对。你算法写得再漂亮,滤波参数设得再精细,不亲眼看看点云长什么样,心里始终没底。我刚开始做SLAM的时候,就吃过这个亏:跑完一帧匹配,觉得效果挺好,结果可视化一看,点云全飘到天上去了……嗯,从那以后,我再也不敢跳过可视化这一步。

这一章,咱们就扎扎实实地把Open3D可视化这块啃下来。说白了,就是学会怎么把点云“摆”在屏幕上,还能随心所欲地调颜色、调大小、换视角。你想想看,后面做滤波、做配准,每一步都要靠眼睛来验证,可视化就是你的“第二双眼睛”。

4.1 Open3D可视化窗口:从零搭建你的“点云观察站”

Open3D的可视化核心就一个函数:draw_geometries。但别小看它,参数调好了,能玩出花来。

先看最基础的用法:

import open3d as o3d
import numpy as np

# 生成一个简单的点云(1000个随机点)
points = np.random.rand(1000, 3)
pcd = o3d.geometry.PointCloud()
pcd.points = o3d.utility.Vector3dVector(points)

# 可视化
o3d.visualization.draw_geometries([pcd])

这段代码一跑,一个窗口就弹出来了。你可以用鼠标拖拽旋转、滚轮缩放、右键平移。操作很直觉,跟玩3D建模软件差不多。

但实际项目中,我们往往需要更精细的控制。比如窗口大小、窗口标题、背景颜色。这时候就要用draw_geometries的window_name和width/height参数:

o3d.visualization.draw_geometries(
    [pcd],
    window_name="我的第一个点云窗口",
    width=1280,
    height=720,
    point_show_normal=False
)
我的习惯:窗口分辨率我一般设1280x720,刚好适配大部分屏幕。如果点云特别大(比如超过100万个点),我会把窗口设小一点,比如1024x768,不然旋转起来会卡。

4.2 点云颜色与大小:让数据“说话”

默认的点云是灰色的,大小是1个像素。说实话,看起来挺费劲的。尤其是当你要区分不同区域、不同高度或者不同类别的点时,颜色和大小就是你的“画笔”。

4.2.1 给点云上色

Open3D里给点云上色有三种方式:

方法 代码示例 适用场景
统一颜色 pcd.paint_uniform_color([1, 0, 0]) 区分不同物体或不同帧
按高度染色 根据z值映射颜色 地形、建筑物立面分析
按类别染色 根据标签分配颜色 语义分割结果展示

统一颜色最简单,直接传RGB值(范围0-1):

pcd.paint_uniform_color([0.2, 0.6, 1.0])  # 浅蓝色

按高度染色是我用得最多的。比如你有一片地面点云,想看看地形起伏,按z轴染色一目了然:

# 获取点的z坐标
points = np.asarray(pcd.points)
z = points[:, 2]

# 归一化到0-1
z_min, z_max = z.min(), z.max()
z_norm = (z - z_min) / (z_max - z_min)

# 使用colormap(这里用jet)
colors = plt.cm.jet(z_norm)[:, :3]  # 去掉alpha通道
pcd.colors = o3d.utility.Vector3dVector(colors)
避坑指南:我曾经犯过一个低级错误——颜色值传了0-255的整数。Open3D只认0-1的浮点数,传255进去,点云直接变白。记得归一化!

4.2.2 调整点的大小

点的大小在Open3D里不是直接设pcd的属性,而是通过可视化选项来调。有两种方式:

方式一:运行时按键盘
在可视化窗口打开后,按+和-键可以实时调整点的大小。这个技巧很实用,我经常在调试时一边看效果一边调。

方式二:代码中预设
用Visualizer类可以精确控制:

vis = o3d.visualization.Visualizer()
vis.create_window(window_name="点云大小测试", width=800, height=600)
vis.add_geometry(pcd)

# 获取渲染选项并设置点大小
opt = vis.get_render_option()
opt.point_size = 5.0  # 默认是1.0

vis.run()
vis.destroy_window()

点大小的取值范围一般是1.0到10.0。点云密度大时用小点(1-3),密度小时用大点(5-8)。我个人的经验是:激光雷达点云用2-3,深度相机点云用4-6。

4.3 多窗口与多视角可视化:同时看,才能对比

做点云处理,最怕的就是“盲人摸象”。只看一个视角,很容易漏掉关键信息。比如你滤波前和滤波后的点云,放在两个窗口里对比着看,效果立竿见影。

4.3.1 多窗口:各看各的

Open3D支持同时打开多个窗口。每个窗口独立控制视角、独立渲染。实现方式很简单——开多个Visualizer实例:

# 创建两个窗口
vis1 = o3d.visualization.Visualizer()
vis1.create_window(window_name="原始点云", width=640, height=480, left=50, top=50)

vis2 = o3d.visualization.Visualizer()
vis2.create_window(window_name="滤波后点云", width=640, height=480, left=700, top=50)

# 添加几何体
vis1.add_geometry(pcd_original)
vis2.add_geometry(pcd_filtered)

# 分别设置点大小
opt1 = vis1.get_render_option()
opt1.point_size = 3.0
opt2 = vis2.get_render_option()
opt2.point_size = 3.0

# 同时更新
while True:
    vis1.poll_events()
    vis1.update_renderer()
    vis2.poll_events()
    vis2.update_renderer()
注意:多窗口模式下,poll_events()和update_renderer()必须放在循环里同时调用。如果只更新一个窗口,另一个会卡死。我刚开始写多窗口时,就因为这个bug折腾了半天。

4.3.2 多视角:一个窗口,多个角度

有时候我们不想开那么多窗口,而是希望在一个窗口里从不同角度观察同一个点云。Open3D的ViewControl可以帮我们实现:

vis = o3d.visualization.Visualizer()
vis.create_window()
vis.add_geometry(pcd)

# 获取视角控制
ctrl = vis.get_view_control()

# 设置前视图
ctrl.set_front([0, 0, -1])  # 从z轴负方向看
ctrl.set_up([0, -1, 0])     # 上方向为y轴负方向
ctrl.set_zoom(0.8)

# 运行
vis.run()
vis.destroy_window()

常用的视角预设:

视角 front向量 up向量 说明
俯视图 [0, 0, -1] [0, -1, 0] 看地面分布
前视图 [0, -1, 0] [0, 0, 1] 看立面结构
侧视图 [1, 0, 0] [0, 0, 1] 看侧面轮廓
等轴测图 [1, -1, -1] [0, 0, 1] 立体感最强

我个人习惯在调试时先切到俯视图,看看点云的整体分布是否合理。然后再切到等轴测图,观察细节结构。

4.4 本章知识体系

下面这张图把本章的核心内容串起来了,你可以对照着回顾一下:

点云可视化基础(Open3D) 可视化窗口 窗口配置 window_name / width / height left / top 窗口位置 point_show_normal 颜色与大小 paint_uniform_color() 按高度/类别染色 opt.point_size 设置大小 +/- 键实时调整 多窗口与多视角 多Visualizer实例 poll_events()循环 ViewControl视角预设 set_front/set_up/set_zoom 可视化 = 调试的第一生产力

可视化这件事,说难不难,说简单也不简单。关键是要养成习惯——每做一步处理,都打开窗口看一眼。你会发现,很多bug在可视化面前根本藏不住。

好了,这一章的内容就到这里。拿起你的点云数据,动手试试吧。记住,看得见,才能调得准。