From first calibration to fully automated: meet the new camcalib app
Teams already use the camcalib library to calibrate camera, LiDAR and IMU rigs inside their own pipelines, on every vehicle, robot and sensor head they build. The new camcalib desktop app adds the step that comes before automation. You set up a calibration visually, check it with your own eyes, and then hand it to your pipeline as a ready-to-run Python script.
The app and the library use the same calibration engine. Whatever you get in the app, your pipeline gets too.

A guided workflow, from recording to result
The app splits calibration into five clear steps: Load, Configure, Detect, Calibrate, Inspect. A step bar at the top shows where you are. When you change something upstream, it marks which results are out of date.
Drop in a ROS 1 or ROS 2 bag, an MCAP file or a folder of images. You can scrub through the recording, look at every camera side by side, plot the IMU and view the LiDAR point cloud in 3D before any calibration starts.

Set up in minutes, verify on the spot
Give each stream a role (camera, LiDAR or IMU) and pick a camera model, from classic pinhole to fisheye and omnidirectional lenses. Choose your calibration board or reuse a saved one. Supported boards include AprilGrid, ChArUco and chessboards.
One click on Test detection runs the board detector on the current frame, so you know the setup is right before you run the full dataset.

LiDAR–camera calibration: click the board instead of measuring
A LiDAR–camera calibration needs a rough starting guess of where the LiDAR sits relative to the camera. Until now that meant a tape measure, a CAD drawing, and converting roll, pitch and yaw between frame conventions by hand. That last step is where errors creep in.
In the new app, you click the calibration board in a few LiDAR frames. From three or more clicks, camcalib fits the board in the point cloud, matches it with what the camera sees, and computes the starting pose for you. The LiDAR points are drawn straight onto the camera image, so you can see right away that the fit is correct. You don't need a measurement, a rotation convention or reflective tape.

The full calibration is sturdier too. On our test recording, the new board detector found the board in 76 of 76 LiDAR frames, where the previous one found 68. It did so even when the starting guess was 8° and 27 cm off.

Watch it solve, then trust the numbers
Calibration is no longer a black box. While the solver runs, a live plot shows the error dropping, and the results view updates with it. When it finishes you get:
Error per camera, and per frame, so a bad recording stands out right away
Uncertainty for every parameter, so you know how far to trust each number
One-click outlier removal and re-run, with every earlier run kept to compare against

Export to Python: from one calibration to every rig you build
This is where the app and the library come together. Once a calibration looks right, Export Python script turns it into a plain, readable camcalib script. It holds everything you set up in the app: the sensors, the board, the starting guess, the solver settings and the outlier rule.
Run that script on the next recording of the same rig and it repeats the calibration unattended. That could be every vehicle at the end of the line, every robot after maintenance, or every night in CI. It is the same engine as the app, so it gives the same result. It writes the calibration and a report, and it ends with a clear pass or fail through its exit code, based on checks such as convergence, error limits and enough board detections. Your pipeline can act on that without anyone opening the app.
Nothing is hidden. The app previews the full script before you save it, and one click copies it into your own tooling. It's plain Python on the camcalib API, so you can change anything you like.

An excerpt of a real exported script for a four-camera rig with LiDAR and IMU:
"""Camera calibration exported from camcalib-app.
Repeats the app's steps on any recording of the same rig, without user input:
python calibrate_rig.py --source RECORDING --out OUTPUT_FOLDER
Exit code 0: calibrated and every check below passed; 1: a check failed.
"""
SETTINGS = {
"camera_noise": 0.3, # px
"lidar_noise": 0.01, # m
"minimum_corners_per_target": 7,
}
# Checks that decide the exit code.
MAX_RMSE_PX = 0.653
MIN_FRAMES_WITH_DETECTION = {"camera_front": 453, "camera_left": 465, ...}
...
data.from_bag(source, sensor_filter=streams, lidar_max_frames=lidars)
result, summary, errors, lidar_errors = calibrate(data, initial, settings, lidars)
result.save(str(out / "result.yaml"))For teams already scripting with camcalib, nothing changes. Your scripts keep working, and now you can start new ones visually.
Try it on your own rig
The camcalib app runs on Windows, macOS and Linux and reads the recordings you already have. It supports pinhole, fisheye and omnidirectional cameras, 3D LiDARs, and IMUs.
Send us a recording and we'll show you the whole path, from the first click to a calibration script running in your pipeline. Request a demo →



Comments