ML bridge layer for pybvh — tensor packing, augmentation, preprocessing, and PyTorch datasets for motion capture data
Project description
pybvh-ml
ML bridge layer for pybvh — turn motion capture data into training-ready inputs for skeleton-based ML models.
Features
- Tensor packing to
(C,T,V),(T,V,C), and flat(T,D)layouts with round-trip unpacking - Array-level augmentation in quaternion and 6D space — rotation, mirroring, speed perturbation, dropout — all on pre-extracted NumPy arrays, no Bvh objects needed
- Representation conversion between euler, quaternion, 6D, axis-angle, and rotation matrices
- Composable augmentation pipelines with per-step probabilities and seeded randomization
- Preprocessing pipelines — batch convert BVH directories to on-disk datasets (npz, hdf5) with normalization stats
- Skeleton graph metadata — edge lists, body-part partitions, L/R joint pairs for GCN and Transformer models
- Sequence utilities — sliding windows and length standardization (pad, crop, resample)
- Feature metadata — column descriptors that map packed array channels to their meaning
- PyTorch integration (optional) —
MotionDataset,OnTheFlyDataset, andcollate_motion_batchfor variable-length sequences
Philosophy
pybvh-ml is the layer between pybvh (which parses BVH files and does rotation math) and your model (which consumes tensors). It handles the data plumbing — tensor layout, augmentation, preprocessing, dataset construction — without making assumptions about your model or task. All core functions use NumPy; PyTorch is optional.
Installation
pip install pybvh-ml
With optional dependencies:
pip install "pybvh-ml[torch]" # PyTorch Dataset classes
pip install "pybvh-ml[hdf5]" # HDF5 output support
Quick Start
import pybvh
import pybvh_ml
# Load a BVH file and extract rotation data
bvh = pybvh.read_bvh_file("walk.bvh")
root_pos, quats, joints = bvh.get_frames_as_quaternion()
# Pack into (C, T, V) layout for ST-GCN style models
data = pybvh_ml.pack_to_ctv(root_pos, quats) # (4, F, J+1)
# Or flat (T, D) for MLP / Transformer
data = pybvh_ml.pack_to_flat(root_pos, quats) # (F, 3 + J*4)
Augmentation
Array-level augmentation operates directly on NumPy arrays — no Bvh object reconstruction needed:
from pybvh_ml import (
rotate_quaternions_vertical,
mirror_quaternions,
speed_perturbation_arrays,
dropout_arrays,
)
# Vertical rotation (e.g., Y-up skeleton)
quats, root_pos = rotate_quaternions_vertical(quats, root_pos, angle_deg=90, up_idx=1)
# Left-right mirroring
lr_pairs = pybvh_ml.get_lr_pairs(bvh)
quats, root_pos = mirror_quaternions(quats, root_pos, lr_joint_pairs=lr_pairs, lateral_idx=0)
# Speed perturbation (SLERP-based interpolation)
quats, root_pos = speed_perturbation_arrays(quats, root_pos, factor=1.2)
# Frame dropout with SLERP fill
quats, root_pos = dropout_arrays(quats, root_pos, drop_rate=0.1, rng=rng)
6D augmentation avoids the quaternion round-trip in hot data loader paths:
from pybvh_ml import rotate_rot6d_vertical, mirror_rot6d
root_pos, rot6d, joints = bvh.get_frames_as_6d()
rot6d, root_pos = rotate_rot6d_vertical(rot6d, root_pos, angle_deg=45, up_idx=1)
rot6d, root_pos = mirror_rot6d(rot6d, root_pos, lr_joint_pairs=lr_pairs, lateral_idx=0)
Augmentation Pipeline
Compose augmentations with per-step probabilities for use in data loaders:
import numpy as np
from pybvh_ml import AugmentationPipeline
from pybvh_ml.augmentation import rotate_quaternions_vertical, mirror_quaternions
pipeline = AugmentationPipeline([
(rotate_quaternions_vertical, 0.5, {"angle_deg": 90, "up_idx": 1}),
(mirror_quaternions, 0.5, {"lr_joint_pairs": lr_pairs, "lateral_idx": 0}),
])
rng = np.random.default_rng(42)
quats, root_pos = pipeline(quats, root_pos, rng=rng)
Representation Conversion
Convert between any pair of rotation representations on (F, J, C) arrays:
from pybvh_ml import convert_arrays
# Euler to 6D (respects per-joint Euler orders)
rot6d = convert_arrays(euler_data, "euler", "6d", euler_orders=bvh.euler_orders)
# Quaternion to rotation matrix
rotmat = convert_arrays(quats, "quaternion", "rotmat")
Supported: "euler", "quaternion", "6d", "axisangle", "rotmat".
Preprocessing
Batch convert a BVH directory to an on-disk dataset in one call:
from pybvh_ml import preprocess_directory, load_preprocessed
# Convert to npz with 6D representation
stats = preprocess_directory(
"dataset/",
"train.npz",
representation="6d",
)
# Or HDF5 (requires h5py)
stats = preprocess_directory("dataset/", "train.hdf5", representation="quaternion")
# Load back
clips, metadata = load_preprocessed("train.npz")
The output file stores arrays, skeleton metadata, and normalization statistics together.
Skeleton Graph Metadata
Extract the topology data that GCN and Transformer models need:
import pybvh_ml
edges = pybvh_ml.get_edge_list(bvh) # [(child, parent), ...]
lr_pairs = pybvh_ml.get_lr_pairs(bvh) # [(left, right), ...]
partitions = pybvh_ml.get_body_partitions(bvh) # {"torso": [0,1,...], "left_arm": [...], ...}
# All-in-one
info = pybvh_ml.get_skeleton_info(bvh)
# {"edges", "lr_pairs", "body_partitions", "joint_names", "euler_orders"}
Sequence Utilities
from pybvh_ml import sliding_window, standardize_length
# Fixed-length windows for training
windows = sliding_window(data, window_size=64, stride=32) # (num_windows, 64, ...)
# Standardize to target length
padded = standardize_length(data, target_length=128, method="pad")
cropped = standardize_length(data, target_length=64, method="crop")
PyTorch Integration
Optional — install with pip install "pybvh-ml[torch]":
from pybvh_ml.torch import MotionDataset, OnTheFlyDataset, collate_motion_batch
from torch.utils.data import DataLoader
# From preprocessed data
clips, metadata = load_preprocessed("train.npz")
dataset = MotionDataset(clips, target_length=128, augmentation=pipeline)
# From raw BVH files (converts on-the-fly)
dataset = OnTheFlyDataset(bvh_paths, representation="6d", augmentation=pipeline)
# Variable-length batching with padding and masks
loader = DataLoader(dataset, batch_size=32, collate_fn=collate_motion_batch)
for batch in loader:
data = batch["data"] # (B, T_max, D)
mask = batch["mask"] # (B, T_max) bool
lengths = batch["lengths"] # (B,)
Feature Metadata
Know what each column in a packed array represents:
from pybvh_ml import describe_features
desc = describe_features("6d", include_root_pos=True)
# desc.root_pos_slice, desc.joint_data_slice, desc.channels_per_joint, ...
Requirements
- Python >= 3.9
- pybvh >= 0.4.0
- NumPy >= 1.21
Optional: PyTorch >= 2.0 (pip install "pybvh-ml[torch]"), h5py >= 3.0 (pip install "pybvh-ml[hdf5]").
License
MIT
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pybvh_ml-0.1.0.tar.gz.
File metadata
- Download URL: pybvh_ml-0.1.0.tar.gz
- Upload date:
- Size: 29.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
24451b6f4fc43fbab4297c78c59f90e5096f9c36a611d942773cab8c4b8914bb
|
|
| MD5 |
3e99b015fadff60477ca26e63c93d8c2
|
|
| BLAKE2b-256 |
9345e2dc4f4a46e2bbd0b62d65b21ac66d1b8a7fad33a0af7711e3fb975ae5ac
|
Provenance
The following attestation bundles were made for pybvh_ml-0.1.0.tar.gz:
Publisher:
publish.yml on VictorS-67/pybvh-ml
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pybvh_ml-0.1.0.tar.gz -
Subject digest:
24451b6f4fc43fbab4297c78c59f90e5096f9c36a611d942773cab8c4b8914bb - Sigstore transparency entry: 1203314160
- Sigstore integration time:
-
Permalink:
VictorS-67/pybvh-ml@fe5b3bd5ed854298fb8a1c8d93a8ad13b455b918 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/VictorS-67
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@fe5b3bd5ed854298fb8a1c8d93a8ad13b455b918 -
Trigger Event:
release
-
Statement type:
File details
Details for the file pybvh_ml-0.1.0-py3-none-any.whl.
File metadata
- Download URL: pybvh_ml-0.1.0-py3-none-any.whl
- Upload date:
- Size: 23.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cc91f5a100acee3aca7f56d3b9ed467dd56bd23ef6bcee709e4021e0ef4ed47a
|
|
| MD5 |
5fe50d6bf65f704e145023273434596a
|
|
| BLAKE2b-256 |
9f4440d9e015ea36991ba6e50c7f9a62ff749f4a13eb19b91c34afa1191a3741
|
Provenance
The following attestation bundles were made for pybvh_ml-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on VictorS-67/pybvh-ml
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pybvh_ml-0.1.0-py3-none-any.whl -
Subject digest:
cc91f5a100acee3aca7f56d3b9ed467dd56bd23ef6bcee709e4021e0ef4ed47a - Sigstore transparency entry: 1203314165
- Sigstore integration time:
-
Permalink:
VictorS-67/pybvh-ml@fe5b3bd5ed854298fb8a1c8d93a8ad13b455b918 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/VictorS-67
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@fe5b3bd5ed854298fb8a1c8d93a8ad13b455b918 -
Trigger Event:
release
-
Statement type: