Dexcap复现代码数据预处理全流程(四)——demo_clipping_3d.py

此脚本的主要功能是可视化点云数据文件(.pcd 文件),并通过键盘交互选择演示数据的起始帧和结束帧,生成片段标记文件 (clip_marks.json)

主要流程包括:

  • 用户指定数据目录:检查目录是否存在并处理标记文件 ->
  • 加载帧数据并渲染:使用 Open3D 可视化点云数据和几何结构 ->
  • 监听键盘输入:通过键盘动态导航帧,并标记片段的起始和结束 ->
  • 保存标记数据:将标记的片段保存为 JSON 文件

目录

1 库引用

2 主程序入口

3 处理 clip_marks.json 文件

3 初始化 ReplayDataVisualizer

4 键盘交互

5 回放帧可视化


1 库引用

import argparse
import os
import copy
import zmq
import cv2
import sys
import json
import shutil
import open3d as o3d
import numpy as np
import platform
from pynput import keyboard
from transforms3d.quaternions import qmult, quat2mat
from transforms3d.axangles import axangle2mat
from scipy.spatial.transform import Rotation
from transforms3d.euler import quat2euler, mat2euler, quat2mat, euler2mat
from visualizer import *# 全局变量定义
clip_marks = []  # 存储所有片段标记
current_clip = {}  # 当前片段的起始和结束标记
next_frame = False  # 用于指示是否跳转到下一帧
previous_frame = False  # 用于指示是否跳转到上一帧

2 主程序入口

# 主程序入口
if __name__ == "__main__":# 解析命令行参数parser = argparse.ArgumentParser(description="Visualize saved frame data.")parser.add_argument("--directory", type=str, default="./saved_data", help="Directory with saved data")args = parser.parse_args()# 检查输入目录是否存在assert os.path.exists(args.directory), f"given directory: {args.directory} not exists"

解析命令行参数 -> 检查并处理 clip_marks.json -> 初始化数据可视化器 -> 启动回放帧可视化,并监听用户交互

命令行参数解析与输入校验:

1. 解析命令行参数:--directory 参数指定数据目录,默认为 ./saved_data

2. 校验输入路径:检查指定目录是否存在,否则直接报错退出

3 处理 clip_marks.json 文件

    # 检查是否已有 clip_marks.json 文件,避免误覆盖if os.path.exists(os.path.join(args.directory, 'clip_marks.json')):response = (input(f"clip_marks.json already exists. Do you want to override? (y/n): ").strip().lower())if response != "y":print("Exiting program without overriding the existing directory.")sys.exit()

如果 clip_marks.json 已存在,提示用户是否覆盖:

  • 输入 y:继续运行,并允许覆盖文件
  • 输入其他内容:程序退出,避免覆盖原有标记数据

3 初始化 ReplayDataVisualizer

    # 数据目录dataset_folder = args.directory# 初始化可视化器visualizer = ReplayDataVisualizer(args.directory)# 加载左右手校准数据(偏移和旋转)visualizer.right_hand_offset = np.loadtxt("{}/calib_offset.txt".format(args.directory))visualizer.right_hand_ori_offset = np.loadtxt("{}/calib_ori_offset.txt".format(args.directory))visualizer.left_hand_offset = np.loadtxt("{}/calib_offset_left.txt".format(args.directory))visualizer.left_hand_ori_offset = np.loadtxt("{}/calib_ori_offset_left.txt".format(args.directory))# 开始帧回放和交互visualizer.replay_frames()

初始化自定义类 ReplayDataVisualizer,继承自 DataVisualizer 类

从文件中加载左右手的偏移数据(位置偏移和旋转偏移),用于调整点云的显示

4 键盘交互

# 键盘按下事件的回调函数
def on_press(key):"""当键盘按键被按下时触发。根据按键执行相应的功能,例如帧跳转、标记起始/结束、保存标记等。"""global next_frame, previous_frame, frame, clip_marks, current_clip# 当前帧的文件夹名frame_folder = 'frame_{}'.format(frame)# 根据键盘按键的类型执行操作if key == keyboard.Key.up:  # 按下“上箭头”保存当前所有标记到 JSON 文件with open(os.path.join(dataset_folder, 'clip_marks.json'), 'w') as f:json.dump(clip_marks, f, indent=4)elif key == keyboard.Key.down:  # 按下“下箭头”跳转到上一帧previous_frame = Trueelif key == keyboard.Key.page_down:  # 按下“Page Down”键跳转到下一帧next_frame = Trueelif key == keyboard.Key.end:  # 按下“End”键标记当前片段结束if 'start' in current_clip.keys():  # 只有当前片段有起点时才允许结束print("end", frame_folder)current_clip['end'] = frame_folder  # 设置结束帧clip_marks.append(current_clip)  # 将当前片段添加到标记列表current_clip = {}  # 清空当前片段elif key == keyboard.Key.insert:  # 按下“Insert”键标记当前片段开始print("start", frame_folder)current_clip['start'] = frame_folder  # 设置起始帧else:print("Key error", key)  # 其他按键未定义功能

