Visual odometry vs SLAM: motion, maps, and metric scale

Compare visual odometry with SLAM, understand what local maps and loop closures add, and use a pinhole-camera inspector to see why monocular images cannot establish metric scale alone.

By 12 min read

What you will learn

  • Distinguish incremental camera motion estimation from joint pose and map estimation.
  • Explain why a visual-odometry system can maintain a local map.
  • Calculate signed image motion with a simple pinhole model.
  • Demonstrate monocular scale ambiguity and identify the extra information supplied by stereo.
  • Recognize failure modes and choose a fair trajectory comparison.

Before you start

Visual odometry estimates how a camera moves from its images. SLAM estimates motion together with a map of the environment. A visual-odometry system can still keep a local map, and a SLAM system can still drift.

The useful questions are what information a system retains, how it uses revisits, and which measurements establish distance in meters. This lesson answers those questions, then uses three synthetic landmarks to expose monocular scale ambiguity.

Visual odometry vs SLAM answers two questions

Visual odometry, or VO, estimates camera motion as images arrive. A camera rigidly attached to a robot provides information about the robot's motion once you account for the camera-to-robot transform. Scaramuzza and Fraundorfer's 2011 tutorial develops this incremental estimation problem.

Simultaneous localization and mapping, or SLAM, jointly estimates the sensor or robot state and an environment model. Cadena and colleagues' SLAM survey uses that joint-estimation definition. The SLAM lesson separates it from localization with a known map and mapping with known poses.

QuestionVisual odometryVisual SLAM
Main aimEstimate successive camera motionEstimate poses and a reusable map together
Map useCan retain local landmarks and recent posesMaintains a map for joint estimation and reuse
Old observationsOften limits optimization to a recent windowCan connect observations across distant times
RevisitsA basic VO pipeline need not recognize themOften supports place recognition and loop constraints

These are practical distinctions, with overlap between implementations. Inspect a system's retained state and update rules; its name alone does not establish accuracy or capabilities.

Follow the image-to-motion pipeline

A typical feature-based pipeline performs several jobs:

  1. Calibrate the camera and associate each image with a capture time.
  2. Detect or track image features and propose matches.
  3. Reject inconsistent matches and estimate relative camera motion.
  4. Refine poses and scene points using the image observations.
  5. Compose relative transforms to update the trajectory.

Direct methods can compare pixel intensities without using the same feature-matching pipeline. Fraundorfer and Scaramuzza's Part II tutorial examines matching, outliers, and refinement. The inspector below supplies correct correspondences and camera geometry, so it skips these difficult estimation steps.

Wheel odometry supplies another motion measurement from wheel travel. ICP aligns geometric point sets once a system has suitable points. ICP alone does not recover missing monocular depths from two ordinary images.

Explain local maps and revisits

A VO system can optimize recent camera poses and landmarks in a sliding window. Those landmarks form a local map that helps estimate motion. Part I of the VO tutorial explicitly describes this use of windowed bundle adjustment.

A persistent map lets a system reuse information from places visited earlier. A valid loop closure adds a constraint between distant parts of the estimated path. The estimator can then revise earlier poses and map geometry.

Joint estimation remains a SLAM problem before a robot revisits a place. A revisit is not guaranteed, and a SLAM implementation need not contain a loop detector. The ORB-SLAM2 paper describes loop closure in its own system while also discussing earlier RGB-D mapping systems that lacked it.

Loop closure also does not supply a meter ruler to a purely monocular system. It can improve consistency while leaving a uniform scale ambiguity. The next example isolates that ambiguity from drift and matching errors.

Define the camera and its pixel coordinates

Use a virtual pinhole image plane in front of the camera. Let +X point right, +Z point forward, and u = 0 mark the principal point. The focal length f uses pixels; scene coordinates X and Z use meters.

For a camera center at horizontal coordinate C, with no rotation, a static landmark projects to:

u = f(X − C) / Z

The first center is C₀ = 0. The second is C₁ = b, where b is positive. Both cameras look along +Z, so the landmark's depth stays Z. The coordinate-frames lesson explains why the camera-relative horizontal coordinate becomes X − C.

u₁ − u₀ = −fb / Z
d = u₀ − u₁ = fb / Z

Moving the camera right makes these image points move left. This formula assumes pure horizontal translation, static points, parallel optical axes, and known correspondences. A general camera motion also includes rotation and requires a fuller projection model.

Calculate the motion of three landmarks

Choose f = 400 px and b = 0.2 m. The scene contains A at (−0.4, 2) m, B at (0.2, 4) m, and C at (1.2, 8) m, written as (X, Z).

