使用 Open3D 批量渲染并导出固定视角点云截图
一、前言
在三维点云处理与可视化中,固定视角批量生成点云渲染截图是一个常见的需求。例如,想要将同一系列的点云(PCD 文件)在同样的视角下生成序列图片,以便后续合成为视频或进行其他可视化演示。本文将介绍如何使用 Python + Open3D 实现批量加载 PCD 文件、设置统一的相机视角,并导出渲染截图。
二、环境准备
- Python 环境:建议使用 Python 3.7+。
- Open3D 库:本文使用的是
open3d和open3d.visualization.gui。安装方式如下:pip install open3d - 其他依赖库:
numpypickleglobtimeos
如果缺少对应的库,使用pip install 库名即可。
三、代码解析
下面的代码分为几个主要部分:
- 相机矩阵转换:将 Open3D 的模型矩阵转换为外参矩阵。
- 相机内参生成:根据视口大小与视场角(FOV)生成相机内参。
- 保存与加载相机视角:使用
pickle将当前相机的内外参持久化保存,方便在下次使用时快速恢复相机位置。 - 批量处理函数:遍历指定文件夹下所有
.pcd文件,加载点云、应用相机视角、并自动保存渲染截图。 - 主函数:在
if __name__ == "__main__":中调用批处理函数,或先进行单独的相机视角设置保存操作。
完整代码如下(可直接复制使用):
import numpy as np
import open3d as o3d
import open3d.visualization.gui as gui
from pickle import load, dump
import os
import glob
import time# 用于将坐标系转换为OpenGL风格
ToGLCamera = np.array([[1, 0, 0, 0],[0, -1, 0, 0],[0, 0, -1, 0],[0, 0, 0, 1]
])
FromGLGamera = np.linalg.inv(ToGLCamera)def model_matrix_to_extrinsic_matrix(model_matrix):"""将Open3D的model_matrix转换为外参矩阵"""return np.linalg.inv(model_matrix @ FromGLGamera)def create_camera_intrinsic_from_size(width=1024, height=768, hfov=60.0, vfov=60.0):"""根据视口大小与水平/垂直FOV生成相机内参"""fx = (width / 2.0) / np.tan(np.radians(hfov) / 2)fy = (height / 2.0) / np.tan(np.radians(vfov) / 2)return np.array([[fx, 0, width / 2.0],[0, fy, height / 2.0],[0, 0, 1]])def save_view(vis, fname='saved_view.pkl'):"""保存当前可视化窗口的相机视角(内参、外参、图像尺寸)"""try:model_matrix = np.asarray(vis.scene.camera.get_model_matrix())extrinsic = model_matrix_to_extrinsic_matrix(model_matrix)width, height = vis.size.width, vis.size.heightintrinsic = create_camera_intrinsic_from_size(width, height)saved_view = dict(extrinsic=extrinsic, intrinsic=intrinsic, width=width, height=height)with open(fname, 'wb') as pickle_file:dump(saved_view, pickle_file)print(f"Camera view saved to {fname}")except Exception as e:print("Error saving view:", e)def load_view(vis, fname="saved_view.pkl"):"""加载已保存的相机视角(内参、外参、图像尺寸)"""try:with open(fname, 'rb') as pickle_file:saved_view = load(pickle_file)vis.setup_camera(saved_view['intrinsic'], saved_view['extrinsic'],saved_view['width'], saved_view['height'])print(f"Camera view loaded from {fname}")except Exception as e:print("Can't load view file:", e)def process_pcd_folder(input_folder, output_folder, view_file='saved_view.pkl'):"""批量处理文件夹中的所有 PCD 文件,应用指定视角并保存截图"""os.makedirs(output_folder, exist_ok=True)pcd_files = sorted(glob.glob(os.path.join(input_folder, "*.pcd")))if not pcd_files:print(f"No PCD files found in {input_folder}")returnprint(f"Found {len(pcd_files)} PCD files")# 初始化GUIgui.Application.instance.initialize()vis = o3d.visualization.O3DVisualizer("PCD Batch Renderer", 1920, 1080)gui.Application.instance.add_window(vis)# 设置渲染参数vis.point_size = 4vis.show_axes = Falsevis.show_skybox(False)def process_next(idx):if idx >= len(pcd_files):print("Batch processing completed!")gui.Application.instance.quit()returnpcd_file = pcd_files[idx]print(f"Processing {idx+1}/{len(pcd_files)}: {os.path.basename(pcd_file)}")try:# 加载点云文件pcd = o3d.io.read_point_cloud(pcd_file)geom_name = f"PointCloud_{idx}"# 清除之前所有几何体,确保内存资源不会累积if idx > 0:vis.remove_geometry(f"PointCloud_{idx-1}")vis.add_geometry(geom_name, pcd)# 加载预先保存的视角load_view(vis, view_file)# 构建输出路径base_name = os.path.splitext(os.path.basename(pcd_file))[0]output_path = os.path.join(output_folder, f"{base_name}.png")def take_screenshot():# 延迟1秒以确保视角和渲染完全加载time.sleep(1)vis.export_current_image(output_path)print(f"Screenshot saved to {output_path}")# 处理完当前文件后,处理下一个process_next(idx + 1)# 使用post_to_main_thread确保截图任务在GUI线程执行gui.Application.instance.post_to_main_thread(vis, take_screenshot)except Exception as e:print(f"Error processing {pcd_file}: {e}")# 出错时跳过当前文件,继续下一个process_next(idx + 1)# 开始处理第一个文件process_next(0)gui.Application.instance.run()def batch_process():"""主函数:指定输入、输出文件夹以及相机视角文件,然后进行批量处理"""input_folder = './input'output_folder = './screenshots'os.makedirs(output_folder, exist_ok=True)view_file = 'saved_view.pkl'process_pcd_folder(input_folder, output_folder, view_file)if __name__ == "__main__":# 若需要先设置视角,运行 save_view 所在的逻辑# 若已设置好视角,运行 batch_process()批量处理batch_process()
1. 代码主要流程
- 读取文件列表:通过
glob.glob获取指定文件夹下的所有.pcd文件并排序。 - 初始化 Open3D GUI:使用
O3DVisualizer进行可视化。 - 循环处理每个 PCD:
- 读取点云数据
pcd = o3d.io.read_point_cloud(...) - 加载之前保存的视角参数
load_view(vis, view_file) - 设置几何体到渲染窗口
- 通过
vis.export_current_image(...)将当前视图截图保存
- 读取点云数据
- 处理结束后退出:当全部
.pcd文件处理完毕,自动退出 GUI。
2. 视角保存与加载
save_view(vis, fname='saved_view.pkl'):从当前的vis.scene.camera获取model_matrix,然后计算外参矩阵、内参矩阵并存储到一个字典中,通过pickle持久化到saved_view.pkl文件。load_view(vis, fname='saved_view.pkl'):从文件中读取上述字典,调用vis.setup_camera(...)将相机恢复到保存时的视角。
这样做的好处是,我们可以先交互式地在 Open3D 中调整一个理想的点云视角,然后保存该视角。后续就可以用同样的参数去渲染其他点云,实现“统一视角”输出。
3. 视角设置的两种方式
- 先在单个点云上用脚本交互式设置并保存:
- 先运行一个类似的脚本,只加载一个点云,不做批处理。
- 在界面中使用鼠标旋转/平移点云至理想位置,然后调用
save_view(vis)。
- 直接修改代码中的相机参数:如果你对内参、外参很熟悉,也可以直接硬编码想要的矩阵。
四、使用说明
- 准备 PCD 文件:将所有需要处理的
.pcd文件放在同一个文件夹中。 - 保存视角(可选):
- 若你已知道要使用的视角参数,可以跳过这一步;否则先写个简单脚本,加载一两个 PCD 文件后,通过交互操作找到满意的视角,执行
save_view(vis)。 - 此时会生成一个
saved_view.pkl文件,里面记录了相机的内外参。
- 若你已知道要使用的视角参数,可以跳过这一步;否则先写个简单脚本,加载一两个 PCD 文件后,通过交互操作找到满意的视角,执行
- 运行批处理:
- 修改
batch_process()中的input_folder和output_folder为你的输入、输出路径。 - 运行脚本后,Open3D 窗口会依次加载每个
.pcd,应用保存好的视角,然后自动截图并存储到output_folder中。
- 修改
在所有点云都处理完后,你就能在输出文件夹下看到对应的 .png 文件序列。
五、结果展示
下面是一张示例截图,展示了点云在固定视角下的渲染效果(仅做示意,非实际数据):