监听键盘输入,并根据按键触发相应功能:

  • Insert:标记当前帧为片段的起始帧
  • End:标记当前帧为片段的结束帧,并保存到 clip_marks 列表
  • Page Down:跳转到下一帧
  • Down Arrow:跳转到上一帧
  • Up Arrow:将标记的片段保存到 clip_marks.json 文件

5 回放帧可视化

# 定义自定义可视化类,继承 DataVisualizer
class ReplayDataVisualizer(DataVisualizer):def __init__(self, directory):"""初始化 ReplayDataVisualizer 类:param directory: 数据目录路径"""super().__init__(directory)def replay_frames(self):"""帧回放和交互函数。可视化点云数据,并支持用户通过键盘交互切换帧和标记片段。"""global next_frame, previous_frame, frame# 初始化基准帧if self.R_delta_init is None:self.initialize_canonical_frame()# 加载初始帧数据self._load_frame_data(frame)# 将几何体添加到可视化场景中self.vis.add_geometry(self.pcd)  # 添加点云self.vis.add_geometry(self.coord_frame_1)  # 添加坐标系1self.vis.add_geometry(self.coord_frame_2)  # 添加坐标系2self.vis.add_geometry(self.coord_frame_3)  # 添加坐标系3for joint in self.left_joints + self.right_joints:  # 添加所有关节self.vis.add_geometry(joint)for cylinder in self.left_line_set + self.right_line_set:  # 添加所有连杆self.vis.add_geometry(cylinder)# 使用键盘监听器处理交互事件try:with keyboard.Listener(on_press=on_press) as listener:while True:# 跳转到下一帧if next_frame:next_frame = Falseframe += 10  # 每次跳转10帧# 跳转到上一帧if previous_frame:previous_frame = Falseframe -= 10  # 每次返回10帧# 加载新帧数据self._load_frame_data(frame)# 更新几何体的显示self.vis.update_geometry(self.pcd)self.vis.update_geometry(self.coord_frame_1)self.vis.update_geometry(self.coord_frame_2)self.vis.update_geometry(self.coord_frame_3)for joint in self.left_joints + self.right_joints:self.vis.update_geometry(joint)for cylinder in self.left_line_set + self.right_line_set:self.vis.update_geometry(cylinder)# 渲染场景self.vis.poll_events()self.vis.update_renderer()listener.join()finally:# 输出累积校正信息(如果有)print("cumulative_correction ", self.cumulative_correction)

加载并可视化当前帧数据:渲染点云数据和其他几何体(坐标系、关节、连杆等)

键盘监听:根据用户输入跳转到下一帧或上一帧

更新渲染:每次跳转后重新加载当前帧数据,并更新渲染场景

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/66390.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

k8s修改存储目录-介绍

k8s修改存储目录-介绍 文章目录 k8s修改存储目录-介绍总结:介绍指定 Docker 或 containerd 镜像和容器存储目录Docker 存储目录containerd 存储目录 指定 Kubelet 的存储目录指定 Pod 和容器存储目录 docker 运行时,迁移目录实操:https://blo…

【华为OD-E卷 - 热点网站统计 100分(python、java、c++、js、c)】

【华为OD-E卷 - 热点网站统计 100分(python、java、c、js、c)】 题目 企业路由器的统计页面,有一个功能需要动态统计公司访问最多的网页URL top N。请设计一个算法,可以高效动态统计Top N的页面 输入描述 每一行都是一个URL或…

安装Cockpit服务,使用Web页面管理你的Linux服务器

说起管理 Linux 服务器,大家首先想到的使用 SecureCRT、Xshell、MobaXterm 等工具远程到服务器,然后使用命令行管理服务器。今天给大家介绍一个好玩的工具,名字叫Cockpit, Cockpit 是一个免费开源的基于 web 的 Linux 服务器管理…

[A-25]ARMv8/v9-GIC的系统架构(中断的硬件基础)

ver0.1 前言 我们在观看很多的影视剧过程中,尤其是军旅体裁类型的布景中,经常会看见高级干部的办公桌上都会有几部电话机。这样的电话可不能小看,重要的事情尤其是突发和紧急的情况都要通过这几部电话第一时间通知给决策者。这几部电话,必须举报几个特点:及时性好、稳定…

ffmpeg将mp4等文件转mp3

安装ffmpeg 目录 安装ffmpeg macOS Windows 实现方法 Base Golang macOS 在macOS上,你可以使用Homebrew来安装FFmpeg,这是最简单和推荐的方法。以下是具体步骤: ‌安装Homebrew‌(如果尚未安装): 打开终端,执行以下命令来安装Homebrew: /bin/bash -c "$(c…

13-线段的转折点样式

13-线段的转折点样式_哔哩哔哩_bilibili13-线段的转折点样式是一次性学会 Canvas 动画绘图(核心精讲50个案例)2023最新教程的第14集视频,该合集共计53集,视频收藏或关注UP主,及时了解更多相关视频内容。https://www.bi…

