Rolling shutter
A rolling-shutter camera exposes rows sequentially, so one image spans a range of times. CamCalib solves the readout time as a parameter rather than correcting for it afterwards.
Enable it
Section titled “Enable it”cameras: - camera_id: 0 shutter_type: rolling # global | rollingPer camera — a rig can mix global- and rolling-shutter cameras freely, and the released 4-IMU/4-camera rig does exactly that.
In a camera–IMU config, readout can be estimated in the cam-IMU stage instead:
camera_input: estimate_readout: trueWhy it is solved jointly
Section titled “Why it is solved jointly”Projection, time offset, rolling shutter, extrinsic composition, and SLERP pose interpolation live in one unified factor. A row’s observation is projected against the trajectory at that row’s time, not the frame’s — so readout is constrained by the same residuals as everything else instead of being a post-hoc correction with no derivative.
What to expect
Section titled “What to expect”Readout is among the weakest parameters in the graph. It is only excited by motion fast enough that rows see meaningfully different geometry — a slow, smooth recording will not constrain it, and the estimate will drift toward whatever the initialisation suggested.
Two checks worth more than a single run’s residual:
- Repeatability. Calibrate several sequences of the same rig with batch mode and compare. A readout that moves between sequences was not observed in them.
- Round-trip.
camcalib roundtripcatches a readout that absorbed error belonging to the time offset.
Reporting
Section titled “Reporting”Readout appears in the HTML report’s temporal-calibration section, merged with the time offset — they are read together for the reason above. Regression comparison reports break out per-collection readout and time offset so drift across a dataset family is visible.
The residual and its Jacobians: Camera model.