Overview
CamCalib is a Python camera-calibration toolbox for single- and multi-camera systems, built on GTSAM factor-graph optimisation with native SO(3)/SE(3) Lie group support. It is the calibration library behind Open MVIS, and it replaces the earlier C++/ROS implementation.
Everything is solved in one graph — intrinsics, distortion, extrinsics, time offsets, rolling-shutter readout, board poses, and, with an IMU, the camera–IMU transform, IMU intrinsics, and biases.
What makes it different
Section titled “What makes it different”No ROS required. Pure Python, pip install, Windows/macOS/Linux. Bags are
read through rosbags, so a ROS1 or ROS2 recording calibrates on a machine that
has never had ROS installed.
Six distortion models, mixable. radtan, equidistant, fov,
double_sphere, eucm, and experimental omni_radtan — available in both
camera-only and camera–IMU calibration, and mixable across cameras in one rig.
Multi-IMU. Several IMUs in one graph, each with its own extrinsics, time offset, and intrinsics; per-IMU gyro-only mode for sensors whose accelerometer you cannot trust.
It checks its own work. camcalib roundtrip applies a calibration to the
data it came from and recalibrates — a PASS requires the IMU intrinsics to
collapse to identity and the geometry to stay put. That is a much stronger
statement than a low residual.
Three ways it is used
Section titled “Three ways it is used”Full calibration. Solve everything from a board sequence.
Refinement. Start from an existing calibration — Kalibr output reads
directly via camcalib.io.kalibr — and refine it.
Partial calibration. Pin what you trust and solve the rest. The common case is camera–IMU calibration with intrinsics pinned from a prior camera-only run, which is the recommended two-step workflow.
Why one graph
Section titled “Why one graph”Calibrating a rig pairwise accumulates error: each pairwise result carries its own uncertainty, and composing them discards the correlations between them. Solving jointly keeps those correlations, which matters most for the weakly observable parameters — time offsets, rolling-shutter readout, and IMU intrinsics. See Calibration graph.
The same principle shows up in the implementation: pose interpolation, extrinsic composition, time offset, rolling shutter, and projection are one unified factor, not a chain of corrections.
The shape of a run
Section titled “The shape of a run”Detection → Quality gating → Init → Per-camera opt → Alignment → Joint opt → Outlier rerun- Target and data — print a board, record with well-excited motion.
- Config — one YAML: board, cameras, optimiser.
- Run —
camcalib calibrate -c config.yaml. - Read —
*_calib.yamlto deploy,*_full.yamlto replay, and a self-contained HTML report. - Validate — repeatability across sequences, and
camcalib roundtripfor camera–IMU.
Where to go next
Section titled “Where to go next”- Never run it → Quickstart.
- Have a rig → Camera calibration, then Camera–IMU.
- Public data → Examples.
- The maths → Concepts.