Skip to content
AI360XpertBeta

Visual Odometry from Frame Motion

Watch the ground slide past frame by frame and add up the steps. Visual odometry turns pixel motion between consecutive frames into a running camera path.

Tracked features step the camera forward frame by frame while small per-step errors accumulate into about 2 m of drift.
Tracked features step the camera forward frame by frame while small per-step errors accumulate into about 2 m of drift.

Why Does This Exist?

GPS dies indoors and wheels slip, so a camera must dead-reckon from what it sees. Visual odometry exists for that incremental job: estimate rotation RR and translation tt between consecutive frames and chain them into a path. It is the front end inside visual SLAM; SLAM adds the map reuse and loop closure that odometry lacks.

This page covers frame-to-frame motion only. Pixel motion basics live in optical flow; the global correction that removes drift belongs to pose graph optimization and structure from motion.

Think of It Like This

Counting steps by watching floor tiles

Walk with eyes on the floor tiles and count how each tile slides past. Big fast slides mean long strides; slow slides mean shuffling. After a hundred steps your count is close but off, because each step estimate carried a small error.

Tiles are tracked corners and strides are RR and tt steps. The analogy stops at scale: tile size is known, while a single camera never learns meters without a baseline or a known object.

How It Actually Works

How one step is solved

Each step detects corners, tracks them into the next frame, and solves for the motion that best explains the 2D shifts. With calibrated stereo, triangulated points carry true scale and perspective-n-point recovers [R∣t][R|t] directly, where RR is the 3×33 \times 3 rotation and tt is the 3×13 \times 1 translation. With one camera, the epipolar constraint x′TEx=0x'^T E x = 0 over matched normalized points xx and x′x' yields the essential matrix E=[t]×RE = [t]_{\times} R, with [t]×[t]_{\times} the skew-symmetric form of tt, and motion recovers up to an unknown scale factor. Keyframes anchor the chain: new frames track against the last keyframe, and a new keyframe spawns when parallax or feature loss passes a threshold. Chaining composes poses as T0:k=T0:k−1Tk−1:kT_{0:k} = T_{0:k-1} T_{k-1:k}, so per-step errors near 1 percent compound into percent-level drift per hundred meters.

Worked drift numbers

At 10 Hz with 0.5 m per step, 200 frames cover 100 m. A 1 percent scale bias adds 0.005 m each step, totaling 200×0.005=1.0200 \times 0.005 = 1.0 m. Independent per-step noise of 0.07 m accumulates as a random walk with standard deviation 0.07×200=0.07×14.14=0.990.07 \times \sqrt{200} = 0.07 \times 14.14 = 0.99 m, about 1.0 m. The path ends roughly 2 m from truth with no loop to pin it: the textbook odometry drift curve.

Code

import math
steps = [0.505] * 200  # 0.5 m of truth plus 1 percent scale biastotal = 0.0for s in steps:    total += s  # 1D chaining stands in for SE(3) compositionprint(total)# -> 100.9999999999998print(round(total - 100.0, 2))# -> 1.0print(round(0.07 * math.sqrt(200), 2))# -> 0.99

Watch Out For

Trusting monocular scale over distance

Monocular odometry recovers direction but not meters, so scale drifts silently with scene depth. The symptom is a path with the right shape at the wrong size. Fix scale from stereo, an IMU, or a known-height object, and never report meters from one camera alone.

Tracking through pure rotation

Distant scenes under rotation give tiny parallax, so translation estimates swing wildly while rotation looks clean. The symptom is a position that jumps while orientation stays smooth. Gate keyframes on translation parallax and freeze the position update when the baseline collapses.

The Quick Version

  • Visual odometry chains frame-to-frame RR and tt into a running camera path.
  • Stereo gives metric scale; one camera recovers motion only up to a scale factor.
  • Keyframes bound cost by tracking new frames against sparse anchors.
  • At 10 Hz and 0.5 m steps, 1 percent bias plus noise ends about 2 m off after 200 frames.
  • Odometry drifts by design; only loop closure removes the accumulated error.