Skip to main content

TouchLabel AI - Tactile Data Annotation Toolkit

Project description

๐Ÿฆž TouchLabel AI

The World's First Sensor-Agnostic Tactile Data Annotation Toolkit

Load any tactile sensor โ†’ Annotate visually โ†’ Export a unified schema

PyPI Python License Downloads GitHub Stars Last Commit ไธญๆ–‡ๆ–‡ๆกฃ

TLabel Panel Demo

GelSight ยท DIGIT ยท PaXini ยท Daimon โ€” one tool, one format, all sensors

๐Ÿš€ Quick Start ยท ๐Ÿค– AI Pre-Annotation ยท ๐Ÿ“Š Benchmark ยท ๐Ÿ“– Docs ยท ๐Ÿค Contributing


๐Ÿ†• What's New

v0.11.0 โ€” Tactile Image Visualization & Data Augmentation

Canvas-based tactile image playback, pure-numpy augmentation, and AnyTouch multi-sensor support.

  • ๐ŸŽฌ Tactile Image Sequence Visualization: Canvas-rendered playback with 3-level strategy (real image / heatmap / placeholder), play/pause/seek/speed controls, dark mode & i18n
  • ๐Ÿ“ˆ Data Augmentation Module: 5 methods (time_warp, noise_inject, random_crop, force_scale, frame_dropout), zero new deps (pure numpy), 3-level API
  • ๐Ÿ”Œ TacQuad Adapter: GeWu-Lab AnyTouch (ICLR 2025) โ€” GelSight Mini, DIGIT, DuraGel + optional Tac3D force field
  • ๐Ÿ“ฆ pip install tlabel[tacquad]
import tlabel

# Data augmentation โ€” one-liner
data = tlabel.demo('gelsight')
augmented = tlabel.augment(data, methods=["time_warp", "noise_inject"], seed=42)

# TacQuad multi-sensor loading
data = tlabel.load("anytouch_dataset/", format="tacquad", sensor="digit")

v0.10.2 โ€” UniVTAC Adapter

Cross-dataset tactile interoperability โ€” UniVTAC benchmark support.

  • ๐Ÿ†• UniVTAC Adapter: Load UniVTAC HDF5 datasets with auto-detection (dual GelSight Mini, 22 dims)
  • ๐Ÿ” Smart HDF5 Detection: Auto-distinguishes PaXini vs UniVTAC by internal structure
  • ๐Ÿ“ฆ pip install tlabel[univtac]

v0.8.0 โ€” FTP-1 / MTTS Export

Export labeled data directly to FTP-1's MTTS Zarr format for foundation model fine-tuning.

  • ๐Ÿš€ FTP-1 Converter: tlabel_to_ftp1() / batch_to_ftp1() โ€” one-click export to Zarr
  • ๐Ÿ– 21 Functional Areas: MTTS morphology-aware tactile token space (15 hand zones + 6 wrist torque channels)
  • ๐Ÿ“ก 7 Sensor Registry: GelSight, GelSightMini, FreeTacMan, ViTaMIn, 3DViTac, Contactile, BinaryContact
  • ๐ŸŽจ New Export Tab in Panel: sensor selection, functional area picker with presets, export preview
  • ๐Ÿ“ฆ Zarr backend: append mode for multi-episode datasets, auto image resize to 224ร—224 + normalization
from tlabel import demo
data = demo('gelsight')
data.export_ftp1("output.zarr",
    sensor_name="GelSightMini",
    functional_areas=[0, 1])  # thumb tip + index fingertip

v0.5.0 โ€” AI-Assisted Pre-Annotation

Let the engine suggest labels, then you review and correct โ€” human-in-the-loop, not black-box.

  • ๐Ÿค– PredictEngine: predict contact, slip, and manipulation phase automatically
  • ๐Ÿ“ˆ Warm start with fit(): learn from your partially labeled data โ€” even 10% labels significantly boost accuracy
  • ๐ŸŽฏ Confidence threshold: only apply predictions above your threshold, you stay in control
  • ๐Ÿ”ฌ HMM Phase Detection: Hidden Markov Model for manipulation phase inference with Viterbi decoding
  • ๐Ÿงน Removed black-box pkl models: no opaque pretrained weights โ€” every prediction is interpretable
