explainer
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.
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.
| Question | Visual odometry | Visual SLAM |
|---|---|---|
| Main aim | Estimate successive camera motion | Estimate poses and a reusable map together |
| Map use | Can retain local landmarks and recent poses | Maintains a map for joint estimation and reuse |
| Old observations | Often limits optimization to a recent window | Can connect observations across distant times |
| Revisits | A basic VO pipeline need not recognize them | Often 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:
- Calibrate the camera and associate each image with a capture time.
- Detect or track image features and propose matches.
- Reject inconsistent matches and estimate relative camera motion.
- Refine poses and scene points using the image observations.
- 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).
| Landmark | First u₀ (px) | Second u₁ (px) | Parallax d (px) |
|---|---|---|---|
| A | −80 | −120 | 40 |
| B | 20 | 0 | 20 |
| C | 60 | 50 | 10 |
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
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
- Scaramuzza and Fraundorfer, Visual Odometry Part I, 2011: motion estimation, local maps, and camera geometry.
- Fraundorfer and Scaramuzza, Visual Odometry Part II, 2012: matching and estimation failures.
- Cadena and colleagues, Past, Present, and Future of SLAM, 2016: joint estimation and mapping scope.
- Mur-Artal and Tardós, ORB-SLAM2, 2017: a concrete monocular, stereo, and RGB-D system.
- Scaramuzza and Zhang, Visual-Inertial Odometry of Aerial Robots, 2019: visual–inertial state estimation and calibration.
- Qin, Li, and Shen, VINS-Mono, 2018: initialization and inertial excitation.
Continue with SLAM's joint pose-and-map estimation, then add a verified loop constraint to see what revisiting a place changes.