Skip to content

Latest commit

 

History

History
289 lines (198 loc) · 10.5 KB

File metadata and controls

289 lines (198 loc) · 10.5 KB

Postprocessing Guide

After the VIO program finishes, copy its output into the matching results folder:

results/<sequence_name>/estimated_trajectory.txt

The VIO program writes this file to its own working directory; move or copy it here so the post-processing scripts can find it via --sequence <sequence_name>.

The post-processing scripts in scripts/postprocessing/ operate on that file (and the GPS data already extracted by the preprocessing) to produce visualizations and GPS-aligned trajectories.

All scripts accept a --sequence <name> shorthand that sets sensible default paths relative to results/<name>/. Explicit path flags always override the defaults. Run any script with --help for the full flag list.


Typical Script Order

# 1. Align VIO trajectory to GPS (recommended flags for a flat-ground rover)
python scripts/postprocessing/align_vio_to_gps.py --sequence <sequence_name> \
  --horizontal_only --z_mode flat --z_flat_value 0.0

# 2. Plot the trajectory overview (saved to results/<sequence_name>/visualizations/)
python scripts/postprocessing/plot_estimated_trajectory.py --sequence <sequence_name> --no-show

# 3. (Optional) NeRF export
python scripts/postprocessing/tum_timestamps_to_nerfstudio_transforms.py --sequence pipeline_from_uturn

# 4. (Optional) COLMAP GPS reference images
python scripts/postprocessing/create_colmap_ref_images_from_gps.py --sequence pipeline_from_uturn

1. GPS Alignment — align_vio_to_gps.py

Script: scripts/postprocessing/align_vio_to_gps.py

Purpose: Fit a global similarity transform (Sim(3) or Sim(2)) between VIO positions and GPS-derived ENU positions, then apply it to every pose.

Dependencies: numpy. matplotlib optional for residual plots.

Default paths from --sequence NAME:

File Path
Input trajectory results/<NAME>/estimated_trajectory.txt
GPS log results/<NAME>/gps.txt
Output trajectory results/<NAME>/estimated_trajectory_gps.txt

Recommended usage (flat-ground rover):

python scripts/postprocessing/align_vio_to_gps.py --sequence <sequence_name> \
  --horizontal_only --z_mode flat --z_flat_value 0.0

--horizontal_only fits a 2D yaw + scale in the E/N plane only, avoiding GPS altitude noise. --z_mode flat --z_flat_value 0.0 sets all output Z to 0.0 in the ENU frame (i.e. the reference altitude of the first matched GPS fix). This is the most stable choice for ground robots and NeRF training on flat terrain.

Key options:

--horizontal_only       Fit only in E/N plane (recommended for ground robots)
--z_mode {offset,gps,flat}
    offset   Z_out = z_vio + median(gps_z - vio_z)   VIO vertical shape, no scale applied
    gps      Z_out = interpolated GPS altitude         only when GPS vertical is reliable
    flat     Z_out = constant (default 0.0)            best for flat terrain / NeRF
--z_flat_value 0.0      Z constant when --z_mode flat; 0.0 = ENU reference altitude
--no_scale              Rigid transform only (scale = 1)
--sweep_time_offset     Search for best GPS time alignment over a range of offsets

With diagnostics output:

python scripts/postprocessing/align_vio_to_gps.py --sequence <sequence_name> \
  --horizontal_only --z_mode flat --z_flat_value 0.0 \
  --residuals_csv results/<sequence_name>/residuals.csv \
  --plot_residuals_en_path results/<sequence_name>/visualizations/residuals_en.png

Z mode summary:

Mode Output Z When to use
offset z_vio + median(gps_z − vio_z) Preserve VIO vertical trend (no scale)
gps Interpolated GPS altitude When GPS vertical is reliable
flat Constant --z_flat_value (= 0.0) Flat terrain, NeRF training (default rec)

2. Trajectory Visualization — plot_estimated_trajectory.py

Purpose: Four-panel static overview + optional animated video.

Dependencies: numpy, matplotlib. Animation (--animate) also requires ffmpeg on PATH.

Default paths from --sequence NAME:

File/Output Path
Input trajectory results/<NAME>/estimated_trajectory_gps.txt (falls back to estimated_trajectory.txt)
Static PNG results/<NAME>/visualizations/trajectory_overview.png
Animation results/<NAME>/visualizations/trajectory_animation.mp4

