Skip to main content

ML bridge layer for pybvh — tensor packing, augmentation, preprocessing, and PyTorch datasets for motion capture data

Project description

pybvh-ml

PyPI version Python License: MIT

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, and collate_motion_batch for 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

pybvh_ml-0.1.0.tar.gz (29.6 kB view details)

Uploaded Source

Built Distribution

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

pybvh_ml-0.1.0-py3-none-any.whl (23.4 kB view details)

Uploaded Python 3

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

Hashes for pybvh_ml-0.1.0.tar.gz
Algorithm Hash digest
SHA256 24451b6f4fc43fbab4297c78c59f90e5096f9c36a611d942773cab8c4b8914bb
MD5 3e99b015fadff60477ca26e63c93d8c2
BLAKE2b-256 9345e2dc4f4a46e2bbd0b62d65b21ac66d1b8a7fad33a0af7711e3fb975ae5ac

See more details on using hashes here.

Provenance

The following attestation bundles were made for pybvh_ml-0.1.0.tar.gz:

Publisher: publish.yml on VictorS-67/pybvh-ml

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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

Hashes for pybvh_ml-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 cc91f5a100acee3aca7f56d3b9ed467dd56bd23ef6bcee709e4021e0ef4ed47a
MD5 5fe50d6bf65f704e145023273434596a
BLAKE2b-256 9f4440d9e015ea36991ba6e50c7f9a62ff749f4a13eb19b91c34afa1191a3741

See more details on using hashes here.

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

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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