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.2.0.tar.gz (34.2 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.2.0-py3-none-any.whl (25.5 kB view details)

Uploaded Python 3

File details

Details for the file pybvh_ml-0.2.0.tar.gz.

File metadata

  • Download URL: pybvh_ml-0.2.0.tar.gz
  • Upload date:
  • Size: 34.2 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.2.0.tar.gz
Algorithm Hash digest
SHA256 48b553a4a8445c7d2ec916d4ee20794d0edb175e8b55259f98f57cad42b91413
MD5 b9f6028c08e3b06b8267a957d80957b7
BLAKE2b-256 b77a65ced54b4a2c77bb67ea63e2223ee0fe5ba8ccebf4d846521e8a169d6cd3

See more details on using hashes here.

Provenance

The following attestation bundles were made for pybvh_ml-0.2.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.2.0-py3-none-any.whl.

File metadata

  • Download URL: pybvh_ml-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 25.5 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.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 7a0aa26ac6d01648c92297ae9d8cdd3ad94282de168db6d4ae063b1df7689a42
MD5 dbe6f8c4433ec8b53771868f4f523042
BLAKE2b-256 e47b971a993c290e4fca867d7974f97af02807543bbe3d33069bd1230b69d8bf

See more details on using hashes here.

Provenance

The following attestation bundles were made for pybvh_ml-0.2.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