计算机网络 (28)虚拟专用网VPN

前言 虚拟专用网络(VPN)是一种在公共网络上建立私有网络连接的技术,它允许远程用户通过加密通道访问内部网络资源,实现远程办公和安全通信。 一、基本概念 定义:VPN是一种通过公共网络(如互联网&#xff09…

基于transformer的目标检测:DETR

目录 一、背景介绍 二、DETR的工作流程 三、DETR的架构 1. 损失函数 2. 网络框架讲解及举例 一、背景介绍 在深度学习和计算机视觉领域,目标检测一直是一个核心问题。传统方法依赖于复杂的流程和手工设计的组件,如非极大值抑制(nms&…

代码随想录18

20. 有效的括号 给定一个只包括 (,),{,},[,] 的字符串,判断字符串是否有效。 有效字符串需满足: 左括号必须用相同类型的右括号闭合。左括号必须以正确的顺序闭合。注意空字符串可被认为是有…

Vue Amazing UI 组件库(Vue3+TypeScript+Vite 等最新技术栈开发)

Vue Amazing UI 一个 Vue 3 组件库 使用 TypeScript,都是单文件组件 (SFC),支持 tree shaking 有点意思 English | 中文 Vue Amazing UI 是一个基于 Vue 3、TypeScript、Vite 等最新技术栈开发构建的现代化组件库,包含丰富的 UI 组件和常…

git:指令集

以下是对这些 Git 新特性和命令的更详细解读和实际用例分析,帮助更好地理解它们的作用及适用场景: 1. git switch 和 git restore 背景: 传统上,git checkout 是一个多功能命令,用于切换分支、检出文件、创建分支等&…

C语言----指针

目录 1.概念 2.格式 3.指针操作符 4.初始化 1. 将普通变量的地址赋值给指针变量 a. 将数组的首地址赋值给指针变量 b. 将指针变量里面保存的地址赋值给另一个指针变量 5.指针运算 5.1算术运算 5.2 关系运算 指针的大小 总结: 段错误 指针修饰 1. con…

ElasticSearch系列(一)

一.了解ES、倒排索引、es的一些概念、安装es、kibana 二.DSL;索引库操作 三.Java RestClient:索引库操作 一、了解ES、倒排索引、es的一些概念、安装es、kibana kibana、logstash、beats Elasticserach 存储,计算 ,搜索数据 –…

Python应用——将Matplotlib图形嵌入Tkinter窗口

Python应用——将Matplotlib图形嵌入Tkinter窗口 目录 Python应用——将Matplotlib图形嵌入Tkinter窗口1 模块简介2 示例代码2.1 Matplotlib嵌入Tkinter2.2 Matplotlib嵌入Tkinter并显示工具栏 1 模块简介 Tkinter是Python的标准GUI(图形用户界面)库&…

C#语言的网络编程

C#语言的网络编程 引言 随着互联网的飞速发展,网络编程成为了软件开发中的一个重要领域。C#语言作为一种现代编程语言,凭借其丰富的类库、良好的可读性和强大的功能,广泛应用于开发各种网络应用程序。无论是Windows应用、Web应用还是云服务…

软件工程大复习之(四)——面向对象与UML

4.1 面向对象概述 面向对象(OO)是一种编程范式,它将数据和处理数据的方法封装在对象中。面向对象的主要概念包括: 对象:实例化的数据和方法的集合。类:对象的蓝图或模板。封装:隐藏对象的内部…

【linux基础I/O(2)】理解文件系统|文件缓冲区|软硬链接|动静态库

目录 前言1. 理解C语言的缓冲区2. 对文件系统的初认识3. 理解软硬链接1. 软硬链接的特征2.软硬链接的作用 4. 理解动静态库5. 总结 前言 对于文件来讲,有打开的在内存中的文件,也有没有打开的在磁盘上文件,上一篇文章讲解的是前者,本篇文章将带大家了解后者! 本章重点: 本篇文…

什么是Redis的渐进式ReHash?

文章内容收录到个人网站,方便阅读:http://hardyfish.top/ 文章内容收录到个人网站,方便阅读:http://hardyfish.top/ 文章内容收录到个人网站,方便阅读:http://hardyfish.top/ Redis 的渐进式 rehash 是一…

Linux应用软件编程--网络通信(udp协议,tcp协议)

网络通信:不同主机,进程间通信,分为广域网和局域网 OSI 七层模型:是一种理论模型 应用层:通信传输的数据内容 http、FTP、TFTP、MQTT 表述层:数据加密,解密操作,压缩&#xff…

深度学习,训练集准确率高,但验证集准确率一直不上升,很低的问题

在训练过程中,训练集的准确率稳步上升,但是验证集的准确率一直在40%左右徘徊,从网上搜索可能的原因有: 1、学习率太小,陷入局部最优。 2、数据量太小(4000多条数据,应该还可以吧) …