Skip to main content

Comprehensive camera-lidar calibration suite with GUI and fleet management

Project description

Calibrate-Suite: Multi-Modal Sensor Calibration

A comprehensive calibration suite for LiDAR-Camera extrinsic calibration using AprilTag fiducials(for 2d-3d method) and a plane board(for 3d-3d method). Provides three calibration frameworks with CLI tools, REST API, and PyQt5 GUI for desktop and fleet-scale deployments(dummy test).


๐Ÿ“‹ Table of Contents

  1. Project Overview
  2. Features
  3. Installation
  4. Dependencies & Conflicts
  5. Quick Start
  6. Calibration Frameworks
  7. Command-Line Tools
  8. Data Formats
  9. Cautions & Best Practices
  10. Troubleshooting
  11. FAQ
  12. Version

๐ŸŽฏ Project Overview

Calibrate-Suite provides production-ready tools for calibrating the extrinsic transformation between LiDAR and camera sensors in robotic platforms. The package includes:

  • Three calibration frameworks targeting different sensor configurations (LiDAR-only, 3D-3D, 2D-3D (AprilTag-based))
  • Desktop GUI (PyQt5) for interactive calibration workflows
  • REST API (Flask) for distributed fleet management dummy illustration
  • Command-line tools for automated batch processing
  • Multiple installation methods supporting both pip and ROS2 environments

Supports: Ubuntu 20.04+, Python 3.8+, ROS2(humble)(optional)

Hardware Setup

Hardware Setup

Pattern Generator: i used the Calib io Pattern Generator for the AprilGrid


โœจ Features

Core Calibration

  • โœ… LiDAR-Camera extrinsic calibration using AprilTag fiducials for 2D-3D and plane board for 3D-3D
  • โœ… Three frameworks for different sensor setups and use cases
  • โœ… Automatic corner normalization in single-pass calibration(2D-3D)
  • โœ… Robust quality filtering with per-pose metrics
  • โœ… Comprehensive error reporting (reprojection, translational, rotational)
  • โœ… Multi-pose support (20+ poses used)

Desktop GUI

  • โœ… Tab-based interface for all frameworks and tools
  • โœ… Real-time data visualization with 3D point cloud overlay
  • โœ… Interactive parameter tuning with live metrics
  • โœ… Web-based 3D viewer for browser access(the dummy server)
  • โœ… PCD file browser and upload functionality

REST API (dummy Fleet Server)

  • โœ… Calibration management endpoints
  • โœ… Result persistence with YAML/JSON export
  • โœ… Metrics dashboard for fleet monitoring
  • โœ… File upload/download for distributed workflows
  • โœ… Browser-based interface for web access

Data Processing

  • โœ… Automatic data extraction from ROS2 bags
  • โœ… Synchronized sensor capture (camera + LiDAR)
  • โœ… Point cloud filtering and preprocessing
  • โœ… AprilTag detection and corner localization
  • โœ… Board segmentation and quality assessment

Deployment

  • โœ… pip installation for standard Python environments
  • โœ… ROS2 colcon build for local deployments on ROS2
  • โœ… System package compatibility (no Qt/RViz conflicts)
  • โœ… Docker support ready
  • โœ… Minimal dependencies with optional extras

๐Ÿ“ฆ Installation

Prerequisites

# Python 3.8 or higher
python3 --version

# System packages (Ubuntu 22.04)
sudo apt update

Installation Options

Option 1: ROS2 + System Packages (Recommended for ROS users)

# Install system dependencies
sudo apt install python3-opencv python3-open3d python3-pyqt5 python3-yaml

# Build with ROS2
cd ~/calib_ws
colcon build --packages-select calibrate-suite
source install/setup.bash

# Launch after installation
calibrate-suite  # GUI
fleet-server      # REST API

Option 2: pip - Core Only (Minimal)

pip install calibrate-suite

Option 3: pip - With Computer Vision

pip install calibrate-suite[cv]

Option 4: pip - With 3D Processing

pip install calibrate-suite[3d]

Option 5: pip - With GUI

pip install calibrate-suite[gui]

Option 6: pip - Full Installation (Isolated venv recommended)

