TLabel:现多传感器触觉数据统一标注与22维特征提取
TLabel:现多传感器触觉数据统一标注与22维特征提取
摘要:本文详细介绍了 TLabel v0.2.0b2 版本的核心更新与完整使用流程。TLabel 是一个用于多传感器触觉数据统一标注与 22 维特征提取的 Python 工具库。本次更新主要包含:1) UI 导出功能升级,新增 JSON/CSV/HDF5 三个一键导出按钮;2) 元数据增强,新增传感器 ID、标定参数、特征名称列表等字段,支持与 LeRobot、RLDS 等机器人学习框架无缝对接;3) LeRobot 双向转换器,实现与 Hugging Face LeRobot 格式的双向转换。文章通过代码实战演示了从安装依赖、加载多传感器数据(GelSight/DIGIT、PaXini、Daimon)、交互式标注与修正到多格式导出的完整流程。技术实现方面,详细解析了 22 维触觉特征定义、适配器模式实现和延迟注册机制。性能优化实践包括背景计算的采样策略和惰性加载与缓存机制。最后提供了常见问题解答和总结。
一、核心更新概览
1.1 UI 导出功能升级
v0.2.0b2 最显著的改进是在交互面板底部新增了三个醒目的导出按钮,用户无需编写代码即可一键导出数据:
import tlabel
# 加载数据
data = tlabel.demo()
# 打开交互面板,底部会显示三个导出按钮
panel = data.review(lang="zh")
# - 💾 导出 JSON(粉红色主按钮)
# - 📊 导出 CSV(粉色边框按钮)
# - 🔬 导出 HDF5(灰色边框按钮)
三种格式对比:
| 格式 | 特点 | 适用场景 |
|---|---|---|
| JSON | 完整 TLabel Format v2 schema,包含元数据 | 数据备份、工具间交换 |
| CSV | 扁平表格格式 | Excel/pandas 分析 |
| HDF5 | 科学计算标准格式 | MATLAB/SciPy、大规模数据集 |
1.2 元数据增强
新增以下元数据字段,解决与下游训练框架的对接问题:
data_dict = data.to_dict()
# 新增字段示例
print(data_dict['sensor_id']) # 传感器唯一标识
print(data_dict['calibration']) # 标定参数
print(data_dict['feature_names']) # 22维特征名称列表
print(data_dict['frames'][0]['is_first']) # Episode边界标记
这些字段对于 LeRobot、RLDS 等机器人学习框架至关重要。
1.3 LeRobot 双向转换器
新增与 Hugging Face LeRobot 格式的双向转换:
from tlabel.converters import lerobot_to_tlabel, tlabel_to_lerobot
# LeRobot Parquet → TLabel(用于标注)
tlabel_data = lerobot_to_tlabel("path/to/lerobot_dataset")
# 标注完成后转回 LeRobot 格式
tlabel_to_lerobot("annotated.json", "output/lerobot_dataset")
自动处理 meta/info.json 和 Parquet 文件,支持自定义触觉字段路径。
二、完整使用流程(代码实战)
2.1 安装依赖
# 核心包(仅 numpy 依赖)
pip install tlabel==0.2.0b2
# 根据传感器类型安装额外依赖
pip install tlabel[gelsight] # GelSight/DIGIT(需要 opencv-python)
pip install tlabel[paxini] # PaXini(需要 h5py)
pip install tlabel[daimon] # Daimon(需要 pyarrow)
2.2 加载多传感器数据
TLabel 支持三种主流触觉传感器的自动识别和加载:
import tlabel
# GelSight / DIGIT(视觉型触觉传感器)
data_gelsight = tlabel.load("gelsight_episode.pkl")
# PaXini PXCap(分布式力阵列)
data_paxini = tlabel.load("paxini_episode.h5")
# Daimon DM-TacClaw(多模态机器人)
data_daimon = tlabel.load("daimon_episode/") # 目录路径
适配器模式自动处理格式差异,输出统一的 22 维特征向量。
2.3 交互式标注与修正
# 打开交互面板
data = tlabel.load("my_data.pkl")
panel = data.review(lang="zh")
# 在面板中可以:
# 1. 点击时间线查看每帧的雷达图
# 2. 批量修正错误标注(如 contact=0 但 force>0)
# 3. 底部点击导出按钮保存结果
# 或者用代码批量修正
data.batch_patch(10, 25, "contact", 0) # 第10-25帧设为无接触
# 级联规则会自动清零 force_magnitude、slip_event 等关联字段
级联规则确保物理一致性:当 contact=0 时,自动清零相关字段并将 manipulation_phase 重置为 "idle"。
2.4 多格式导出
方式一:面板导出(推荐)
在交互面板底部直接点击对应按钮:
- 💾 导出 JSON:完整 schema,适合备份
- 📊 导出 CSV:表格格式,适合 Excel 分析
- 🔬 导出 HDF5:科研标准格式(需 Python API)
方式二:代码导出
# JSON 导出(完整 TLabel Format v2)
data.export("output.json")
# CSV 导出(扁平表格)
data.export("output.csv")
# HDF5 导出(科学计算格式)
data.export("output.hdf5")
HDF5 文件结构:
import h5py
with h5py.File("output.hdf5") as f:
features = f["tactile_features"][:] # shape: (num_frames, 22)
timestamps = f["timestamps"][:]
is_first = f["is_first"][:] # Episode 起始标记
metadata = f["metadata"].attrs # 传感器ID、标定参数等
三、技术实现要点
3.1 22 维触觉特征定义
TLabel Format v2 定义了标准化的 22 维特征向量:
| 类别 | 维度 | 说明 |
|---|---|---|
| 接触状态 | contact, contact_area, centroid_x | 接触检测与定位 |
| 力学特征 | force_magnitude, force_peak, force_direction | 力的大小与方向 |
| 滑移检测 | slip_entropy, slip_event | 滑动事件识别 |
| 纹理分析 | texture_energy, edge_density | 表面纹理特征 |
| 场分析 | normal_field_, shear_field_ | 法向/剪切应力场 |
| 时序特征 | delta_force_, optical_flow_ | 帧间变化率 |
| 摩擦特性 | friction_cone_ratio | 切向/法向力比值 |
注意:力型传感器(如 PaXini)没有光学图像,因此只有 20 维(缺少光流相关字段)。
3.2 适配器模式实现
不同传感器格式的加载通过适配器模式统一:
from tlabel.adapters.base import BaseAdapter
class GelSightAdapter(BaseAdapter):
"""GelSight/DIGIT pkl → TLabelData"""
def load(self, file_path: str, **kwargs) -> TLabelData:
# 1. 解析 pkl 文件
with open(file_path, "rb") as f:
raw_data = pickle.load(f)
# 2. 背景减除提取触觉图像
background = _get_background(raw_data['images'])
diff_imgs = [_bg_subtract(img, background) for img in raw_data['images']]
# 3. 提取 22 维特征
frames = []
for diff_img in diff_imgs:
tlabel_v2 = _extract_tlabel_v2(diff_img)
frames.append(TLabelFrame(..., tlabel_v2=tlabel_v2))
# 4. 返回统一格式
return TLabelData(frames=frames, sensor_info={...}, ...)
3.3 延迟注册机制
避免导入时依赖缺失导致崩溃:
def _ensure_adapters():
"""确保适配器已注册(延迟加载)"""
if "gelsight" not in _ADAPTERS:
try:
from tlabel.adapters.gelsight import GelSightAdapter
register_adapter("gelsight", GelSightAdapter)
except ImportError:
pass # opencv-python 未安装时静默跳过
四、性能优化实践
4.1 背景计算的采样策略
对于数千帧的数据集,采用随机采样加速背景计算:
def _get_background(images_list: list, sample_size: int = 50) -> np.ndarray:
"""通过随机采样计算背景图像"""
np.random.seed(42)
sample_idx = np.random.choice(len(images_list), sample_size, replace=False)
sample_imgs = [decode_jpeg(images_list[i]) for i in sample_idx]
return np.median(np.stack(sample_imgs, axis=0), axis=0)
性能对比:
- 全量计算(1000 帧):~15 秒
- 采样 50 帧:~0.8 秒
- 精度损失:< 2%(可接受)
4.2 惰性加载与缓存
class LazyImageLoader:
"""惰性图像加载器(避免一次性加载所有图像到内存)"""
def __init__(self, image_files: list, max_cache_size: int = 100):
self.image_files = image_files
self._cache = {}
self._max_cache_size = max_cache_size
def get(self, index: int) -> np.ndarray:
if index in self._cache:
return self._cache[index]
img = decode_jpeg(self.image_files[index])
# LRU 缓存策略
if len(self._cache) >= self._max_cache_size:
oldest_key = next(iter(self._cache))
del self._cache[oldest_key]
self._cache[index] = img
return img
五、常见问题
Q1: 导入时出现 ImportError: No module named 'cv2'
解决:运行 pip install tlabel[gelsight] 或 pip install opencv-python
Q2: 导入时出现 ImportError: No module named 'h5py'
解决:运行 pip install tlabel[paxini] 或 pip install h5py
Q3: HDF5 导出失败
原因:浏览器无法直接创建 HDF5 文件(需要 h5py 库)
解决:使用 Python API 导出
data.export("output.hdf5") # 不要从面板点击 HDF5 按钮
Q4: 如何在命令行中批量处理多个 episode?
import tlabel
import glob
for pkl_file in glob.glob("episodes/*.pkl"):
data = tlabel.load(pkl_file)
data.export(f"annotated/{pkl_file.stem}.json")
print(f"Processed {pkl_file}")
六、总结
TLabel v0.2.0b2 的核心改进在于:
- UI 导出功能增强:三个一键导出按钮,降低使用门槛
- 元数据标准化:支持与 LeRobot 等下游框架无缝对接
- 多格式兼容:JSON/CSV/HDF5 满足不同场景需求
- 性能优化:采样策略和惰性加载提升处理效率
完整源码和教程:https://github.com/liesliy/tlabel
关键词:Python、触觉传感器、数据标注、LeRobot、HDF5、适配器模式
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐




所有评论(0)