The four panels (saved in one PNG):

  1. XY path — coloured by elapsed time.
  2. Camera heading — yaw from the quaternion, unwrapped, in degrees.
  3. Movement direction — tangent angle from consecutive XY positions, unwrapped.
  4. Z position over time.

Plot with interactive window (can manually save in the window's menu):

python scripts/postprocessing/plot_estimated_trajectory.py --sequence pipeline_from_uturn

Save without opening a window:

python scripts/postprocessing/plot_estimated_trajectory.py --sequence pipeline_from_uturn --no-show

Override the input trajectory file:

python scripts/postprocessing/plot_estimated_trajectory.py \
  results/pipeline_from_uturn/estimated_trajectory_gps.txt \
  --sequence pipeline_from_uturn --no-show

Animated video:

python scripts/postprocessing/plot_estimated_trajectory.py \
  --sequence pipeline_from_uturn \
  --no-show \
  --animate \
  --animate-fps 15

Generates results/pipeline_from_uturn/visualizations/trajectory_animation.mp4. Each video frame shows the XY path building up, with a green arrow for camera heading and a blue arrow for movement direction at the current position.

ffmpeg must be on PATH (or installed via conda) for MP4 export.


3. NeRF Export — tum_timestamps_to_nerfstudio_transforms.py

Purpose: Convert a TUM trajectory + camera timestamps + image folder into a NerfStudio transforms.json.

Dependencies: numpy. Pillow optional (needed only when --width/--height are omitted and image dimensions must be read from disk).

Default paths from --sequence NAME:

File Path
Trajectory results/<NAME>/estimated_trajectory_gps.txt (falls back to estimated_trajectory.txt)
Cam timestamps results/<NAME>/<NAME>/cam_timestamps.txt
Images results/<NAME>/<NAME>/images/
Output results/<NAME>/nerfstudio/transforms.json

Usage:

python scripts/postprocessing/tum_timestamps_to_nerfstudio_transforms.py \
  --sequence pipeline_from_uturn

Point ns-train at the directory containing transforms.json:

ns-train nerfacto --data results/pipeline_from_uturn/nerfstudio

Key options:

--stride N              Keep every Nth frame (thin the sequence)
--allow_length_mismatch Use min(images, timestamps) if counts differ
--applied_transform     Optional 3×4 JSON for NerfStudio coordinate rotation

NerfStudio expects camera-to-world matrices in the OpenGL convention (+Y up, -Z forward). If the scene appears upside-down or mirrored, provide an --applied_transform.


4. COLMAP Reference Images — create_colmap_ref_images_from_gps.py

Purpose: Generate a COLMAP ref_images file so that a sparse reconstruction can be geo-registered with model_aligner --ref_images_path.

Dependencies: standard library only.

Default paths from --sequence NAME:

File Path
Cam timestamps results/<NAME>/<NAME>/cam_timestamps.txt
GPS log results/<NAME>/gps.txt
Output results/<NAME>/ref_images_gps.txt

Usage:

python scripts/postprocessing/create_colmap_ref_images_from_gps.py \
  --sequence pipeline_from_uturn

Output format (one line per frame, pass to COLMAP with --ref_is_gps 1):

000001.png  42.014204000  -93.788170000  333.708000
000002.png  ...

GPS coordinates are linearly interpolated to each camera timestamp.


Result folder layout after all steps

results/<name>/
  gps.txt                          ← extracted by preprocessing
  estimated_trajectory.txt         ← VIO program output
  estimated_trajectory_gps.txt   ← GPS-aligned (step 1)
  vio_to_enu_transform.txt         ← alignment parameters (optional)
  ref_images_gps.txt               ← COLMAP reference (step 4)
  visualizations/
    trajectory_overview.png        ← 4-panel static plot (step 2)
    trajectory_animation.mp4       ← animated video (step 2, optional)
    residuals_en.png               ← alignment quality plot (step 1, optional)
  nerfstudio/
    transforms.json                ← NerfStudio export (step 3)
  <name>/
    images/
    cam_timestamps.txt
    imu_data.csv

Dependencies summary

Package Used by
numpy all scripts except create_colmap_ref_images_from_gps.py
matplotlib plot_estimated_trajectory.py, align_vio_to_gps.py (residual plots)
Pillow tum_timestamps_to_nerfstudio_transforms.py (read image dimensions when --width/--height are not given)
ffmpeg (CLI) plot_estimated_trajectory.py (MP4 animation only)

Install Python packages:

pip install -r requirements.txt

ffmpeg for animation export must be on PATH or installed via conda:

conda install -c conda-forge ffmpeg