Skip to content

Features

features

Feature export for ML pipelines.

Composes the per-frame motion descriptors from :mod:pybvh.analysis (rotations, root position, velocities, foot contacts) into a single flat (F, D) array, plus the column-layout helper that describes it.

feature_array_layout(*, num_joints: int, num_feet: int = 0, representation: str = '6d', include_root_pos: bool = True, include_velocities: bool = False, include_foot_contacts: bool = False) -> dict[str, slice]

Column layout of the array returned by :func:to_feature_array.

Returns a dict mapping block name to column slice so callers can write feat[:, layout['rotations']] without counting columns. Pure function — no :class:~pybvh.bvh.Bvh required; useful for model-shape setup before any data is loaded.

Parameters:

Name Type Description Default
num_joints int

Number of joints (excluding end sites). Used for both the rotation and velocity blocks: velocities are per-joint (not per-node), aligning with the rotation block's joint axis.

required
num_feet int

Number of foot joints for contact detection. Required (>0) when include_foot_contacts=True.

0
representation str

Rotation representation: 'euler', 'axisangle' (3 values per joint), 'quat' (4), '6d' (6, default), 'rotmat' (9).

'6d'
include_root_pos bool

Mirror the flags of :func:to_feature_array.

True
include_velocities bool

Mirror the flags of :func:to_feature_array.

True
include_foot_contacts bool

Mirror the flags of :func:to_feature_array.

True

Returns:

Type Description
dict

{block_name: slice} with keys drawn from {"root_pos", "rotations", "velocities", "foot_contacts"} depending on the flags.

Notes

Within the rotations and velocities blocks joints are in skeleton hierarchy order — the file's declaration order, i.e. Bvh.joint_names, end sites excluded — not alphabetical. For representation='euler' the three columns per joint follow that joint's own channel order from the file (which can differ per joint and between files), not a fixed XYZ; every other representation is order-independent. 'rotmat' flattens each 3×3 row-major (C order).

Raises:

Type Description
ValueError

If representation is unknown, or if include_foot_contacts=True but num_feet == 0.

to_feature_array(bvh: Bvh, representation: str = '6d', include_root_pos: bool = True, include_velocities: bool = False, include_foot_contacts: bool = False, centered: str = 'world', foot_joints: list[str] | None = None, stencil: str = 'central', pad: str = 'edge') -> npt.NDArray[np.float64]

Export motion as a single flat feature array for ML pipelines.

Composes root position, joint rotations, velocities, and foot contacts into a single (F, D) array ready for model input.

Parameters:

Name Type Description Default
bvh Bvh

Input motion.

required
representation str

Rotation representation: 'euler', '6d' (default), 'quat', 'axisangle', or 'rotmat' (9 values per joint as a flattened 3×3). 'quat' inherits the per-frame canonical form (w >= 0) of :meth:Bvh.to_quat, which is not temporally continuous — a joint passing through 180° flips sign between frames. Apply :func:pybvh.rotations.quat_unwrap to the array yourself if your model is sensitive to that; '6d' (the default) has no such discontinuity, which is the representation's whole point.

'6d'
include_root_pos bool

If True (default), include root position (3 columns).

True
include_velocities bool

If True, include joint velocity features, in units per frame — deliberately not :func:joint_velocities' own units-per-second default, because a feature array is consumed per-frame by a model and a per-frame delta keeps the block on the same time base as the rest of the array. Multiply by 1 / bvh.frame_time to recover units/second, and note the two disagree by exactly that factor if you cross-check this block against a direct joint_velocities(bvh) call.

False
include_foot_contacts bool

If True, include foot contact labels. Contacts are always detected in world frame (see :func:pybvh.analysis.foot_contacts), whatever centered says.

False
centered str

Coordinate centering mode (default "world").

'world'
foot_joints list of str or None

Foot joints for contact detection. Only used when include_foot_contacts=True.

None
stencil optional

Only affect output when include_velocities=True. Same semantics as :func:joint_velocities. The root-position, rotation, and foot-contact blocks are trimmed in time so all blocks align with the velocity shape: pad="none" drops one frame from each end for stencil="central", and the last frame for stencil="forward" (a forward difference labels frame i, so the final frame has no velocity).

'central'
pad optional

Only affect output when include_velocities=True. Same semantics as :func:joint_velocities. The root-position, rotation, and foot-contact blocks are trimmed in time so all blocks align with the velocity shape: pad="none" drops one frame from each end for stencil="central", and the last frame for stencil="forward" (a forward difference labels frame i, so the final frame has no velocity).

'central'

Returns:

Type Description
ndarray, shape (F, D), (F-1, D), or (F-2, D)

See :func:feature_array_layout for the column layout. Leading dimension depends on include_velocities and the stencil × pad combination.

Raises:

Type Description
ValueError

If representation is unknown, or stencil / pad is invalid.