2. 点云可视化:使用Open3D/PCL进行点云可视化,调整视角与颜色。
点云可视化,说白了就是让那些密密麻麻的坐标点“活”起来。你想想看,一堆 xyz 数字摆在那,谁能看出门道?但一旦渲染成 3D 场景,地面、墙壁、障碍物一目了然。我个人习惯,拿到点云数据的第一件事,不是滤波也不是分割,而是先可视化看看“长什么样”。
这一节,我们就来聊聊怎么用 Open3D 和 PCL 把点云画出来,并且把视角和颜色调得顺手。
2.1 为什么可视化这么重要?
我在项目中遇到过好几次这样的坑:算法跑出来的结果看起来指标不错,但一可视化,发现点云里有一大片飞点(outliers)没滤掉。如果只看数值,你根本发现不了。可视化就像给数据做“体检”,能让你快速感知数据质量。
另外,调整视角和颜色也不是花架子。比如做地面提取时,把地面点染成绿色,非地面点染成红色,一眼就能看出分割效果好不好。嗯,这里要注意,颜色映射如果没调好,反而会误导判断。
2.2 Open3D 可视化:轻量又高效
Open3D 是我现在最常用的点云可视化工具。它 API 设计得很 Pythonic,几行代码就能搞定。
2.2.1 基本可视化流程
先看一个最简单的例子:
import open3d as o3d
import numpy as np
# 生成随机点云(假装是激光雷达扫出来的)
points = np.random.rand(1000, 3) * 10 # 范围 0-10 米
pcd = o3d.geometry.PointCloud()
pcd.points = o3d.utility.Vector3dVector(points)
# 可视化
o3d.visualization.draw_geometries([pcd])
运行这段代码,你会看到一个 3D 窗口,可以用鼠标拖拽旋转、滚轮缩放。默认视角是从 z 轴正方向往下看,颜色是均匀的灰色。
draw_geometries 里加参数 width=1280, height=720 来调整尺寸。
2.2.2 调整视角:找到最佳观察角度
默认视角往往不是最合适的。比如你想看地面提取的效果,最好从侧面斜着看,而不是俯视。Open3D 提供了两种调视角的方法:
方法一:手动调整后保存
在可视化窗口里,用鼠标旋转到你满意的角度,然后按 Ctrl + C(Windows)或 Cmd + C(Mac),控制台会输出当前视角参数。下次直接复制粘贴就行:
# 假设你手动调好视角后,控制台输出了这些参数
view_params = {
"front": [0.5, -0.5, 0.7],
"lookat": [0.0, 0.0, 0.0],
"up": [0.0, 0.0, 1.0],
"zoom": 0.8
}
o3d.visualization.draw_geometries([pcd], **view_params)
方法二:用代码直接设置
如果你知道想要的角度,可以直接写:
vis = o3d.visualization.Visualizer()
vis.create_window()
vis.add_geometry(pcd)
# 设置视角:从侧面 45 度俯视
ctr = vis.get_view_control()
ctr.set_front([0.5, -0.5, 0.7]) # 视线方向
ctr.set_lookat([0.0, 0.0, 0.0]) # 观察中心
ctr.set_up([0.0, 0.0, 1.0]) # 上方向
ctr.set_zoom(0.8) # 缩放
vis.run()
vis.destroy_window()
set_front 和 set_up 不垂直导致视角扭曲,画面看起来像“歪脖子”。记住,这两个向量必须正交,否则 Open3D 会报错或显示异常。
2.2.3 颜色映射:让数据“说话”
颜色是可视化里最强大的工具之一。我常用的颜色方案有三种:
| 应用场景 | 颜色方案 | 说明 |
|---|---|---|
| 地面 vs 非地面 | 绿色 vs 红色 | 对比强烈,一眼区分 |
| 高度信息 | 彩虹色(低到高) | 用颜色表示 z 值,适合看地形起伏 |
| 强度/反射率 | 灰度或热力图 | 适合激光雷达强度数据 |
来看一个按高度着色的例子:
# 按 z 轴高度着色
z = np.asarray(pcd.points)[:, 2]
z_min, z_max = z.min(), z.max()
colors = np.zeros((len(z), 3))
# 蓝色到红色的渐变
colors[:, 0] = (z - z_min) / (z_max - z_min) # R
colors[:, 2] = 1 - (z - z_min) / (z_max - z_min) # B
pcd.colors = o3d.utility.Vector3dVector(colors)
o3d.visualization.draw_geometries([pcd])
为什么用蓝色到红色?因为人眼对红蓝对比最敏感。你想想看,如果地面是蓝色,高处是红色,地形起伏一目了然。
2.3 PCL 可视化:C++ 环境下的选择
如果你在 C++ 项目里用 PCL,可视化也不复杂。PCL 的 pcl::visualization::PCLVisualizer 类功能很全。
2.3.1 基本示例
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/point_types.h>
#include <pcl/point_cloud.h>
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZ>);
// 假设 cloud 已经填充了数据
pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("点云可视化"));
viewer->addPointCloud(cloud, "cloud");
viewer->setBackgroundColor(0.1, 0.1, 0.1); // 深灰色背景
while (!viewer->wasStopped()) {
viewer->spinOnce(100);
}
2.3.2 调整视角和颜色
PCL 里调视角稍微麻烦一点,但更灵活:
// 设置相机位置
viewer->setCameraPosition(
5.0, 5.0, 5.0, // 相机位置 (eye)
0.0, 0.0, 0.0, // 观察点 (center)
0.0, 0.0, 1.0 // 上方向 (up)
);
// 按高度着色
pcl::visualization::PointCloudColorHandlerGenericField<pcl::PointXYZ> color_handler(cloud, "z");
viewer->addPointCloud(cloud, color_handler, "colored_cloud");
PointCloudColorHandlerGenericField 默认用彩虹色映射。如果你想要自定义颜色,可以用 PointCloudColorHandlerCustom 手动指定 RGB。
2.4 核心知识体系
为了让你更直观地理解这一节的内容,我画了一张流程图:
这张图把整个流程串起来了:从原始点云出发,根据你的开发环境选择 Open3D 或 PCL,然后调整视角和颜色,最终得到有意义的可视化结果。
2.5 避坑指南
最后,分享几个我踩过的坑:
- 点太多导致卡顿: 我曾经加载一个 500 万点的点云,Open3D 直接卡死。后来学会了下采样再可视化,或者用
draw_geometries的point_show_normal参数只显示法向量。 - 颜色值范围搞错: Open3D 的颜色值范围是 [0, 1],不是 [0, 255]。我第一次用的时候传了 255,结果点云一片白,还以为是 bug。
- PCL 窗口不响应: 在循环里忘了调用
spinOnce,窗口会卡死。记得加上std::this_thread::sleep_for控制刷新频率。
嗯,可视化这块其实不难,但细节决定成败。调好视角和颜色,你的点云数据会“开口说话”。