LandmarkFirst u₀ (px)Second u₁ (px)Parallax d (px)
A−80−12040
B20020
C605010

For A, u₀ = 400(−0.4)/2 = −80 px. After translation, u₁ = 400(−0.4 − 0.2)/2 = −120 px. Its signed shift is −40 px, and its positive parallax is 40 px.

The farther points have smaller parallax for the same camera translation. X changes where the point appears, but cancels from this horizontal-shift equation. The supplied geometry produces these images; the calculation does not estimate an unknown camera pose.

Scale the scene without changing the images

Multiply every scene coordinate and the camera translation by the same positive scale s. The new projection is:

f(sX − sC) / (sZ) = f(X − C) / Z

With s = 2, A moves to (−0.8, 4) m and the camera translation becomes 0.4 m. Its images still appear at −80 and −120 px. The same equality holds for every landmark and both views.

The images constrain ratios such as b/Z, so these candidate worlds cannot be distinguished from their ideal projections. This is a geometric ambiguity even with exact arithmetic and perfect matches. A monocular estimator needs extra metric information to select a scale. (VO tutorial, monocular geometry)

Inspect monocular and stereo geometry

Pinhole scale inspector

Change the scene, then compare its images

This synthetic example projects three known landmarks. It shows a geometric ambiguity; it runs no feature tracker, motion estimator, or SLAM system.

1
400

One camera captures the first view at 0 s and the second at 0.1 s. Scene scale multiplies every landmark coordinate and the camera translation together. The displayed meter values describe a candidate scene; the images alone do not select that scale.

Horizontal feature coordinates

Monocular horizontal landmark projectionsBlue circles mark the first view; orange squares mark the second. Lines connect the known match for each landmark. A: first -80.000000, second -120.000000 pixels. B: first 20.000000, second 0.000000 pixels. C: first 60.000000, second 50.000000 pixels. The three vertical lanes and marker offsets separate labels only; they are not vertical image coordinates. Horizontal coordinates use a virtual image plane with principal point zero.-1500150Horizontal u (px)ABC
Circle: first image. Square: second image. Each lane contains one known landmark match, with a small vertical offset to keep the markers distinct. Lane height has no geometric meaning. The horizontal axis rescales with focal length and scene settings; use the pixel ticks and numbers when comparing.
Centered horizontal coordinates and signed image shift, in pixels
PointFirstSecondShift
A-80.000-120.000-40.000
B20.0000.000-20.000
C60.00050.000-10.000

Positive camera displacement along +X moves these image points left. Signed shift equals second minus first; the positive parallax readouts equal first minus second. Scene depths are inputs, not monocular estimates. All landmarks stay visible in an ideal pinhole camera with no finite image boundary, noise, rotation, or occlusion.

Camera separation (m)
0.200000
Capture-time difference (s)
0.100000
Scene depth A (m)
2.000000
Parallax A (px)
40.000000
Scene depth B (m)
4.000000
Parallax B (px)
20.000000
Scene depth C (m)
8.000000
Parallax C (px)
10.000000
Metric depth from this pair
Undetermined without a metric reference

Choose Double monocular scene. The candidate depths become 4, 8, and 16 m, and camera translation becomes 0.4 m. Every displayed image coordinate stays unchanged.

Choose Double stereo scene. The scene still doubles, but a calibrated pair keeps its physical baseline at 0.2 m. Parallaxes now halve to 20, 10, and 5 px, and the known-baseline formula Z = fb/d recovers the doubled depths.

In monocular mode, one camera captures two frames at 0 and 0.1 s. In stereo mode, two cameras capture simultaneous views at 0 s; their spatial separation does not represent motion over a time interval. Changing focal length changes pixel coordinates and disparities while preserving the underlying geometry.

The three chart lanes identify landmarks, with vertical marker offsets for readability. They are not vertical image coordinates. Presets restore all controls; reset restores monocular mode, scale 1, and f = 400 px.

Identify what supplies metric scale

Calibrated stereo supplies a measured camera separation. In the parallel, rectified case, a positive disparity gives Z = fb/d. The ORB-SLAM2 paper describes how stereo and RGB-D observations provide depth information for metric estimation.

RGB-D supplies image-associated depth measurements with a sensor-specific calibration and valid operating range. Visual-inertial odometry combines cameras with an IMU and estimates quantities such as velocity and sensor biases. Its camera–IMU geometry and timing require calibration. (Scaramuzza and Zhang, 2019)

An IMU can make metric scale observable under suitable motion, but merely attaching one does not guarantee a well-constrained initialization. The VINS-Mono paper checks for sufficient inertial excitation during initialization. Biases, weak excitation, and timing errors still matter.