Previous releases
  • v0.10.3 โ€” VTouch/YCB-Slide adapter registration, LeRobot export panel, PyPI fixes
  • v0.9.0 โ€” Panel Phase 1 (5 UI features), Exporter Plugin Registry (7 formats)
  • v0.4.2 โ€” Full i18n: bilingual Panel UI (ไธญๆ–‡/English), localized error messages, docs in both languages
  • v0.4.1 โ€” Panel UI integration: Tab navigation, batch correction tool, export buttons directly in panel
  • v0.4.0 โ€” Interactive Panel: color-coded timeline, 22-dim radar chart, frame detail editor
  • v0.2.0b1 โ€” LeRobot integration, HDF5 export, enhanced metadata, comprehensive tutorials

๐ŸŽฏ Why TLabel?

Every tactile sensor spits out a different format. There's no universal annotation tool โ€” until now.

The Problem TLabel's Answer
4 different sensors โ†’ 4 different pipelines One tlabel.load() call, auto-detected
Raw tactile data = unreadable numbers Visual Panel: timeline + radar chart + frame editor
Fixing labels frame-by-frame is soul-crushing AI pre-annotation + batch patch + cascade rules
"We use DIGIT, they use PaXini" โ€” data doesn't mix Sensor-agnostic 22-dim schema, one format for all
No standardized tactile labels exist TLabel Format v2 โ€” the first unified specification
Annotation tools assume vision, not touch Built for tactile from day one

TLabel is the only tool that:

  • โœ… Supports 4+ tactile sensor families out of the box
  • โœ… Provides a unified 22-dimension annotation schema
  • โœ… Offers AI-assisted pre-annotation with human-in-the-loop
  • โœ… Ships an interactive visual Panel for Jupyter
  • โœ… Includes a cross-sensor benchmark (TLabel-Bench)

๐Ÿš€ Quick Start

Install

pip install tlabel

That's it. Core installs in seconds with just numpy as a dependency.

Try the Demo (30 seconds)

import tlabel

data = tlabel.demo()     # Built-in GelSight demo โ€” no files needed
data.review()            # Interactive Panel pops up in Jupyter

What you'll see: a color-coded timeline (๐ŸŸข contact / ๐Ÿ”ด slip / โฌœ idle), 22-dim radar chart, frame detail editor, and batch patching โ€” all in one panel.

Other sensors:

tlabel.demo('digit').review()    # DIGIT sensor
tlabel.demo('paxini').review()   # PaXini force sensor
tlabel.demo('daimon').review()   # Daimon DM-TacClaw

๐Ÿ‘‰ Try it live in your browser โ€” no install needed.

Load Your Own Data

import tlabel

# Auto-detect sensor format โ€” no config needed
data = tlabel.load("gelsight_force.pkl")     # GelSight / DIGIT
data = tlabel.load("paxini_episode.h5")      # PaXini
data = tlabel.load("daimon_data/")           # Daimon (directory or .parquet)
data = tlabel.load("univtac_episode.hdf5")   # UniVTAC (dual GelSight Mini)
data = tlabel.load("anytouch_dataset/")      # TacQuad / AnyTouch (ICLR 2025)

Annotate & Export

# Interactive Jupyter panel (bilingual: ไธญๆ–‡ / English)
data.review()           # Chinese UI
data.review(lang="en")  # English UI

# Export โ€” unified TLabel Format v2
data.export("output.json")   # Full schema JSON
data.export("output.csv")    # Flat CSV for pandas/Excel

Full loop: load โ†’ review โ†’ correct โ†’ export ๐Ÿ”

Data Augmentation

import tlabel

data = tlabel.demo('gelsight')

# Quick augment โ€” default: time_warp + noise_inject
augmented = tlabel.augment(data)

# Fine-grained control
from tlabel.augment import AugmentEngine
engine = AugmentEngine(seed=42)
augmented = engine.augment(data, methods=["time_warp", "noise_inject", "random_crop"])

# Or via TLabelData method
augmented = data.augment(methods=["force_scale", "frame_dropout"], seed=42)

5 built-in methods: time_warp, noise_inject, random_crop, force_scale, frame_dropout โ€” all pure numpy, zero new dependencies.

Export to FTP-1 (Foundation Model Ready)

pip install tlabel[ftp1]   # installs zarr
# Export labeled data โ†’ FTP-1 Zarr format
data.export_ftp1("output.zarr",
    sensor_name="GelSightMini",
    functional_areas=[0, 1])

# Batch export multiple episodes
from tlabel.converters import batch_to_ftp1
batch_to_ftp1(["ep1.json", "ep2.json"], "dataset.zarr",
    sensor_name="GelSightMini",
    functional_areas=[0, 1])

# Preset configurations
from tlabel.converters import DEFAULT_AREA_MAPPINGS
# "parallel_gripper": [0, 1]
# "three_finger": [0, 1, 2]
# "five_finger": [0, 1, 2, 3, 4]
# "dexterous_hand": list(range(15))