python3 -m venv calib_env
source calib_env/bin/activate
pip install calibrate-suite[full]

# Launch commands after installation
calibrate-suite  # GUI
fleet-server      # REST API (optional parameters: --host 0.0.0.0 --port 8080 --debug)

Verification

# Check installation and verify commands are available
which calibrate-suite
which fleet-server

# Quick test of GUI
calibrate-suite --version

# Quick test of server
fleet-server --version

๐Ÿ”ง Dependencies & Conflicts

Core Dependencies (Always Required)

Package Version Purpose
numpy โ‰ฅ1.20.0 Numerical computing
scipy โ‰ฅ1.7.0 Scientific functions
scikit-learn โ‰ฅ1.0.0 Machine learning algorithms
Flask 2.3.3 REST API framework
requests 2.31.0 HTTP client
python-dotenv 1.0.0 Environment configuration
pyyaml โ‰ฅ6.0 YAML parsing

Optional Dependencies (Feature-Specific)

Extra Packages When to Use
[cv] opencv-python โ‰ฅ4.5.0 Computer vision, AprilTag detection
[3d] open3d โ‰ฅ0.13.0 3D point cloud processing
[visualization] matplotlib โ‰ฅ3.3.0 Result visualization
[gui] PyQt5 โ‰ฅ5.15.0 Desktop GUI application
[full] All packages Complete feature set
[dev] pytest, black, flake8 Development & testing

Known Conflicts & Solutions

Issue: OpenCV conflicts with system Qt/RViz

Problem: pip opencv-python can conflict with system OpenCV
Solution: Use system package instead
  sudo apt install python3-opencv
  pip install calibrate-suite  # without [cv]

Issue: PyQt5 conflicts in ROS2 environment

Problem: pip PyQt5 may conflict with ROS2 system packages
Solution: Use system PyQt5
  sudo apt install python3-pyqt5
  pip install calibrate-suite  # without [gui]

Issue: NumPy 2.x compatibility

Problem: Some packages compiled against NumPy 1.x
Solution: Pin NumPy version if needed
  pip install 'numpy<2' calibrate-suite[full]

๐Ÿš€ Quick Start

GUI Application (Recommended)

# Launch desktop application
calibrate-suite

# Tabs available:
# - Home: Quick navigation
# - Recorder: Capture ROS2 bag data
# - Extractor: Extract frames and point clouds
# - Single LiDAR: LiDAR-only calibration
# - 3D-3D: Dense 3D point cloud calibration
# - 2D-3D: AprilTag-based calibration (recommended)
# - Calibrator: Advanced settings and batch processing

GUI Workflow Tabs:

Home/Record Overlay
Home Interface Record Page

Command-Line (Quick Calibration)

cd /home/jamih/calib_ws/src/calibrate-suite/src

#launching calibrator suite from terminal
# Method 2: Direct Python execution
python3 -m gui.main

# Method 3: Direct script execution
python3 gui/main.py

# 2D-3D Calibration (AprilTag-based, recommended)
python3 2d_3d_calibrator.py --data_root ../calib_data/multimodal_captures

# View results
cat ../calib_data/multimodal_captures/final_extrinsic.yaml

Data Processing Pipeline

# 1. Extract synchronized data from ROS2 bag
python3 2d_3d_data_extractor.py \
  --data_root ../calib_data/multimodal_captures\
  --output ../calib_data/multimodal_captures \
  --num-poses 20

# 2. Run calibration
python3 2d_3d_calibrator.py --data_root ../calib_data/multimodal_captures

# 3. Visualize results
python3 visualize_alignment.py --data_root ../calib_data/multimodal_captures

๐Ÿ“ Calibration Frameworks

Framework 1: Single LiDAR Calibration

Purpose: Point cloud self-registration and intrinsic validation

Features:

  • Point cloud pair registration using Point-to-Plane ICP
  • FPFH-RANSAC global registration for difficult alignments
  • Hybrid initialization (centroid multi-start + FPFH-RANSAC)
  • Multi-scale ICP pyramid (coarse โ†’ medium โ†’ fine)
  • GICP final refinement for sub-millimeter accuracy
  • Statistical outlier removal
  • Adaptive Voxel-based downsampling
  • Fitness score and RMSE metrics