六、后续扩展
- 生成视频:如果想将渲染好的序列图片合成为视频,可使用
ffmpeg,示例命令如下:
其中ffmpeg -framerate 10 -i labeled_sync_frame_%03d.png -c:v libx264 -pix_fmt yuv420p output.mp4-framerate 10表示每秒 10 帧,可根据需要调整。 - 更多可视化选项:如改变
point_size、背景颜色、或添加坐标轴等,可参考 Open3D 文档或修改O3DVisualizer的属性。 - 其他文件格式:如果想批量处理
.ply或.xyz,只需要在代码中修改对应的读取方式,以及glob.glob匹配模式即可。
七、总结
通过上述方法,可以轻松地在同一视角下对多份点云进行批量渲染和截图,适用于制作点云动画、对比分析等场景。核心思想是事先保存好相机参数,并在批处理过程中为每个点云恢复相同的内外参,保证输出图像的视角一致。希望对你的三维可视化工作有所帮助,欢迎交流讨论!
相关文章:
使用 Open3D 批量渲染并导出固定视角点云截图
一、前言 在三维点云处理与可视化中,固定视角批量生成点云渲染截图是一个常见的需求。例如,想要将同一系列的点云(PCD 文件)在同样的视角下生成序列图片,以便后续合成为视频或进行其他可视化演示。本文将介绍如何使用…...
汽车无钥匙进入一键启动操作正确步骤
汽车智能无钥匙进入和一键启动的技术在近年来比较成熟,不同车型的操作步骤可能略有不同,但基本的流程应该是通用的,不会因为时间变化而有大的改变。 移动管家汽车一键启动无钥匙进入系统通常是通过携带钥匙靠近车辆,然后触摸门把…...
JMeter 的基础知识-安装部分
以下将从环境配置开始,为你详细介绍 JMeter 的基础知识,涵盖环境搭建、界面认知、测试计划创建、常用组件使用等方面内容。 1. 环境配置 1.1 安装 Java JMeter 是基于 Java 开发的,所以需要先安装 Java 开发工具包(JDK)。 下载 JDK:访问 Oracle 官方网站(https://www…...
解决后端跨域问题
目录 一、什么是跨域问题? 1、跨域问题的定义 2、举例 3、为什么会有跨域问题的存在? 二、解决跨域问题 1、新建配置类 2、编写代码 三、结语 一、什么是跨域问题? 1、跨域问题的定义 跨域问题(Cross-Origin Resource Sh…...
补题A-E Codeforces Round 953 (Div. 2)
https://codeforces.com/contest/1979 A. Guess the Maximum 原题链接:https://codeforces.com/contest/1979/problem/A 求相邻元素的最大值的最小值。 #include <bits/stdc.h> using namespace std; #define IOS ios::sync_with_stdio(0), cin.tie(0), cout…...
【WordPress】发布文章时自动通过机器人推送到钉钉
在您的主题下functions.php中添加如下代码: function wpso_dingding_publish_notify($post_ID) {// 获取文章对象$post get_post($post_ID);// 检查是否是文章首次发布(即不是修订版)if (get_post_status($post_ID) publish && !g…...
鸿蒙开发深入浅出04(首页数据渲染、搜索、Stack样式堆叠、Grid布局、shadow阴影)
鸿蒙开发深入浅出04(首页数据渲染、搜索、Stack样式堆叠、Grid布局、shadow阴影) 1、效果展示2、ets/pages/Home.ets3、ets/views/Home/SearchBar.ets4、ets/views/Home/NavList.ets5、ets/views/Home/TileList.ets6、ets/views/Home/PlanList.ets7、后端…...
管道文件(1)
1.无名管道:在同一主机下,具有亲缘关系的进程间的通信,如父子进程间的通信。 2.有名管道:在同一主机下的任意进程间的通信。 (1)管道的创建 (2)管道的打开(openÿ…...
什么是AI agent技术,有哪些著名案例
AI Agent技术是一种基于人工智能的智能实体,能够感知环境、进行决策和执行动作,以实现特定目标。近年来,随着大模型(如GPT-4)和生成式AI技术的发展,AI Agent在多个领域得到了广泛应用,并取得了显…...
Cursor结合Claude 3.7零基础开发愤怒的小鸟【深夜Claude 3.7系列发布,类似DeepSeek-R1和V3的合体?】
文章目录 前言介绍“市面上唯一的混合模型”卓越的编程能力、精准控制思考时间Cursor已接入Cursor结合Claude 3.7快速编写游戏完整html代码 🍃作者介绍:双非本科大四网络工程专业在读,阿里云专家博主,前三年专注于Java领域学习&am…...
基于 Python 的天气数据分析与可视化
基于 Python 的天气数据分析与可视化 1. 项目背景 天气数据分析与可视化项目旨在通过爬取天气数据并进行分析,生成可视化图表,帮助用户了解天气变化趋势。通过该项目,学生可以掌握 Python 的数据爬取、数据分析和可视化技能。该项目适用于气…...
Bybit事件技术分析
事件概述 2025年2月21日UTC时间下午02:16:11,Bybit的以太坊冷钱包(0x1db92e2eebc8e0c075a02bea49a2935bcd2dfcf4)因恶意合约升级遭到资金盗取。根据Bybit CEO Ben Zhou的声明,攻击者通过钓鱼攻击诱骗冷钱包签名者错误签署恶意交易…...
JavaWeb-在idea中配置Servlet项目
文章目录 在idea中进行Servlet项目的配置(较新的idea版本)创建一个空的JavaSE项目(Project)创建一个普通的JavaSE板块(module)添加Web项目的配置定义一个对象模拟实现接口在web.xml中配置路径映射配置项目到Tomcat服务器启动Tomcat服务器进行测试 在idea中进行Servlet项目的配置…...
redis小记
redis小记 下载redis sudo apt-get install redis-server redis基本命令 ubuntu16下的redis没有protected-mode属性,就算sudo启动,也不能往/var/spool/cron/crontabs写计划任务,感觉很安全 #连接到redis redis-cli -h 127.0.0.1 -p 6379 …...
垂类大模型微调(一):认识LLaMA-Factory
LlamaFactory 是一个专注于 高效微调大型语言模型(LLMs) 的开源工具框架,尤其以支持 LLaMA(Meta 的大型语言模型系列)及其衍生模型(如 Chinese-LLaMA、Alpaca 等)而闻名。它的目标是简化模型微调流程,降低用户使用门槛; 官方文档 一、介绍 高效微调支持 支持多种微调…...
企业为什么要选择软件测试外包公司?湖南软件测试公司有哪些?
在当今快速发展的技术背景下,软件测试已成为软件开发生命周期的重要一环。随着企业对软件质量要求的不断提高,软件测试外包公司逐渐被越来越多的企业所青睐。 软件测试外包公司通过将软件测试从内部团队外包出去,帮助企业减少开发成本、提升…...
数据保护API(DPAPI)深度剖析与安全实践
Windows DPAPI 安全机制解析 在当今数据泄露与网络攻击日益频繁的背景下,Windows 提供的 DPAPI(Data Protection API)成为开发者保护本地敏感数据的重要工具。本文将从 双层密钥体系、加密流程、跨上下文加密、已知攻击向量与防御措施、企业…...
java23种设计模式-桥接模式
桥接模式(Bridge Pattern)学习笔记 🌟 定义 桥接模式属于结构型设计模式,将抽象部分与实现部分分离,使它们可以独立变化。通过组合代替继承的方式,解决多维度的扩展问题,防止类爆炸。 &#x…...
3D Web轻量化引擎HOOPS Communicator如何赋能航空航天制造?
在当今航空航天制造领域,精确度、效率和协作是推动行业发展的关键要素。随着数字化技术的飞速发展,3D Web可视化开发包HOOPS Communicator 为航空航天制造带来了革命性的变化。它凭借强大的功能和灵活的应用,助力企业在设计、生产、培训等各个…...
iOS手机App爬虫- (1) Mac安装Appium真机运行环境
iOS手机App爬虫 一、环境准备与工具安装1. 开发基础环境配置1.1 Node.js环境1.2 Xcode套件1.3 Java环境 2. 核心测试工具链2.1 Appium主程序2.2 辅助工具集 3. 可视化工具 二、设备与环境验证1. 设备信息获取2. 环境健康检查 三、WebDriverAgent编译部署1. 设备端准备2. 项目配…...
消防主机组网通信质量有担忧?巧用光纤环网冗余方案,实现超远距离、高可靠CAN通讯
摘要:在大型园区、隧道、高层建筑等消防报警系统中,如何将分散各处的消防主机(如海湾、青鸟、利达等品牌)稳定可靠地联网,并实现长距离、抗干扰的数据传输,一直是工程实践的难点。本文分享我们如何利用LCAN…...
【实战教程+数据集】YOLOv8车牌识别数据集7811张,从数据标注到模型部署,构建智慧交通车牌检测系统
1. 车牌识别技术为何需要YOLOv8? 车牌识别听起来简单,但实际落地时会遇到各种头疼的问题。我去年帮一个停车场做改造时就深有体会——白天阳光强烈时反光严重,傍晚逆光时车牌变成黑乎乎一片,下雨天水珠还会在车牌上形成光斑。传统…...
3步轻松实现Windows任务栏透明化:TranslucentTB完整使用指南
3步轻松实现Windows任务栏透明化:TranslucentTB完整使用指南 【免费下载链接】TranslucentTB A lightweight utility that makes the Windows taskbar translucent/transparent. 项目地址: https://gitcode.com/gh_mirrors/tr/TranslucentTB 你是否厌倦了Win…...
别再让Simulink-PS Converter报错!手把手教你搞定物理信号转换的滤波与单位设置
物理信号转换实战指南:从Simulink到Simscape的精准控制 在机电系统建模中,信号在不同域间的转换常常成为影响仿真精度的关键环节。想象这样一个场景:你正在设计一套电机控制系统,Simulink中生成的PWM信号需要驱动Simscape中的电机…...
从零部署MinerU文档解析服务:GPU加速、防OOM配置与Docker打包全攻略
从零部署MinerU文档解析服务:GPU加速、防OOM配置与Docker打包全攻略 在AI模型服务化的浪潮中,文档解析作为企业数字化转型的关键环节,正经历着从实验室Demo到生产级服务的蜕变。MinerU-OpenAPI以其多模态处理能力和工业级稳定性,成…...
2026-04-17 全国各地响应最快的 BT Tracker 服务器(电信版)
数据来源:https://bt.me88.top 序号Tracker 服务器地域网络响应(毫秒)1udp://60.249.37.20:6969/announce广东广州电信312http://211.75.210.221:80/announce广东广州电信323http://211.75.205.187:6969/announce广东广州电信324udp://132.226.6.145:6969/announce…...
同样的招聘工作,别人 AI 一周筛选千份简历,你的 HR 要加班一个月:2026企业级实在Agent深度实践
在2026年的春招赛道上,企业间的竞争早已从“人才争夺”演变为“筛选效率”的降维打击。 根据最新的行业观察,头部企业通过部署智能体(Agent)技术,已实现从简历抓取、逻辑初筛到面试预约的全链路自动化。 相比之下&…...
企业级开发 AI Coding 标准流程及个人操作
企业规范个人操作实现流程...
Zotero Reference:3分钟学会PDF文献参考文献自动提取的神器
Zotero Reference:3分钟学会PDF文献参考文献自动提取的神器 【免费下载链接】zotero-reference PDF references add-on for Zotero. 项目地址: https://gitcode.com/gh_mirrors/zo/zotero-reference 还在为手动整理参考文献而烦恼吗?Zotero Refer…...
从零到一:基于mmdetection-3.1.0与RTMDet-Ins-m的自定义数据集实例分割实战
1. 环境准备与mmdetection安装 第一次接触mmdetection框架时,我也被它复杂的依赖关系搞晕过。不过跟着官方文档一步步操作,其实半小时就能搞定。这里分享几个避坑经验:建议使用conda创建虚拟环境,python版本选择3.8最稳妥…...
