Skip to main content
Version: dev-latest

Migrating from Kalibr to MetriCal

Objectives

  • Migrate your calibration process from Kalibr to MetriCal

One of the most common questions we get is how to migrate from Kalibr to MetriCal. This tutorial will guide you through the process of migration, the main differences in operation, and what you should expect.

Why Migrate?

We'll freely admit, Kalibr makes a lot of sense when first getting started with camera calibration. It's accurate, documented, and has a large user base. On top of that, it's open source, which is a huge draw for those who like to dive into the math.

However, it is not designed for scalable production. It is an academic tool for small-scale projects. MetriCal is more robust, scalable, and maintainable, with a whole company devoted to continuously improving its user experience. Some improvements you can expect:

  • Drastically improved time to calibration (>10x improvement on large datasets)
  • Use multiple fiducials, not just one
  • Equal or greater accuracy in calibration results
  • Easily-digestable metrics across every component
  • More modalities supported out of the box
    • Cameras, IMU, LiDAR
    • Radar, sensor-to-chassis coming soon
  • More intrinsics models supported out of the box
  • Complete reporting of parameter covariances
  • Enhanced visualization tools

...among others. The good news is that much of your data collection processes can remain the same! ROSbags are supported, along with MCAPs, and MetriCal can use Kalibr-style Aprilgrids as fiducials. Whatever you're doing for data collection, just keep doing it!

Once you're ready to scale your systems, we're confident that you'll find MetriCal to be the right tool for the job.

Operational Differences

Camchains vs. Plex

The most significant difference between Kalibr and MetriCal is the way they handle extrinsics. Kalibr uses a "camchain" structure, where each component is connected to the next in a chain. In order to derive the extrinsics between two cameras, you must traverse the chain from one camera to the other.

MetriCal uses the plex structure, where each component is connected to every other component in a fully connected graph, along with a measurement of uncertainty along each connection. This means that there are actually several ways to derive the spatial constraints between two components, depending on the path you take through the graph.

Spatial Constraint Traversal

You can read more about how extrinsics are treated in the Plex by perusing the Spatial Constraint Traversal documentation.

In practice, it's best to use the Shape command to derive the "best" (i.e. most precise) path between two components. If you would like to program your own pathfinding algorithm, you can use our reference implementation in the MetriCal Utilities repository, found here.

Motion Filtering

Artifacts from excessive motion can ruin a calibration. To prevent this fate, MetriCal has a built-in motion filter that automatically identifies and removes frames with excessive motion from your dataset. This is especially useful for large datasets where most of the data can be either redundant or noisy.

Motion Filtering

Read more about the motion filter in the documentation for Calibrate mode.

Those used to Kalibr will be familiar with the bag-freq parameter, which is used to remove data in a more heuristic way by taking every Nth observation. MetriCal uses a fundamentally different philosophy; with the right data capture process, there should never be a reason to throw away data without cause.

If you do find that you need to downsample your data, or you would like to use all your data during a calibration, we either recommend modifying the camera motion threshold or disabling the motion filter entirely.

Migrations

Camera Model Conversion

Here's a handy conversion chart for Kalibr camera models to MetriCal camera models:

Kalibr ModelCorresponding MetriCal Model
pinholeno_distortion
pinhole-radtanopencv_radtan
pinhole-equiopencv_fisheye
omniomni
dsdouble_sphere
eucmeucm

Describing Your Target/Object Space

The conversion between Kalibr and MetriCal is straightforward. The only difference is that MetriCal can support more than one fiducial at a time, which means MetriCal has to add UUIDs to each.

Here's an example of how to convert a Kalibr target YAML to a MetriCal object space JSON:

Kalibr Target YAML

target_type: "aprilgrid"
tagCols: 5
tagRows: 6
tagSize: 0.088
tagSpacing: 0.3

MetriCal Object Space JSON

{
"object_spaces": {
"24e6df7b-b756-4b9c-a719-660d45d796bf": {
"descriptor": {
"variances": [0.01, 0.01, 0.01] // Recommended default values
},
"detector": {
"april_grid": {
"marker_dictionary": "ApriltagKalibr",
"marker_grid_height": 6,
"marker_grid_width": 5,
"marker_length": 0.088,
"tag_spacing": 0.3
}
}
}
}
}

Script Migration

If you're used to running Kalibr from the command line, you'll find that MetriCal is quite similar; it just has a few more options.

Here's an example of migrating a calibration script from Kalibr to MetriCal:

Kalibr Command

kalibr_calibrate_cameras       \
--bag data.bag \
--topics /cam_one /cam_two \
--models pinhole eucm \
--target target.yaml

MetriCal Command

# Profile our data and create an initial plex
metrical init \
-m /cam_one:no_distortion \
-m /cam_two:eucm \
data.bag init_plex.json

# Calibrate our system
metrical calibrate \
-o results.json \
data.bag init_plex.json target.json

# Derive the minimum spanning tree of our plex
metrical shape mst results.json .