Input:

  • Source and target PCD files (.pcd)

Output:

  • Transformation matrix (4ร—4)
  • Fitness score (0-1)
  • RMSE error (meters)
  • Aligned point cloud visualization

Single LiDAR Output

When to Use:

  • Sensor self-calibration and intrinsic validation
  • Point cloud registration debugging
  • Temporal drift assessment
  • LiDAR-to-LiDAR pose estimation

Note:

  • when you run single Lidar capturing under bag mode, Rviz might seem unstable, just click the pause/play button, it will stabilize after that

GUI Usage:

GUI โ†’ Single LiDAR Tab โ†’ Upload PCD files โ†’ Select method โ†’ Run โ†’ View metrics
Record Calibrate
Single LiDAR Record Single LiDAR Calibrate

Framework 2: 3D-3D Camera-LiDAR Calibration

Purpose: Dense point cloud correspondence calibration

Features:

  • 3D point cloud extraction from both camera and LiDAR
  • DBSCAN clustering for board segmentation
  • Centroid-based initial estimation
  • Least-squares iterative refinement
  • Per-pose quality metrics (centroid error, normal error, point-to-plane RMSE)
  • Cloud overlay visualization

Input:

  • Camera point clouds (depth+image-to-3D conversion)
  • LiDAR point clouds (PCD files)
  • Synchronized multi-pose captures

Output:

final_extrinsic.yaml:
  rotation_matrix: 3ร—3
  translation_vector: [x, y, z]
  metrics:
    centroid_error_m: float
    normal_error_deg: float
    rmse_error_m: float
  per_pose_quality: [...]

3D-3D Calibration Output

When to Use:

  • Both sensors provide dense 3D data
  • High-precision applications required
  • Full point cloud validation needed
  • Stereo camera + LiDAR setups

GUI Usage:

GUI โ†’ 3D-3D Tab โ†’ Select data directory โ†’ Configure parameters โ†’ Run โ†’ View metrics

Framework 3: 2D-3D Camera-LiDAR Calibration (Recommended) โญ

Purpose: AprilTag fiducial-based corner correspondence calibration (RECOMMENDED)

Features:

  • AprilTag detection in camera images (6ร—6 grid)
  • 2D corner localization in pixel coordinates
  • LiDAR corner extraction via PCA and DBSCAN
  • 8-permutation search for optimal corner matching
  • Automatic corner index normalization in single pass
  • Quality filtering (best N poses by board quality)
  • Huber loss optimization with outlier rejection
  • Comprehensive error metrics per pose
  • Reprojection and translational error reporting
  • Convergence guarantees with verification pass

Input:

  • 20+ synchronized multi-pose captures
  • Camera images (arbitrary resolution, e.g., 1920ร—1440)
  • Point cloud scans (E.g., Velodyne, RoarIndar, etc.)
  • AprilTag board (8ร—11 grid, any tag size or grid)
final_extrinsic.yaml:
  method: camera_pose_iterative_quality_filtered
  rotation_matrix: 3ร—3
  translation_vector: [x, y, z]
  euler_angles_deg: [roll, pitch, yaw]
  reprojection_error_metrics: {...}
  fitness_scores: {...}
  quality_distribution: {...}
  calibration_info: {...}

2D-3D Calibration OutputOutput:

When to Use:

  • AprilTag board is available
  • Corner-based correspondences required
  • Multi-pose dataset available (20+ poses)
  • Need comprehensive error metrics
  • Want automatic normalization and single-pass completion
  • Standard camera+LiDAR robotics applications

GUI Usage:

GUI โ†’ 2D-3D Tab โ†’ Select data directory โ†’ Configure quality filter โ†’ Run โ†’ View metrics
GUI Interface Alignment Visualization
2D-3D Calibration Alignment Overlay

๐Ÿ’ป Command-Line Tools

Data Extraction Tools

# Synchronized extraction from ROS2 bag
cd src
python3 3d_3d_data_extractor.py \ 
  --bag path-to-bag \ 
  --output ../calib_data/captures \ 
  --num-poses 20 \ 
  --sync-tolerance 100

