A minimal, automated toolkit to calibrate a 4-camera fisheye system (e.g., OAK-FFC-4P) and generate rectification maps for stereo depth estimation of the OmniNxt system. This repo was inspired by this repo.
This toolkit streamlines the process into two steps:
-
Physical Calibration Records ROS 2 data and uses TartanCalib (Docker) to solve intrinsics and extrinsics.
-
Map Generation Analytically generates virtual stereo cameras, computes rectification, merges lookup tables, and visualizes results for verification.
Install the required Python packages:
pip install -r requirements.txtROS 2 (Humble recommended) Source your environment:
source /opt/ros/humble/setup.bashDocker Required for running the TartanCalib calibration solver.
Before starting the calibration scripts, launch the camera driver oak_ffc_4p_driver to publish the required image topics. Make sure that your drone and your PC where you're doing the calibration have the same ROS_DOMAIN_ID to be able to subscribe to the image topic.
Crucial: Ensure your driver configuration (cam_config.yaml or equivalent parameters) matches the settings below.
synс_master must be set, and compress_images: true should be enabled for efficient recording.
oak_ffc_4p_driver_node:
ros__parameters:
sync_master: "CAM_A" # master clock: "CAM_A", "CAM_B", "CAM_C", "CAM_D"
resolution: "800"
fps: 10
rgb: true
auto_exposure_time: true
exposure_time_us: 10000
iso: 400
image_info: true
auto_awb: true
awb_value: 4000
sharpness_calibration_mode: false
enable_upside_down: false
max_size_fps: 10
publish_cams_individually: false
compress_images: true
jpeg_quality: 90Run calibrate_physical.py to record a calibration sequence and solve for the physical parameters of the rig:
python3 calibrate_physical.py A window will open showing the camera feed (4-image grid).
Press SPACE to advance through stages:
The order or recording goes like this for easy setup: mono0, pair01, mono1, pair12, mono2, pair23, mono3, pair30.
Press Q to finish recording.
The script will automatically launch Docker to run the solver.
After the calibration is done, check the pdf files in calibration_output/cam_* and make sure the reprojection error is less then 1.5 pixels. If not, you can recalibrate the camera/pair in question using the --only argument (see arguments below).
--out– Output directory (default:calibration_output)--topic– ROS 2 image topic (default:/oak_ffc_4p_driver_node/compressed)--uncompressed– Use if topic publishes rawsensor_msgs/Image--only– Calibrate specific targets only (e.g.,--only mono0,pair01)--skip-recording– Re-calibrate using existing bags only
Run the map generation script:
python3 generate_maps.py --width 224 --height 224 --hfov 110For each stereo pair, a window will show:
Top: Raw input pair Bottom: Rectified pair with green horizontal epipolar lines
You should verify that:
- Green lines are perfectly horizontal
- Features align across left/right views
Press any key to continue to the next pair.
--calib-dir– Input calibration folder (default:calibration_output)--out-dir– Output directory for final maps (default:final_maps)--width, --height– Final rectified resolution (default: 224x224)--hfov– Horizontal FoV for virtual stereo (default: 110°)
The final_maps/ directory will contain all the configuration files required by the depth estimation node.
final_rectified_to_fisheye_map_{i}_{j}.yml– OpenCV remap lookup tablesfinal_map_config_{i}_{j}.yaml– Calibration metadata (intrinsics, baseline, poses)
Copy the contents of:
final_maps/
to your depth estimation package’s config directory, e.g.:
depth_estimation_ros2/config/final_maps_224_224
Add calibration between cameras and IMU for VIO.
