Robust Loss Functions

Standard least squares minimizes the sum of squared residuals . This objective is highly sensitive to outliers: a single point with a large residual can dominate the entire cost function and corrupt the solution. Robust loss functions (M-estimators) reduce the influence of large residuals, making optimization tolerant to outliers in the data.

Problem Setup

In non-linear least squares, calibration-rs minimizes

where is a residual block (a reprojection's 2D pixel error, say) and is the loss applied to its squared norm. Without a robust loss , which gives the standard . This is the Ceres convention: and , so every loss agrees with least squares for small residuals. RobustLoss::rho evaluates it.

Available Loss Functions

RobustLoss has four variants: None (plain squared loss) and three robust loss functions, each parameterized by a scale that controls the transition from quadratic (inlier) to robust (outlier) behavior.

Huber Loss

Properties:

  • Quadratic in for small residuals, linear for large ones
  • Continuous first derivative
  • Influence: bounded — an outlier contributes a constant-magnitude gradient, not a growing one

When to use: The default robust loss. Good general-purpose choice when you expect a moderate number of outliers.

Cauchy Loss

Properties:

  • Grows logarithmically for large residuals (slower than linear)
  • Smooth everywhere
  • Influence: decreases to zero for large residuals, effectively down-weighting far outliers

When to use: When outliers are far from the bulk of the data and should have near-zero influence.

Arctan Loss

Here the scale is in squared-residual units: the transition is near .

Properties:

  • Bounded: as
  • Influence: approaches zero for large residuals (redescending)

When to use: When very strong outlier rejection is needed. More aggressive than Cauchy but can make convergence harder.

Comparison

LossLarge- growthOutlier influenceConvergence
None ()QuadraticUnboundedBest
HuberLinearBounded (constant)Good
CauchyLogarithmicDecreasingModerate
ArctanBoundedApproaching zeroCan be tricky

Choosing the Scale Parameter

The scale sets the boundary between "inlier" and "outlier" behavior:

  • Too small: Treats good data as outliers, reducing effective sample size
  • Too large: Outliers still dominate (approaches standard least squares)
  • Rule of thumb: For Huber and Cauchy, set to the expected residual magnitude for good data points; for reprojection residuals pixels is typical. Arctan's scale is in squared units, so the equivalent is .

Usage in calibration-rs

Robust losses are selected with the RobustLoss enum:

#![allow(unused)]
fn main() {
pub enum RobustLoss {
    None,
    Huber { scale: f64 },
    Cauchy { scale: f64 },
    Arctan { scale: f64 },
}
}

Each non-laser problem type exposes the loss function via its shared solver: SolverConfig group:

#![allow(unused)]
fn main() {
session.update_config(|c| {
    c.solver.robust_loss = RobustLoss::Huber { scale: 2.0 };
})?;
}

Laser-carrying stages (laserline device, rig-handeye-laserline) do not use solver.robust_loss — they track calibration and laser residuals as independent families with their own calib_loss/laser_loss fields instead.

The backend applies the loss function during residual evaluation, modifying both the cost and the Jacobian.

How the Solver Applies a Loss

The Levenberg–Marquardt loop always measures progress with itself. To build each step's linear model, a backend folds the loss into the residual block and its Jacobian:

  • tiny-solver uses the Triggs correction, which matches to second order.
  • factrs uses iterative reweighting: the block and its Jacobian are scaled by .

Both models have the same first-order change as , so both converge to the same minimum; see Solver Backends.

Interaction with RANSAC

RANSAC and robust losses address outliers at different stages:

  • RANSAC (linear initialization): Binary inlier/outlier classification. Used during model fitting to reject gross outliers before any optimization.
  • Robust losses (non-linear refinement): Soft down-weighting. Used during optimization to reduce the influence of moderate outliers that passed RANSAC.

The two approaches are complementary: RANSAC handles gross outliers during initialization, while robust losses handle smaller outliers during refinement.