# Extract camera images only(it will be 3d_3d_data extractor for the 3d_3d mode)
python3 2d_3d_data_extractor.py \ 
  --bag path-to-bag \ 
  --type camera \ 
  --output ../calib_data/camera_images

# Extract LiDAR point clouds only
python3 2d_3d_data_extractor.py \ 
  --bag path-to-bag \ 
  --type lidar \ 
  --output ../calib_data/lidar_clouds

# single lidar data extraction
python3 single_data_extractor.py \ 
  --bag path-to-bag \

Calibration Tools

# 2D-3D calibration (AprilTag-based, recommended)
python3 2d_3d_calibrator.py \ 
  --data_root ../calib_data/multimodal_captures \  
  --quality-filter 0.05 \ 
  --output final_extrinsic.yaml

# 3D-3D calibration (Dense point cloud)
python3 3d_3d_calibrator.py \ 
  --camera_pcds ../calib_data/camera_pcd \ 
  --lidar_pcds ../calib_data/lidar_pcd \ 
  --output final_extrinsic.yaml

# Single LiDAR registration
python3 single_lidar_calib.py \ 
  --source source.pcd \ 
  --target target.pcd \ 
  --output registration.yaml

Visualization Tools

# Generate 3d_3d mode alignment overlays
python3 3d_3d_overlay.py \ 
  --data_root ../calib_data/multimodal_captures \ 
  --output alignment_viz/

# Overlay AprilTag detection for 2d_3d
python3 2d_3d_overlay.py \ 
  --data_root ../calib_data/multimodal_captures \ 
  --pose 1

# generate/Verify corner detection
python3 camtag_det.py \ 
  --data_root ../calib_data/multimodal_captures

python3 lidtag_det.py \ 
  --data_root ../calib_data/multimodal_captures

๐Ÿ“Š Data Formats

Directory Structure (Package-Created)

When using calibrate-suite, the following directory structure is created(note, they can be changed as per your wish in the GUI):

calib_data/
โ”œโ”€โ”€ multimodal_captures/              # Main calibration dataset
โ”‚   โ”œโ”€โ”€ camera_intrinsics.yaml        # Camera K, D matrices
โ”‚   โ”œโ”€โ”€ final_extrinsic.yaml          # Output extrinsic transformation
โ”‚   โ”œโ”€โ”€ calibration_metrics.json      # Per-pose metrics
โ”‚   โ”œโ”€โ”€ pose_1/
โ”‚   โ”‚   โ”œโ”€โ”€ frame.jpg                 # Original camera image
โ”‚   โ”‚   โ”œโ”€โ”€ anot_image.jpg            # Annotated with corner detections
โ”‚   โ”‚   โ”œโ”€โ”€ board_plane.pcd           # Filtered/segmented LiDAR cloud
โ”‚   โ”‚   โ”œโ”€โ”€ detections.yaml           # Camera and LiDAR corner detections
โ”‚   โ”‚   โ””โ”€โ”€ metrics.yaml              # Per-pose quality metrics
โ”‚   โ”œโ”€โ”€ pose_2/
โ”‚   โ”‚   โ””โ”€โ”€ [same structure]
โ”‚   โ””โ”€โ”€ alignment_viz/                # Visualization outputs
โ”‚   |   โ”œโ”€โ”€ pose_1_overlay.jpg        # Corner reprojection overlay
โ”‚   |   โ”œโ”€โ”€ pose_1_cloud.jpg          # Point cloud projection
โ”‚   |   โ””โ”€โ”€ ...
|----

Board Geometry Configuration

board_type: "AprilTag"
grid_dimensions: [8, 11]              # 8ร—11 tag grid, it can be as per your board
tag_size_m: 0.04                     # Individual tag width
board_width_m: 0.609                 # Total board width
board_height_m: 0.457                # Total board height
tag_spacing_m: 0.005                 # Gap between tags (if any)

โš ๏ธ Cautions & Best Practices

Data Collection Best Practices