A measured object dimension, known camera height under an appropriate model, or another metric sensor can also supply scale information. A learned depth or motion model can encode scale priors from training data. That prior adds information beyond monocular projective geometry and needs validation on the intended environment.

Diagnose failures beyond scale ambiguity

Even a system with metric scale must handle imperfect observations:

  • Missing visual evidence: weak texture, blur, exposure changes, or too little overlap can break tracking.
  • Wrong associations: repeated patterns can produce false matches; moving objects can violate a static-scene model.
  • Weak geometry: very small parallax makes depth sensitive to pixel error. Pure rotation supplies no translational baseline for triangulating new depths.
  • Sensor-model mismatch: lens distortion, rolling shutter, calibration errors, and timing offsets can invalidate the assumed projection.
  • Bad revisits: a false loop constraint can deform an otherwise plausible map.

The Part II tutorial discusses outlier rejection and loop matching. The visual-inertial survey explains camera limitations, IMU biases, and calibration requirements. Extra sensors add constraints and their own error models.

For this inspector's exact stereo model, Z = fb/d implies a local sensitivity magnitude |∂Z/∂d| = fb/d². With f = 400 px and b = 0.2 m, a disparity near 10 px gives sensitivity 0.8 m per pixel. This derivative is a local sensitivity, not a calibrated uncertainty bound.

When comparing VO and SLAM results, state the sensor inputs, test route, tracking losses, and any permitted scale alignment. Use trajectory error metrics to distinguish local drift from global path error. A visually neat trajectory alone cannot establish accuracy.

Reproduce the projections in Python

This standard-library example generates the ideal projections directly. It assumes known matches and never solves a VO or SLAM estimation problem.

points = [(-0.4, 2.0), (0.2, 4.0), (1.2, 8.0)]
focal = 400.0

def views(scale, fixed_baseline=False):
    baseline = 0.2 if fixed_baseline else 0.2 * scale
    first = [focal * (scale * x) / (scale * z) for x, z in points]
    second = [focal * (scale * x - baseline) / (scale * z)
              for x, z in points]
    disparity = [left - right for left, right in zip(first, second)]
    return first, second, disparity

def show(label, values):
    print(label + ": " + ", ".join(f"{v:.6f}" for v in values))

first, second, disparity = views(1.0)
show("First pixels", first)
show("Second pixels", second)
show("Monocular scale 2 pixels", views(2.0)[1])
stereo = views(2.0, fixed_baseline=True)
show("Stereo scale 2 pixels", stereo[1])
show("Stereo depths (m)", [focal * 0.2 / d for d in stereo[2]])
print(f"Depth sensitivity at 10 px: {focal * 0.2 / 10**2:.6f} m/px")

Expected output:

First pixels: -80.000000, 20.000000, 60.000000
Second pixels: -120.000000, 0.000000, 50.000000
Monocular scale 2 pixels: -120.000000, 0.000000, 50.000000
Stereo scale 2 pixels: -100.000000, 10.000000, 55.000000
Stereo depths (m): 4.000000, 8.000000, 16.000000
Depth sensitivity at 10 px: 0.800000 m/px

Try two scale and depth checks

Exercise 1: Can these monocular worlds be distinguished?

Use f = 300 px, a point at X = 0.6 m and Z = 3 m, and camera translation b = 0.15 m. Find both image coordinates. Then multiply X, Z, and b by 3 and repeat.

Check the monocular scale calculation

Solution: u₀ = 300 × 0.6 / 3 = 60 px. u₁ = 300 × (0.6 − 0.15) / 3 = 45 px, so the signed shift is −15 px.

The scaled world has X = 1.8 m, Z = 9 m, and b = 0.45 m. It gives the same 60 and 45 px. The exact images cannot choose between these metric scales.

Exercise 2: How does a disparity error change stereo depth?

A rectified stereo pair has f = 400 px and a known baseline of 0.2 m. Calculate depth for disparities of 10 and 11 px. Compare the exact difference with the local sensitivity estimate for a +1 px change at 10 px.

Check the stereo depth calculation

Solution: The first depth is 80/10 = 8 m. The second is 80/11 = 7.272727 m, a change of −0.727273 m.

At 10 px, ∂Z/∂d = −80/100 = −0.8 m/px, so the linear estimate gives −0.8 m. The difference comes from using a local linear approximation for a finite change. This calculation does not assign a probability to the measurement error.

Sources and further study

Continue with SLAM's joint pose-and-map estimation, then add a verified loop constraint to see what revisiting a place changes.