C.W.K.
Stream
Lesson 03 of 05 · published

The Bounded Focal Sweep

~12 min · focal, bounded-sweep, ill-posed, prior

Level 0Blank Page
0 XP0/35 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"Give the solver total freedom over focal length and it will explain a normal face with a fisheye lens. Freedom isn't always a gift."

Focal and Distance Look the Same to One Face

There is a genuine ambiguity buried in a single portrait: a wide lens up close and a long lens far away produce almost the same image of a face. Move the camera back and zoom in and the face barely changes — this is the same trade-off filmmakers exploit in the dolly-zoom shot. To the geometry, focal length and camera distance are tangled together, and one face gives the solver only a weak grip on which is which. It's an ill-conditioned parameter: the data barely pins it down.

Let It Roam and It Lies

If you hand solvePnP an unbounded focal search, it does something technically correct and practically useless. It finds some focal that drives reprojection error to near zero — often an absurd, extreme wide-angle value — and pairs it with a distance that makes the numbers work. The reprojection error looks great. The recovered box converges like a fisheye, the head reads as violently turned, and the answer is nonsense. The math was satisfied; the perspective is a lie. A low error on a weakly-constrained parameter is not the same as a correct fit.

The Bounded Sweep

Loomis fixes this the honest way: it bounds the search. Focal length is swept only across a plausible portrait band — roughly a normal-lens range, not fisheye and not extreme telephoto — and the fit with the lowest error within that band wins. This is a prior in the plain-English sense: portraits are overwhelmingly shot with normal-ish lenses, so refusing to consider a fisheye explanation is not cheating, it's using real knowledge the single face can't supply. The bound is what keeps the recovered box's convergence sane.

The Escape Hatch

Priors should be overridable, and this one is. When a photo genuinely was shot wide — an arm's-length selfie, a real wide-angle lens — a human can set the focal directly and skip the sweep entirely. That manual override is the deliberate escape hatch for the one parameter geometry can't confidently recover from a face alone. It's a small, honest admission: the engine is deterministic where it can be, and hands the wheel to a human exactly where the data runs out.

Code

Bound the sweep; override when a human knows the lens·python
# Focal is only weakly constrained by ONE face, so DON'T optimize it freely.
# Sweep a sane portrait band and keep the lowest-error fit inside it.
FOCAL_MIN, FOCAL_MAX = focal_equiv(35), focal_equiv(135)   # normal-portrait band

best = None
for focal in np.linspace(FOCAL_MIN, FOCAL_MAX, N):
    R, t, err = solve_pose(landmarks, canonical_head, focal)
    if best is None or err < best.err:
        best = Fit(R, t, focal, err)

# The escape hatch: a human who knows the real lens overrides the whole sweep.
if focal_override is not None:
    best = solve_pose(landmarks, canonical_head, focal_override)

# An UNBOUNDED search would 'win' with a fisheye focal + near-zero error
# and hand you a violently over-converged box. The bound is the honesty.

External links

Exercise

Find two portraits of the same person: one taken up close (a phone selfie, nose slightly enlarged) and one taken from farther with zoom (features flattened). The face's apparent shape changed even though the person didn't. Explain how that single-photo ambiguity is exactly what forces Loomis to bound the focal sweep instead of solving focal freely.
Hint
Because a near-wide shot and a far-long shot can produce nearly the same face image, one photo can't decide between them — the focal/distance pair is under-constrained. A free search would pick an extreme to minimize error; bounding it to normal portrait lenses encodes the overwhelmingly likely truth and refuses the fisheye explanation the single face can't rule out.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.