โœ… DO:

  • Capture 20+ poses with board at varying angles (0ยฐ-60ยฐ from camera normal)
  • Ensure consistent, even lighting throughout capture sequence
  • Keep AprilTag board planar and undamaged
  • Verify sensor time synchronization (<100ms offset)
  • Calibrate camera intrinsics separately beforehand(if not sure of its intrinsics)
  • Document environmental conditions (lighting, reflectance, temperature)
  • Perform test calibration with subset before full dataset

โœ— DON'T:

  • Use fewer than 15 poses (insufficient statistical sampling)(might be less though)
  • Allow board to contact sensor brackets or cables (occlusion/deformation)
  • Capture images with severe motion blur
  • Mix board orientations or rotate frame mid-capture
  • Have LiDAR points sparse or with extreme reflectance outliers
  • Assume intrinsic parameters are accurate without verification
  • Recalibrate unnecessarily (extrinsics typically remain stable)

Quality Assessment

Warning Signs:

  • High standard deviation in error distribution (outliers present)
  • Asymmetric error distribution (systematic bias exists)
  • Rotational error > 60ยฐ (check mechanical alignment)
  • All 20 poses accepted without filtering (quality filter too lenient)
  • Non-identity corner permutations after normalization (check board orientation)

AprilTag Board Setup

The calibrate-suite works with any AprilTag grid configuration, not limited to 8ร—11:

  • Grid size: Configurable (e.g., 4ร—4, 5ร—5, 8ร—8)
  • Tag size: Any size (adjust config/board_geometry.yaml)
  • Board material: Any flat surface with AprilTags
  • Spacing: Regular grid required for PCA-based board frame

Board must be:

  • Planar (flat, no warping)
  • Rigidly mounted (no vibration)
  • Visible to both camera and LiDAR simultaneously
  • Not occluded or partially obscured

๐Ÿ”ง Troubleshooting

Symptom Probable Cause Solution
AprilTag not detected Poor lighting or high exposure time Improve illumination, reduce exposure, check camera focus
Few LiDAR corners detected (<2) Low point cloud density or reflectance Move board closer, ensure LiDAR line-of-sight, check surface reflectance
High reprojection error (>100px) Time sync offset or incorrect intrinsics Verify camera sync (<100ms), recalibrate camera intrinsics
Rotation error >90ยฐ Multiple outlier poses not filtered Increase quality_filter parameter (0.1m), manually review poses
Calibration fails to converge Dominant outliers or bad permutation search Reduce huber_delta (1.5px), check board orientation consistency
Corner indices not normalized Permutation search failed to find match Verify board geometry in config, check corner detection quality
All poses marked "poor" Board completely out of focus or occluded Check camera focus, ensure board visibility, verify synchronization
Memory error during processing Large point clouds not downsampled Reduce voxel size or enable downsampling in config

Common Command Errors

# Error: "ModuleNotFoundError: No module named 'cv2'"
# Solution: Install OpenCV
sudo apt install python3-opencv
# OR
pip install calibrate-suite[cv]

# Error: "No module named 'open3d'"
# Solution: Install Open3D
sudo apt install python3-open3d
# OR
pip install calibrate-suite[3d]

# Error: "PyQt5 import failed" (GUI)
# Solution: Install PyQt5
sudo apt install python3-pyqt5
# OR
pip install calibrate-suite[gui]

# Error: "YAML parsing failed"
# Solution: Verify YAML format and reinstall
sudo apt install python3-yaml
pip install 'pyyaml>=6.0'

REST API Server (Fleet Management)

Note: The fleet server is a dummy reference implementation for demonstration purposes. It provides basic REST endpoints for uploading calibration results from multiple robots. You can test the upload functionality from the GUI by pointing it to your own server URL.

#launching through terminal
cd /home/jamih/calib_ws/src/calibrate-suite/src
# Method 1: Using entry point (if installed)
fleet-server

# Method 2: With custom host/port
fleet-server --host 0.0.0.0 --port 8080 --debug

# Method 3: Direct Python execution
python3 -m fleet_server.app

# Method 4: Direct script execution
python3 fleet_server/app.py


# Optional parameters:
# fleet-server --host 0.0.0.0 --port 8080 --debug