The exported Zarr files are directly compatible with FTP-1 for fine-tuning the world's first general-purpose tactile foundation model.


๐Ÿค– AI Pre-Annotation

New in v0.5.0 โ€” Let the engine suggest labels, then you review and correct.

from tlabel.predict import PredictEngine

engine = PredictEngine()

# Option 1: Cold start โ€” no prior labels needed
results = engine.predict(data)

# Option 2: Warm start โ€” learn from your partial annotations first
engine.fit(data)          # Extract statistics from labeled frames
results = engine.predict(data)

# Apply only high-confidence predictions (โ‰ฅ 0.7)
applied = engine.apply(data, results, min_confidence=0.7)
print(f"Auto-filled {applied} fields")

# Review in Panel โ€” correct any mistakes
data.review()

What it predicts:

Dimension Method Confidence Range
contact Rule-based (force + deformation + area) 0.4 โ€“ 0.9
slip_event Rule-based (shear + delta + entropy) 0.55 โ€“ 0.8
manipulation_phase HMM + Viterbi decoding 0.55 โ€“ 0.65
Missing dims (with fit()) Statistical (mean from labeled frames) ~0.4

๐Ÿ’ก Tip: Use fit() on partially labeled data first โ€” even 10โ€“20% labeled frames significantly improve predictions. Predictions below your confidence threshold are simply skipped.


๐Ÿ“ก Supported Sensors

Sensor Type Format Dims Optical Flow Status
GelSight Mini Vision-based .pkl 22 โœ… โœ… Stable
DIGIT Vision-based .pkl 22 โœ… โœ… Stable
Daimon DM-TacClaw Multimodal .parquet / dir 22 (video) / 20 (no video) โœ… / โ€” โœ… Stable
PaXini PXCap Force array .h5 / .hdf5 20 โ€” โœ… Stable
UniVTAC Vision-based (Dual GelSight Mini) .hdf5 / .h5 22 โœ… โœ… New
TacQuad (AnyTouch) Vision-based multi-sensor directory 22 โœ… โœ… New
VTouch Vision-based .pkl 22 โœ… โœ… New

Force-type sensors (PaXini) lack optical images โ†’ 20 dims. Image-type โ†’ full 22. Daimon gracefully degrades when no video is present. No errors, no surprises.

FTP-1 Compatible Sensors

All sensors below can export directly to FTP-1 MTTS Zarr format via export_ftp1():

Sensor Type Default Shape
GelSight / GelSightMini image (224, 224, 3)
FreeTacMan image (224, 224, 3)
ViTaMIn image (224, 224, 3)
3DViTac matrix (12, 32)
Contactile matrix (12, 32)
BinaryContact binary (1,)

Per-Sensor Installation

pip install tlabel[gelsight]   # GelSight / DIGIT โ†’ opencv-python
pip install tlabel[paxini]     # PaXini โ†’ h5py
pip install tlabel[daimon]     # Daimon โ†’ pyarrow + opencv-python
pip install tlabel[univtac]    # UniVTAC โ†’ h5py
pip install tlabel[tacquad]    # TacQuad / AnyTouch โ†’ (pure numpy)
pip install tlabel[vtouch]     # VTouch โ†’ opencv-python
pip install tlabel[ftp1]       # FTP-1/MTTS export โ†’ zarr
pip install tlabel[all]        # Everything

Sensor Tutorials


๐ŸŽจ Panel Features

  • ๐ŸŽฌ Tactile image sequence visualization: Canvas-based playback with 3-level strategy (real image / heatmap / placeholder), play/pause/seek/speed controls, dark mode
  • ๐ŸŽจ Color-coded timeline: green = contact ยท red = slip ยท gray = idle โ€” patterns jump out instantly
  • ๐Ÿ•ธ 22-dim radar chart: see the full feature vector at a glance, bilingual labels
  • โœ๏ธ Frame & batch patching: fix one frame or a range, your call
  • ๐Ÿ”— Cascade rules: set contact=0 โ†’ 7 related fields auto-zero + phase resets to idle
  • ๐Ÿค– Pre-annotation integration: apply AI predictions, then review in the same panel
  • ๐ŸŒ Bilingual toggle: ไธญๆ–‡ / English, one click top-right
  • ๐Ÿ“ค In-panel export: JSON / CSV / FTP-1 Zarr with one click

๐Ÿ“ TLabel Format v2 โ€” 22 Dimensions

The first unified tactile annotation schema. Every frame, every sensor, same 22 dimensions.

Static Features (18-dim)

