Skip to main content

Fast 3D trajectory video renderer using NumPy + OpenCV

Project description

trajviz

PyPI version PyPI downloads Python versions License: MIT CI pre-commit Ruff mypy Pydantic v2 Beartype

Fast 3D camera trajectory video renderer using NumPy + OpenCV.

Renders animated top-down trajectory visualizations from 3D camera positions, with configurable ghost trails, color-coded markers, glow effects, and camera frustum overlays. Frames are piped directly to ffmpeg as raw RGB — no intermediate files.

Spiral trajectory demo

Spiral trajectory with wedge frustum overlay. Colors encode time progression: blue at the start, magenta at the end. Generated by scripts/generate_demo.py.

Colors are user-provided as RGBA per position (n, 4), so they can encode anything. The renderer draws each segment with its assigned color and smoothly advances through the trajectory.

Coloring strategies

Time gradient — show trajectory progression:

t = np.linspace(0, 1, n, dtype=np.float32)
colors = np.stack([t, np.zeros(n), 1 - t, np.ones(n)], axis=1, dtype=np.float32)

Floor / zone coloring — assign colors by vertical position:

colors = np.zeros((n, 4), dtype=np.float32)
colors[:, 3] = 1.0  # full opacity
for i, z in enumerate(positions[:, 2]):
    if z < 3.0:
        colors[i, :3] = [0.2, 0.5, 0.9]   # blue = ground floor
    elif z < 6.0:
        colors[i, :3] = [0.9, 0.5, 0.1]   # orange = first floor
    else:
        colors[i, :3] = [0.1, 0.8, 0.4]   # green = second floor

Speed-based — highlight fast vs slow movement:

deltas = np.linalg.norm(np.diff(positions, axis=0), axis=1)
speed = np.concatenate([[deltas[0]], deltas])
speed_norm = (speed - speed.min()) / (speed.max() - speed.min() + 1e-8)
colors = plt.get_cmap("coolwarm")(speed_norm).astype(np.float32)

Uniform — single color for the entire trajectory:

colors = np.tile([0.2, 0.8, 0.4, 1.0], (n, 1)).astype(np.float32)

Installation

pip install trajviz
# or
uv add trajviz

Usage

import numpy as np
from trajviz import render_trajectory_video, TrajectoryRenderConfig

# Random 3D trajectory
positions = np.random.randn(120, 3).astype(np.float32)
positions = np.cumsum(positions * 0.1, axis=0)

# RGBA colors per frame (e.g., gradient from blue to red)
t = np.linspace(0, 1, 120)
colors = np.stack([t, np.zeros(120), 1 - t, np.ones(120)], axis=1).astype(np.float32)

render_trajectory_video(
    positions=positions,
    colors_rgba=colors,
    output_path="trajectory.mp4",
)

Configuration

All rendering options are controlled via TrajectoryRenderConfig:

from trajviz import TrajectoryRenderConfig, FrustumStyle

config = TrajectoryRenderConfig(
    width=1080,
    height=1080,
    elevation_deg=45.0,
    frustum_style=FrustumStyle.WEDGE,
    fps=30,
)

render_trajectory_video(positions, colors, "out.mp4", config=config)

Side-by-side comparison

Combine a recording with its trajectory overlay:

from trajviz import combine_videos_side_by_side

combine_videos_side_by_side(
    left_path="recording.mp4",
    right_path="trajectory.mp4",
    output_path="combined.mp4",
    fps=30,
)

Development

pip install -e ".[dev]"
pre-commit install

# Run tests
pytest tests/ -v

# Run linting
pre-commit run --all-files

Requirements

  • Python >= 3.10
  • ffmpeg on PATH
  • numpy, opencv-python-headless, pydantic, jaxtyping, beartype, difflogtest

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

trajviz-0.1.0.tar.gz (312.8 kB view details)

Uploaded Source

Built Distribution

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

trajviz-0.1.0-py3-none-any.whl (12.4 kB view details)

Uploaded Python 3

File details

Details for the file trajviz-0.1.0.tar.gz.

File metadata

  • Download URL: trajviz-0.1.0.tar.gz
  • Upload date:
  • Size: 312.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for trajviz-0.1.0.tar.gz
Algorithm Hash digest
SHA256 b1bd02d9ea5a024f6e1ded190ad522689722914176f78d404fe9980177d38370
MD5 a56057daf029944db4f7ca865467b0ae
BLAKE2b-256 db61c86b8a747fc79c1910a465cc7fc04a319bfef94fce33e3127a8c696f8c75

See more details on using hashes here.

Provenance

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

Publisher: publish.yml on affromero/trajviz

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

File details

Details for the file trajviz-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: trajviz-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 12.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for trajviz-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 ffdb72ad4f9ddfac2605ea9d6696c66373459622d19c4ce32b186a70b7ab5b56
MD5 f2c9f496958c629af936101293eedb26
BLAKE2b-256 75570bf80f8cb602378b39b433d35306ee273ad429a4c44a32f0d32ce8dd1c8d

See more details on using hashes here.

Provenance

The following attestation bundles were made for trajviz-0.1.0-py3-none-any.whl:

Publisher: publish.yml on affromero/trajviz

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