Skip to content

Repository files navigation

English | 中文

Argosphere

Four fisheye eyes. One all-seeing sphere. — 360° panorama stitching with CPU & GPU (OpenGL ES) backends.

License C++ OpenGL ES Platform

Stitch up to 4 fisheye camera images into a single equirectangular (360°×180°) panorama. The system supports two independent backends — a CPU look-up-table (LUT) stitcher and a GPU pipeline built on OpenGL ES 3.0 + EGL — and can produce:

  • an equirectangular panorama (CPU or GPU, headless),
  • an interactive 3D sphere debug view (rotate / zoom around the stitched sphere), and
  • an interactive little-planet (stereographic) view.

It runs as a two-stage pipeline: a one-time calibration stage that precomputes remap LUTs and a GPU sphere mesh from the camera models, followed by a render stage that applies the precomputed data to actual camera frames.

Results

All three outputs below are stitched from the four bundled test/ fisheye frames (sample data courtesy of zsibot).

Equirectangular panorama (CPU or --gpu):

Equirectangular panorama

Little planet — --planet 3D sphere debug view — --debug
Little planet 3D sphere debug view

Features

  • CPU LUT stitching with 6 blend modes (--blend 0..5): 0=soft (distance-weighted, default), 1=hard, 2=hybrid, 3=multiband (Laplacian pyramid), 4=seam, 5=best.
  • Automatic exposure compensation (per-camera BGR gains) and seam-mask computation during calibration when sample images are present.
  • GPU sphere-mesh blending: a per-vertex multi-camera mesh is rendered with a fragment shader that blends all overlapping cameras in one pass.
  • Interactive viewers (X11 windows): a 3D sphere debug view (--debug) and a little-planet stereographic view (--planet).
  • Per-camera coverage map output (CPU path) for sanity-checking calibration.

Dependencies

  • OpenCV (image I/O, fisheye undistortion, remap, blending)
  • yaml-cpp (reads settings.yaml / exposure gains)
  • EGL and OpenGL ES 3.0 (glesv2) — required by the GPU path
  • X11 (interactive --debug / --planet windows)
  • GLMvendored at include/panorama/glm/, no installation needed

Platform: Linux. The GPU path needs a working EGL / OpenGL ES 3.0 runtime; the interactive viewers additionally need an X11 display. The CPU path has no GPU requirement at runtime, but note that all four libraries above are required to build the project (both executables link the GPU library).

Build

Out-of-source CMake build (C++17):

cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j$(nproc)

A clean Release build takes roughly 9 seconds on a typical machine. For a debug build use -DCMAKE_BUILD_TYPE=Debug. The two executables are written to build/panorama_calib and build/panorama_render; the static libraries (panorama_core, panorama_gpu) go to build/lib/.

Usage

1. Set up the environment

source scripts/setup.bash

This exports PANORAMA_CONFIG_ROOT to the repository root (the code appends sources/... to it) and adds build/lib to LD_LIBRARY_PATH.

2. Generate calibration LUTs and the GPU mesh

./build/panorama_calib

This reads the camera models from sources/camera_models/ and writes the LUTs, masks, blend weights, metadata.yaml, and the GPU sphere_mesh.bin into sources/calibration_files/. If the four sample images test/1.png4.png exist, it additionally computes seam masks and exposure_gains.yaml.

Note: sources/calibration_files/ is a generated artifact directory and is not committed to the repository (it can be hundreds of MB). You must run panorama_calib once before rendering.

3. Render a panorama

The bundled test/ fixtures (1.png4.png, named 1/2/3/4) can be used directly as input, since the loader recognizes N.png/N.jpg filenames.

# CPU equirectangular (default blend mode 0 = soft)
./build/panorama_render --input test --output panorama.jpg

# CPU with a specific blend mode (multiband)
./build/panorama_render --input test --output panorama.jpg --blend 3

# GPU equirectangular (headless / FBO)
./build/panorama_render --gpu --input test --output panorama.jpg

# Interactive 3D sphere debug view (implies --gpu)
./build/panorama_render --debug --input test

# Interactive little-planet / stereographic view (implies --gpu)
./build/panorama_render --planet --input test --planet-scale 0.5

The CPU path also writes a <output>_coverage.jpg camera-coverage map next to the panorama.

panorama_render options

Flag Description
--input <dir> Input image directory (defaults to sources/camera_inputs)
--output <file> Output panorama path (default panorama.jpg)
--lut <dir> LUT directory (default sources/calibration_files)
--mesh <bin> Sphere mesh file (default sources/calibration_files/sphere_mesh.bin)
--root <dir> Config root directory
--blend <0-5> CPU blend mode (see Features)
--display Show the CPU result in a window
--gpu Use the GPU (equirectangular FBO) backend
--debug Interactive 3D sphere view (implies --gpu)
--planet Interactive little-planet view (implies --gpu)
--planet-scale <f> Stereographic scale (default 0.5, smaller = wider)
--planet-size <px> Little-planet output size in px (default 2048)
--help Show usage

Input images are matched against several naming conventions, tried in order: camN.jpg, camN.png, cameraN.jpg, cameraN.png, N.jpg, N.png (N is 1-indexed).

panorama_calib options

Flag Description
--config <path> Path to settings.yaml (default sources/settings.yaml)
--root <dir> Config root directory
--no-gpu Skip GPU mesh generation (CPU LUTs only)
--help Show usage

Both executables honor the PANORAMA_CONFIG_ROOT environment variable, which takes precedence over --root.

Interactive window controls (--debug / --planet)

Key / Action Effect
Mouse drag Rotate the view
Scroll wheel Zoom in / out
W Toggle wireframe (debug view)
C Toggle camera-region color tint
R Reset view
S Save a screenshot
ESC Exit

Repository layout

Path Contents
src/ C++ sources: calibration/ and render/ entry points, GL backend in gl/, plus core stitching/geometry/seam/exposure code
include/panorama/ Public headers, GLSL shader strings, and the vendored glm/ library
sources/ settings.yaml, camera_models/ (calibration YAML), and the generated calibration_files/
scripts/ setup.bash environment helper
test/ Sample fisheye images (1.png4.png) used both as render fixtures and as seam/exposure calibration input

Calibration

Camera intrinsics/extrinsics live in sources/camera_models/ as OpenCV cv::FileStorage YAML files. For the on-disk format and a guide to calibrating your own cameras, see docs/calibration.md.

Data attribution

The calibration data in sources/camera_models/ and the sample fisheye images in test/ are provided courtesy of zsibot.

License

This project is licensed under the Apache License 2.0 — see LICENSE. Third-party components (including the vendored GLM library) and runtime dependencies are documented in THIRD_PARTY.md.

About

panorama fisheye 360 equirectangular image-stitching computer-vision opengl-es egl gpu opencv little-planet surround-view cpp17

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages