BodyCompress
This library compresses and serializes the output of nonparametric 3D human mesh estimators such as Neural Localizer Fields (NLF) to disk.
Without compression, a sequence of 3D human meshes extracted from a video can take up huge amounts of disk space, as we need to store the coordinates for thousands of vertices in every frame. At 30 fps and 6890 vertices (like SMPL), this amounts to almost 9 GB/person/hour. If you want to save the estimation result for a multi-person video, it will be proportionally more.
This library achieves a compression ratio of over 8x on temporal human mesh data, with minimal loss in information. It consists of the following steps:
- Quantization: The floating-point coordinates of the vertices are quantized at 0.5 mm resolution.
- Vertex Reordering: The vertices are transparently reordered with a bundled TSP-optimized order (auto-detected for SMPL and SMPL-X) so that consecutive vertices are spatially adjacent, which makes the differential encoding more effective. The original order is restored on decompression.
- Differential Encoding: The quantized coordinates are differentially encoded in the (reordered) vertex order, so the differences between adjacent vertices tend to be small.
- Serialization:
msgpack-numpyis used to serialize the NumPy arrays to a byte stream. - Compression: The serialized byte stream is compressed losslessly with xz (LZMA), using the
multi-threaded
lzma-mtlibrary, which is reasonably fast at compression level 5. (The Python standard librarylzmamodule does not have multi-threading support and is too slow for our use case.) Alternatively, zstd compression can be selected for faster (de)compression at a somewhat lower compression ratio.
The format supports storing additional metadata in the header, and several per-frame pieces of information, such as vertices, joints, uncertainties, and camera parameters, compressing it all into one sequentially readable file.
Installation
pip install bodycompress
Usage
Use the BodyCompressor and BodyDecompressor classes to compress and decompress the data.
The compressor should be used as a context manager and has an append method which should be
called with keyword arguments. The decompressor is an iterable over dictionaries with the same
keys; it also knows the number of frames upfront (len(bdecompr)) and can be iterated multiple
times (each pass decompresses the file again from the start).
Note that seeking is not supported, the stream is compressed as a whole to achieve the best compression ratio.
Compression
from bodycompress import BodyCompressor
with BodyCompressor('out.xz', metadata={'whatever': 'you want'}) as bcompr:
for frame in frames:
vertices, joints = estimate(frame)
bcompr.append(vertices=vertices, joints=joints)
Any keyword arguments can be passed to append that are nested dicts/lists/tuples of primitive
types or NumPy arrays.
However the following keywords are handled specially:
vertices: a(..., num_verts, 3)NumPy array of vertex coordinates (in millimeters)joints: a(..., num_joints, 3)NumPy array of joint coordinates (in millimeters)vertex_uncertainties: a(..., num_verts)NumPy array of vertex uncertainties (in meters)joint_uncertainties: a(..., num_joints)NumPy array of joint uncertainties (in meters)camera: adeltacamera.Cameraobject (or a dict in the format produced bybodycompress.cam_to_dict)
Coordinates are expected in millimeters; a warning is issued if the data looks like it might be in meters (i.e., its value range is tiny compared to the quantization step).
Input is validated and consumed synchronously in append: invalid data (NaN coordinates,
malformed cameras, unserializable values) raises immediately without invalidating the file,
so you can skip the offending frame and keep going, and you may freely reuse or overwrite
the passed arrays after append returns. Only the final compression runs in a background
thread; if that fails, the file is finalized with the frames written so far when possible.
If an exception is raised inside the with block, the partially written (unusable) file is
deleted. If a compressor is never closed, it is finalized at interpreter exit and a
ResourceWarning is emitted; don't rely on this, use the context manager or call close().
Useful options of BodyCompressor (see the API reference for the full list):
quantization_mm=0.5: coordinate resolution; coarser quantization gives smaller filescompression='xz': pass'zstd'for much faster compression at a somewhat lower ratiocompression_level=None: defaults to 5 for xz and 3 for zstdn_threads=0: number of compression threads (0 = auto-detect CPU count)
Decompression
from bodycompress import BodyDecompressor
bdecompr = BodyDecompressor('out.xz')
print(bdecompr.metadata) # {'whatever': 'you want'}
print(len(bdecompr)) # number of frames
for data in bdecompr:
render(data['vertices'], data['joints'])
Stored cameras are yielded as plain dicts by default; pass decode_camera=True to
BodyDecompressor to get deltacamera.Camera objects back.
Metadata
Release files for bodycompress 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| bodycompress-0.3.0.tar.gz | 1.5 MB | With provenance | Details for bodycompress-0.3.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| bodycompress-0.3.0-py3-none-any.whl | Python 3 | none | any | Details for bodycompress-0.3.0-py3-none-any.whl |
Total release size: 1.6 MB
Release files / bodycompress-0.3.0.tar.gz
| Download URL | bodycompress-0.3.0.tar.gz |
|---|---|
| Size | 1.5 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
87acafc3eebb03bbc1a84990431d0addfbe2806f3193285035d7a6aad9c67358
|
|
BLAKE2b-256 checksum How to use checksums |
237e378287da44f8db13bb940d77bafb1a8dc7d34f6905b525d365c6b26c4794
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 23, 2026.
Transparency logRelease files / bodycompress-0.3.0-py3-none-any.whl
| Download URL | bodycompress-0.3.0-py3-none-any.whl |
|---|---|
| Size | 49.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
19af32b9da8766a2c81315fb4de565f730e7a5433daf54e12ce7a32c4b17a616
|
|
BLAKE2b-256 checksum How to use checksums |
29ce06403ec70a31b5e4a9428872f339508e83cbb64d12223eea77a3aa8fa13f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 23, 2026.
Transparency logSecurity for bodycompress 0.3.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for bodycompress-0.3.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 23, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.