Skip to content

Camera model

CamCalib implements six distortion models. Each lives in one place — camera/CameraModel holds its projection, Jacobians, and unprojection — so the same models are available in camera-only and camera–IMU calibration, in board and feature mode, and can be mixed across cameras in a single rig. Models outside GTSAM’s built-ins carry custom analytical Jacobians.

Symbols follow Notation & glossary.

ModelConfig valueOriginSuits
Pinhole + radial-tangentialradtanBrown–ConradyNormal lenses
Equidistant (KB4)equidistantKannala–BrandtFisheye — recommended
FOVfovDevernay–FaugerasWide-angle, single parameter
Double Spheredouble_sphereUsenko / BasaltVery wide FoV
EUCMeucmKhomutenkoVery wide FoV
Omni + radtanomni_radtanMei — experimentalCatadioptric, ultra-wide
config.yaml
cameras:
- camera_id: 0
distortion_model: equidistant

More parameters is not better. A model richer than the lens needs will fit noise, and on wide-FoV data it can slide into a basin that looks converged and is not.

  • Normal lensradtan.
  • Fisheyeequidistant. It is the recommended default for a reason: it is the best-behaved of the wide-FoV models across the benchmark.
  • Very wide FoVdouble_sphere or eucm if equidistant leaves structure in the residuals.
  • Catadioptricomni_radtan, with the caveat that it is experimental.

CamCalib guards against this: the two-pass pathology guardrail reverts to pass 1 if the optimiser lands on a non-positive focal, blown-out distortion, or a P95 regression. It is a backstop, not a substitute for picking the right model.

A rolling-shutter camera exposes rows sequentially, so one image spans a range of times. Set shutter_type: rolling and the per-row readout is solved with everything else:

config.yaml
cameras:
- camera_id: 0
shutter_type: rolling

Projection, time offset, rolling shutter, extrinsic composition, and SLERP pose interpolation all live in one unified factor rather than being applied in sequence. That is what lets readout be estimated jointly rather than corrected afterwards — and the same projection code backs the HTML report, so reported residuals are the ones the optimiser actually minimised.

Practical guidance: Rolling shutter.

The models were compared over a 52-run benchmark across MVIS T265 and TUM-VI 1024 (doc/investigation_ds_convergence.md). On the camera–IMU path, TUM-VI raw IMU bags show omni_radtan and equidistant reproducing the Kalibr cam-IMU extrinsics to ≤2 mm lever, ≤0.15 mm stereo baseline, ≤1 ms time offset.

Model choice does not change the geometry a good fit recovers — it changes whether you get a good fit at all.