Calibration From Scratch Using Rust, Part 3: Application in Rust
Access code building blocks to create a sensor calibration module in Rust.
Paul Schroeder
Staff Perception Engineer
Jun 3, 2021

Explore our entire Calibration From Scratch Series:
If you’d like to be notified of when that next post drops, just follow us on LinkedIn or subscribe to our newsletter.
—
In Part 1 and Part 2 of our series, we covered the theory, principles, mathematics, and some of the code required to create your own camera calibration module. If you have not yet read Part I and II, we strongly recommend doing so to ground yourself in these elements before exploring Part III, where we apply this to creating a model.
Because the Tangram Vision codebase is written in Rust, we'll use that to demonstrate how to create a calibration module. We’ll be using the NAlgebra linear algebra crate and the argmin optimization crate. You can follow along here, or with the full codebase at the Tangram Visions Blog repository. Let's get started.
Putting it Together
Generating Data
In this tutorial, we aren’t going to work with real images, but rather synthetically generate a few sets of image points using ground truth transforms and camera parameters.
To start, we’ll generate some model points. The planar target lies in the XY plane. It will be a meter on each edge.

Then we’ll generate a few arbitrary camera-from-model transforms and some camera parameters.
Finally, we’ll generate the imaged points by applying the image formation model. You can see which synthetic images we rendered by applying the ground truth camera-from-model transform and then projecting the result using the ground truth camera model.

Building the Optimization Problem
We’re going to use the `argmin` crate to solve the optimization problem. To build your own problem with `argmin`, you make a struct which implements the `ArgminOp` trait. The struct holds the data we're processing. Depending on the optimization algorithm you select, you’ll have to implement some of the trait’s functions. We’re going to use the Gauss-Newton algorithm which requires that we implement `apply()` which calculates the residual vector and `jacobian()` which calculates the Jacobian. The implementations for each are in the previous sections.
During the optimization problem, the solver will update the parameters. The parameters are stored in a flat vector and thus it's useful to make a function that converts the parameter vector into easily-used objects for calculating the residual and Jacobian in the next iteration. Here's how we've done it:
Running the Optimization Problem
Before we run the optimization, we’ll have to initialize the parameters with some reasonable guesses. In the code block below, you'll see that we input four values for \\(f_x, f_y, c_x,\\) and \\(c_y\\).
Next we build the argmin "executor" by constructing a solver and passing in the ArgminOp struct.
After letting the module run for over 100 iterations, the cost function will be quite small. We can see that we converged to the right answer.
Calibration Complete
So there you have it - the theory and the execution of a built-from-scratch calibration module for a single sensor. You can revisit Part 1 and Part 2 to review what we explored prior to demonstrating execution of the model above.
As we noted at the end of Part II, creating a calibration module for sensors is no trivial task. The simplified module and execution we've described in these two posts provide the building blocks for a single camera approach, without optimizations for calibration time, compute resources, or environmental variability. Adding these factors, and expanding calibration routines to multiple sensors, makes the calibration challenge significantly more difficult to achieve.
Lucky for you, you have MetrICal, Tangram Vision's premier multi-modal calibration suite for cameras, IMUs, LiDAR, radar, and chassis registration. Download MetriCal today and get calibrating!
—
Edits:
June 2, 2025: Removed reference to the Tangram Vision SDK. Added link to MetriCal Installation page.