# Key Description
1 contact Binary contact flag
2 deformation_magnitude Surface deformation intensity
3 force_magnitude Normal force magnitude
4 force_peak Peak force in episode window
5 force_direction Force vector angle (ยฐ)
6 slip_entropy Uncertainty of slip detection
7 slip_event Binary slip event flag
8 texture_energy Surface texture frequency energy
9 edge_density Contact edge pixel ratio
10 contact_area Contact region area ratio
11 centroid_x Contact centroid x-position
12 normal_field_magnitude Normal pressure field magnitude
13 normal_field_variance Normal field spatial variance
14 shear_field_magnitude Shear stress magnitude
15 shear_field_direction Shear direction angle (ยฐ)
16 delta_force_normal Frame-to-frame ฮ”F_normal
17 delta_force_shear Frame-to-frame ฮ”F_shear
18 friction_cone_ratio Tangential/normal force ratio

Temporal Features (4-dim)

# Key Image-type Force-type Description
19 optical_flow_magnitude โœ… โ€” Inter-frame motion magnitude (Farneback)
20 optical_flow_direction โœ… โ€” Optical flow angle (ยฐ)
21 temporal_deformation_rate โœ… โœ… Rate of deformation change
22 contact_transition โœ… โœ… Contact state transition probability

๐Ÿ“– Full specification: annotation-spec.md | tlabel-format.md


๐Ÿ“– API Quick Reference

import tlabel

# โ”€โ”€ Loading โ”€โ”€
data = tlabel.load(path)                     # Auto-detect sensor format
data = tlabel.load(path, format="gelsight")  # Force specific adapter

# โ”€โ”€ Demo โ”€โ”€
data = tlabel.demo()                         # Built-in demo data
tlabel.list_demos()                          # See available sensors

# โ”€โ”€ Properties โ”€โ”€
data.num_frames        # int โ€” total frame count
data.duration_s        # float โ€” episode duration
data.sensor_type       # str โ€” sensor identifier
data.dimension_keys    # list โ€” all dimension keys
data.modified_count    # int โ€” frames with manual patches

# โ”€โ”€ Frame Access โ”€โ”€
frame = data[0]                          # Index access
frame = data.get_frame(42)               # By frame_idx
frame.contact                            # Contact value
frame.slip_event                         # Slip event value
frame.is_modified                        # Has patches?

# โ”€โ”€ Patching โ”€โ”€
frame.patch("contact", 0)                         # Single frame (cascade=True)
frame.patch("contact", 0, cascade=False)           # No cascade
data.batch_patch(10, 50, "contact", 0)             # Range patch

# โ”€โ”€ Augmentation โ”€โ”€
augmented = tlabel.augment(data)                   # Default augmentation
augmented = tlabel.augment(data, methods=["time_warp", "noise_inject"], seed=42)

# โ”€โ”€ Pre-Annotation โ”€โ”€
from tlabel.predict import PredictEngine
engine = PredictEngine()
engine.fit(data)                                   # Warm start from partial labels
results = engine.predict(data)                     # Predict contact, slip, phase
engine.apply(data, results, min_confidence=0.7)    # Apply high-confidence only

# โ”€โ”€ Review & Export โ”€โ”€
data.review()                    # Jupyter panel (Chinese)
data.review(lang="en")           # English
data.export("output.json")       # JSON (TLabel Format v2)
data.export("output.csv")        # CSV
data.export_ftp1("out.zarr")     # FTP-1 Zarr format

Cascade Rules (contact โ†’ 0)

When contact is set to 0, these fields are automatically zeroed:

Auto-zeroed Field Condition
force_magnitude always
force_peak always
slip_event always
delta_force_normal always
delta_force_shear always
contact_area always
contact_transition only if value > 0.5
manipulation_phase โ†’ "idle" if not already

๐Ÿ† Benchmark

TLabel-Bench โ€” The first cross-sensor unified tactile annotation benchmark.

Same objects, different sensors, one format. TLabel-Bench provides cross-sensor annotations (material labels, episode segmentation, quality scores) for objects annotated with GelSight Mini, DIGIT, DMA, and more โ€” all in the unified TLabel format.

git clone https://github.com/liesliy/tlabel-bench.git
cd tlabel-bench
bash scripts/download_data.sh
python evaluation/material_classification.py

If you're using TLabel in research, citing the benchmark helps demonstrate sensor-agnostic value ๐Ÿ‘‡


๐Ÿ—‚ Project Structure

