2. 点云可视化基础

任务目标

本案例使用Open3D实现点云的基础可视化:加载或生成点云数据,按坐标或自定义颜色渲染,叠加法线显示,并启用交互式旋转与缩放。最终通过可视化窗口验证显示效果。

环境依赖

  • Python 3.8+
  • Open3D 0.17+(pip install open3d)
  • NumPy(pip install numpy)

核心代码

import numpy as np
import open3d as o3d

# 1. 生成示例点云(球面点 + 噪声)
np.random.seed(42)
theta = np.random.uniform(0, 2 * np.pi, 2000)
phi = np.random.uniform(0, np.pi, 2000)
r = 1.0
x = r * np.sin(phi) * np.cos(theta)
y = r * np.sin(phi) * np.sin(theta)
z = r * np.cos(phi)
points = np.stack([x, y, z], axis=1)
points += np.random.normal(0, 0.02, points.shape)  # 轻微噪声

# 2. 创建点云对象并设置颜色(按Z轴高度映射)
pcd = o3d.geometry.PointCloud()
pcd.points = o3d.utility.Vector3dVector(points)

# 颜色映射:z值归一化到[0,1],使用jet-like配色
z_norm = (z - z.min()) / (z.max() - z.min())
colors = np.zeros((len(points), 3))
colors[:, 0] = z_norm          # R
colors[:, 1] = 1 - np.abs(2 * z_norm - 1)  # G
colors[:, 2] = 1 - z_norm      # B
pcd.colors = o3d.utility.Vector3dVector(colors)

# 3. 估计法线(用于法线可视化)
pcd.estimate_normals(
    search_param=o3d.geometry.KDTreeSearchParamHybrid(radius=0.1, max_nn=30)
)

# 4. 创建可视化窗口,启用交互
vis = o3d.visualization.Visualizer()
vis.create_window(window_name="Point Cloud Visualization", width=800, height=600)

# 添加点云(带颜色)
vis.add_geometry(pcd)

# 添加法线显示(每第5个点显示一条法线,避免过于密集)
line_set = o3d.geometry.LineSet()
line_points = []
line_lines = []
normals = np.asarray(pcd.normals)
for i in range(0, len(points), 5):
    line_points.append(points[i])
    line_points.append(points[i] + normals[i] * 0.08)  # 法线长度缩放
    line_lines.append([len(line_points) - 2, len(line_points) - 1])
line_set.points = o3d.utility.Vector3dVector(np.array(line_points))
line_set.lines = o3d.utility.Vector2iVector(np.array(line_lines))
line_set.colors = o3d.utility.Vector3dVector(
    np.tile([1.0, 0.0, 0.0], (len(line_lines), 1))  # 红色法线
)
vis.add_geometry(line_set)

# 5. 设置渲染选项并启动交互循环
opt = vis.get_render_option()
opt.point_size = 2.0
opt.background_color = np.array([0.1, 0.1, 0.1])  # 深色背景

vis.run()  # 阻塞直到窗口关闭
vis.destroy_window()

运行与验证

  1. 将上述代码保存为 visualize_pointcloud.py,在终端执行 python visualize_pointcloud.py。
  2. 预期出现一个800×600的3D窗口,显示彩色球面点云(颜色随Z轴变化),表面叠加红色短线表示法线方向。
  3. 交互验证:按住鼠标左键拖动可旋转视角;滚动滚轮可缩放;按住Ctrl+左键拖动可平移。若窗口能流畅响应这些操作,且点云与法线随视角正确变换,则判定通过。
  4. 数据验证:点云呈近似球形(半径约1.0),法线方向大致沿径向向外(红色短线从表面指向外侧)。

关键说明

  • 法线估计使用KDTree混合搜索,radius=0.1 需根据点云密度调整;若点云更稀疏可适当增大该值。
  • 法线显示每5个点采样一条,避免视觉杂乱;如需更密集显示可改为每2个点或全部显示。
  • 若需加载真实点云文件(如PLY/PCD),将第1步替换为 pcd = o3d.io.read_point_cloud("input.pcd"),并跳过颜色生成逻辑(文件自带颜色时自动显示)。