如何在Open3D(0.10.0)中将点云序列可视化为视频并导出
问题原因排查
方案1问题
- 核心错误是没有对已添加到可视化器的点云对象做原地更新:你在循环中重新给
pcd赋值为新读取的点云对象,而vis.update_geometry()只能更新已经通过add_geometry()注册到可视化器的对象,新赋值的pcd和最开始添加的对象没有关联,所以画面不会更新。 Path.iterdir()返回的文件顺序是系统默认排序,不会自动按01.pcd、02.pcd的数字顺序排列,可能出现帧顺序错乱。- 没有加帧间延时,循环执行速度极快,即使更新正常也看不到逐帧切换的效果。
方案2问题
draw_geometries_with_custom_animation()的入参是同一帧需要同时渲染的所有几何体列表,不是逐帧切换的序列,API本身是用来定制视角动画的,不支持帧序列切换逻辑,所以所有点云会同时显示。
正确实现代码
下面的代码同时支持实时序列可视化,以及导出为MP4格式视频,需要先安装依赖:pip install open3d opencv-python numpy
import open3d as o3d import cv2 import numpy as np from pathlib import Path # 配置参数 pcs_path = Path("point_clouds") frame_delay_ms = 100 # 每帧停留时间,单位毫秒 export_video = True # 是否导出视频 output_video_path = "point_cloud_seq.mp4" fps = 10 # 导出视频的帧率 # 按数字顺序排序pcd文件,避免顺序错乱 pcd_files = sorted(pcs_path.glob("*.pcd"), key=lambda x: int(x.stem)) if not pcd_files: raise FileNotFoundError("未找到pcd文件") # 初始化可视化器 vis = o3d.visualization.Visualizer() vis.create_window(visible=True) # 不需要实时查看可设为False加快导出速度 # 先读取第一帧添加到可视化器 pcd = o3d.io.read_point_cloud(str(pcd_files[0])) vis.add_geometry(pcd) # 导出视频需要先获取画面尺寸 if export_video: vis.poll_events() vis.update_renderer() img = vis.capture_screen_float_buffer() height, width = np.asarray(img).shape[:2] # 初始化视频写入器 fourcc = cv2.VideoWriter_fourcc(*'mp4v') video_writer = cv2.VideoWriter(output_video_path, fourcc, fps, (width, height)) # 逐帧处理 for pcd_file in pcd_files: # 原地更新点云的点和颜色属性,不要重新赋值pcd变量 new_pcd = o3d.io.read_point_cloud(str(pcd_file)) pcd.points = new_pcd.points if new_pcd.has_colors(): pcd.colors = new_pcd.colors # 更新可视化 vis.update_geometry(pcd) vis.poll_events() vis.update_renderer() # 导出当前帧 if export_video: img = np.asarray(vis.capture_screen_float_buffer()) # OpenCV默认使用BGR格式,需做通道转换 img_bgr = cv2.cvtColor((img * 255).astype(np.uint8), cv2.COLOR_RGB2BGR) video_writer.write(img_bgr) # 帧间延时 o3d.utility.wait(frame_delay_ms) # 释放资源 vis.destroy_window() if export_video: video_writer.release() print(f"视频已导出至:{output_video_path}")
内容的提问来源于stack exchange,提问作者dranaivo
相关产品推荐
相关产品推荐

