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

news/2025/1/10 21:25:52/

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

主要流程包括:

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

目录

1 库引用

2 主程序入口

3 处理 clip_marks.json 文件

3 初始化 ReplayDataVisualizer

4 键盘交互

5 回放帧可视化


1 库引用

python">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 主程序入口

python"># 主程序入口
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 文件

python">    # 检查是否已有 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

python">    # 数据目录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 键盘交互

python"># 键盘按下事件的回调函数
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 回放帧可视化

python"># 定义自定义可视化类,继承 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.ppmy.cn/news/1562065.html

相关文章

负载均衡技术【内网去外网运营商出口负载均衡】

1 负载均衡概述 LB(Load Balance,负载均衡)是一种集群技术,它将特定的业务(网络服务、网络流量等)分担给多台网络设备(包括服务器、防火墙等)或多条链路,从而提高了业务…

github 个人主页配置

Guthub 个人主页 (官方称呼是 profile)可以展示很多有用的信息,例如添加一个首页被访问次数的计数器,一个被 Star 与 Commit 的概览信息,以及各种技能标签,设备标签等,还可以利用 wakatime 显示…

Flink概念知识讲解之:Restart重启策略配置

Flink概念知识讲解之:Restart重启策略配置 当 Task 发生故障时,Flink 需要重启出错的 Task 以及其他受到影响的 Task ,以使得作业恢复到正常执行状态。 Flink 通过重启策略和故障恢复策略来控制 Task 重启:重启策略决定是否可以…

iOS - 数组的真实类型

1. NSArray 类簇 // 1. __NSArray0 (空数组) NSArray *empty [];// 2. __NSArrayI (不可变数组) NSArray *immutable [1, 2, 3];// 3. __NSArrayM (可变数组) NSMutableArray *mutable [NSMutableArray array];// 4. __NSSingleObjectArrayI (单元素数组) NSArray *single …

代码管理助手-Git

前言 Git 是一个版本控制系统,可以帮助你记录文件的每一次修改。这样,如果你在编程时不小心把代码写错了,可以很容易地回退到之前的版本。最重要的是,Git 是完全免费的,用户可以在自己的计算机上安装和使用 Git&#x…

【形式篇】年终总结怎么写:PPT如何将内容更好地表现出来

——细节满满,看完立马写出一篇合格的PPT 总述 形式服务于内容,同时合理的形式可以更好地表达和彰显内容 年终总结作为汇报型PPT,内容一定是第一位的,在内容篇(可点击查看)已经很详细地给出了提纲思路,那如何落实到…

java-type-tool 轻量级java type工具类库

java-type-tool 轻量级java type工具类库.链接地址 https://github.com/joker-pper/java-type-tool https://gitee.com/joker-pper/java-type-tool 引入方式 <dependencies><dependency><groupId>io.github.joker-pper</groupId><artifactId>j…

LabVIEW瞬变电磁接收系统

利用LabVIEW软件与USB4432采集卡开发瞬变电磁接收系统。系统通过改进硬件配置与软件编程&#xff0c;解决了传统仪器在信噪比低和抗干扰能力差的问题&#xff0c;实现了高精度的数据采集和处理&#xff0c;特别适用于地质勘探等领域。 ​ 项目背景&#xff1a; 瞬变电磁法是探…