tlabel/
โ”œโ”€โ”€ core/
โ”‚   โ”œโ”€โ”€ types.py          # TLabelFrame / TLabelData containers
โ”‚   โ”œโ”€โ”€ loader.py         # Auto-detect & dispatch loading
โ”‚   โ””โ”€โ”€ registry.py       # Adapter registry
โ”œโ”€โ”€ adapters/
โ”‚   โ”œโ”€โ”€ base.py           # BaseAdapter interface
โ”‚   โ”œโ”€โ”€ gelsight.py       # GelSight Mini / DIGIT
โ”‚   โ”œโ”€โ”€ paxini.py         # PaXini PXCap
โ”‚   โ”œโ”€โ”€ daimon.py         # Daimon DM-TacClaw (+ video decoding)
โ”‚   โ””โ”€โ”€ tacquad.py        # TacQuad / AnyTouch (ICLR 2025)
โ”œโ”€โ”€ augment/
โ”‚   โ””โ”€โ”€ engine.py         # Data augmentation (time_warp, noise, crop, scale, dropout)
โ”œโ”€โ”€ converters/
โ”‚   โ”œโ”€โ”€ lerobot.py        # LeRobot format converter
โ”‚   โ””โ”€โ”€ ftp1.py           # FTP-1/MTTS Zarr format converter
โ”œโ”€โ”€ viewer/
โ”‚   โ”œโ”€โ”€ panel.py          # Jupyter _repr_html_ renderer
โ”‚   โ””โ”€โ”€ templates.py      # HTML + JS + CSS template engine
โ”œโ”€โ”€ predict/
โ”‚   โ””โ”€โ”€ engine.py         # AI-assisted pre-annotation engine
โ”œโ”€โ”€ demo.py               # Built-in demo data loader
โ””โ”€โ”€ export/
    โ””โ”€โ”€ writer.py         # JSON / CSV export + NumpyEncoder

๐Ÿ“ Citing TLabel

If you use TLabel in your research, please cite:

@software{tlabel2026,
  title = {TLabel: A Sensor-Agnostic Tactile Data Annotation Toolkit},
  author = {NiuZhu Tech},
  year = {2026},
  url = {https://github.com/liesliy/tlabel}
}

๐Ÿค Contributing

We welcome contributions! See CONTRIBUTING.md for guidelines.

Good first issues:

  • ๐Ÿ”Œ Add a new sensor adapter (SynTouch? XELA? Your call.)
  • ๐Ÿ“Š Improve radar chart UI (dark mode, interactive hover)
  • ๐ŸŒ Add more language support (ๆ—ฅๆœฌ่ชž, ํ•œ๊ตญ์–ด)
  • ๐Ÿงช Add integration tests for edge cases
  • ๐Ÿค– Improve pre-annotation models (replace rules with lightweight ML?)

๐Ÿ’ฌ Feedback

  • ๐Ÿ› Bug report โ†’ Open an Issue
  • ๐Ÿ’ก Feature request โ†’ GitHub Discussions
  • ๐ŸŒŸ Using TLabel in your research? โ†’ We'd love to hear about it! Drop us a star โญ

๐Ÿ“„ License

MIT ยฉ NiuZhu Tech


If this saved you from manually labeling tactile data, a โญ would make our day!

โญ Star on GitHub ยท ๐Ÿ“ฆ Install from PyPI ยท ๐Ÿ† Try the Benchmark

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tlabel-0.12.2.tar.gz (198.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

tlabel-0.12.2-py3-none-any.whl (204.6 kB view details)

Uploaded Python 3

File details

Details for the file tlabel-0.12.2.tar.gz.

File metadata

  • Download URL: tlabel-0.12.2.tar.gz
  • Upload date:
  • Size: 198.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.12

File hashes

Hashes for tlabel-0.12.2.tar.gz
Algorithm Hash digest
SHA256 e6ef1668a9feb2f6bae87cd258894965469e12ca9ab03015f081ae38b5f7b095
MD5 c6f85be186a6689d224864ed1a5ef3c0
BLAKE2b-256 fd1d032f13adb04788330346fa0439454e2fcadb1ac3aa744b1c852861e33bb1

See more details on using hashes here.

File details

Details for the file tlabel-0.12.2-py3-none-any.whl.

File metadata

  • Download URL: tlabel-0.12.2-py3-none-any.whl
  • Upload date:
  • Size: 204.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.12

File hashes

Hashes for tlabel-0.12.2-py3-none-any.whl
Algorithm Hash digest
SHA256 10446a1ec4276969c163f78bfcab5b137e9c19e33f19d8999d57971e3b3b63f1
MD5 9dc5af377a2fa43830e155e92e9ac639
BLAKE2b-256 87afe5c99ae744c4452bda2a0293d61d3e5c0d73726bb3ee11cadd7f77fc9913

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page