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 git+https://github.com/affromero/trajviz.git

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.0.1.tar.gz (475.6 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.0.1-py3-none-any.whl (11.2 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for trajviz-0.0.1.tar.gz
Algorithm Hash digest
SHA256 e16e184ab8170ace9befba3167ac79f04c8c1724ff44b90ab051a333a746a031
MD5 c8ba8cce65d89e8f4ba9381ff59e960a
BLAKE2b-256 31b330b7cc00cde0b9e5c6a729ca8fbb2b98333bf0f54a1cdd82ae36207186c6

See more details on using hashes here.

Provenance

The following attestation bundles were made for trajviz-0.0.1.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.0.1-py3-none-any.whl.

File metadata

  • Download URL: trajviz-0.0.1-py3-none-any.whl
  • Upload date:
  • Size: 11.2 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.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 94736882a8bd252f72f0304eec50b4230f8dd43b4b0021d2150e48915e4d0744
MD5 09abed4792f763fd86d74c247db1a0d0
BLAKE2b-256 359384212cbf5468b90a39695d716dc3c682491295766c0992efb1d146ff0299

See more details on using hashes here.

Provenance

The following attestation bundles were made for trajviz-0.0.1-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