# Access dashboard: http://localhost:5000
# API endpoints: http://localhost:5000/api/...

Testing from GUI:

  1. In the calibrate-suite GUI, go to the Fleet tab
  2. Enter your server URL (e.g., http://localhost:5000 or your custom server address)
  3. Upload calibration results to your own fleet management backend

Fleet Upload Interface


Performance Optimization

If processing is slow:

# Reduce point cloud density
python3 2d_3d_calibrator.py \
  --data_root ../calib_data/multimodal_captures \
  --voxel-size 0.01              # Increase for faster processing (default 0.005)
  --max-correspondence-dist 0.2  # Increase search radius

# Reduce number of poses
python3 2d_3d_calib.py \
  --data_root ../calib_data/multimodal_captures \
  --max-poses 15                 # Use best 15 poses instead of 20

โ“ FAQ

Q: Which calibration framework should I use?
A: Framework 3 (2D-3D AprilTag-based) is recommended for standard camera+LiDAR setups. Use Framework 2 for stereo+LiDAR or dense depth+LiDAR. Use Framework 1 for LiDAR self-calibration only.

Q: Why do I need 20 poses minimum?
A: Statistical robustness and noise reduction. Fewer poses provide insufficient sampling of the transformation space and make results sensitive to outliers.

Q: Can I use a different board configuration?
A: Yes. Modify config/board_geometry.yaml with your grid size and tag dimensions. The corner detection adapts to any regular AprilTag grid.

Q: How do I integrate the calibration into my ROS2 pipeline?
A: Load final_extrinsic.yaml into your tf2 broadcaster or calibration node. See ROS2 documentation for tf2 static transforms.

Q: What if I have a different LiDAR type?
A: The point cloud processing is format-agnostic. As long as you have synchronized PCD files, the calibration works with any LiDAR (Velodyne, RoarIndar, OS1, etc.).

Q: Can I run this in Docker?
A: Yes. The package is Docker-ready. Dockerfile and compose configuration are available in the repository.

Q: How often should I recalibrate?
A: Extrinsics typically remain stable for months. Recalibrate only if: (1) sensors were physically moved, (2) mechanical stress/vibration occurred, or (3) recalibration validation fails.

Q: Does the package support real-time calibration?
A: Current implementation is batch-based. Real-time streaming calibration is planned for future releases.

Q: Can I export calibration for other tools?
A: Yes. The output is standard YAML with rotation matrix and translation vector. Compatible with ROS2 tf2, OpenCV, and most robotics frameworks.

Q: What is the typical calibration accuracy?
A: Mean reprojection error typically 30-50 px depending on sensor quality and data collection. Rotational error < 5ยฐ for rigid platforms.

Q: How do I handle multiple sensors on the same platform?
A: Run separate calibrations for each camera+LiDAR pair. Combine results using platform geometry (e.g., manual mounting offsets).


๐Ÿ“„ Version

Package Version: 0.1.0
License: MIT

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

calibrate_suite-0.1.0.tar.gz (1.6 MB view details)

Uploaded Source

Built Distribution

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

calibrate_suite-0.1.0-py3-none-any.whl (1.6 MB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: calibrate_suite-0.1.0.tar.gz
  • Upload date:
  • Size: 1.6 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.12

File hashes

Hashes for calibrate_suite-0.1.0.tar.gz
Algorithm Hash digest
SHA256 68a716734f2e1e2fde682cc253f1271414d60419734ba2cce2831ca08bc2fcb3
MD5 e2315837771993e9cc26ce9f6b77629f
BLAKE2b-256 103beb9270bb136942a188f94fe49deff45195b67f40ed77d512c00215e65e61

See more details on using hashes here.

File details

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

File metadata

File hashes

Hashes for calibrate_suite-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b47a2e273a0c3938f60e170bead896d0a5c6d86ae3a2b77e6e53a7452ba50f57
MD5 f2f3be05838d3566378d5fe42203ce49
BLAKE2b-256 a222712d876f2db872c506efd6de959c7fc5f4d68d2df59687d0de4e1395c002

See more details on using hashes here.

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