Foundations
Depth of Field
The range of object distances that a focused lens images with blur no larger than an acceptable circle of confusion, its exact near and far limits under the thin-lens model, the hyperfocal distance, Levoy's approximations and how depth of field scales with f-number, distance and focal length.
intermediate
A lens focuses one distance exactly. Points nearer or farther are imaged as small blur discs, and as long as those discs stay below some acceptable size the eye, or the next stage of a vision pipeline, treats them as sharp. The range of object distances that passes this test is the depth of field (DOF). It is bounded by a near limit and a far limit, it is not centred on the focus distance, and it grows with the f-number, grows roughly with the square of the focus distance and shrinks roughly with the square of the focal length. Focused far enough away, at the hyperfocal distance, a lens keeps everything from half that distance to infinity acceptably sharp.
Depth of field matters to computer vision because it decides which parts of a scene a fixed camera can measure at full resolution, how much light an inspection set-up has to add to keep a deep part sharp, and how much defocus a depth-from-focus method has to work with. This article states the definition and its one free parameter, derives the exact limits under the thin lens model, compares them with the approximations in Marc Levoy’s Stanford CS 178 lecture slides that Torralba, Isola and Freeman’s Foundations of Computer Vision (hereafter visionbook) reproduces, and checks both with an exact computation and a rendered row of bar targets at known depths.
Definition
Put the sensor where a point at distance in front of the lens comes to focus. A point at another distance is imaged as a disc, the circle of confusion, whose diameter the thin lens model derives and image formation uses to simulate defocus. Choose a largest acceptable diameter on the sensor. The depth of field is the set of distances with ; it runs from the near limit to the far limit , and its length is . Levoy (slide 55) splits it into a front part and a back part .
The definition has one free parameter, , and every depth-of-field number depends on it. Levoy (slide 52) says that depends on the sensing and reproduction media, the viewing distance and human vision, and gives typical values: 0.02 mm on the negative for prints from 35 mm film, about 6 µm, one pixel, for a high-end SLR, and larger when the image is downsized for the web or the lens is poor. Visionbook (§6.3.1) defines the depth of field as the region around the plane of focus whose blur at the sensor stays below “some tolerance”.
Depth of field is measured in object space. Its image-side counterpart, the range of sensor positions over which a point stays acceptably sharp, is the depth of focus; Levoy’s slide 53 labels both on one diagram.
Intuition
The cone of light from a point converges behind the lens to the point’s image and diverges again after it. A sensor placed slightly before or after that apex cuts the cone in a disc. How fast the disc grows as the object moves away from the focus distance depends on how wide the cone is, which is set by the aperture: a narrow cone (large f-number) stays thin over a long stretch, so a wider range of object distances lands inside the tolerance. That is why stopping down deepens the depth of field, and why it costs light, as exposure describes.
The range is lopsided. Image distance changes quickly with object distance for near objects and slowly for far ones (the thin lens model shows that depth is compressed by the square of the magnification), so a step towards the camera moves the image farther from the sensor than an equal step away. The blur therefore grows faster in front of the focus plane than behind it, and more of the sharp range lies behind. Levoy (slide 53) puts it as “DoF is asymmetrical around the in-focus object plane”.
Moving the focus distance out has a dramatic effect. Far objects all image close to the focal plane, so once the focus is far enough away even a point at infinity falls inside the tolerance. The back limit then jumps to infinity: that focus distance is the hyperfocal distance.
Formal Definition
Conventions
Distances are in millimetres and positive when real, as in the thin lens model: the object distance in front of the lens, the image distance behind it. The focus distance is , Levoy’s symbol (the thin lens model writes for it); is the focal length, the aperture diameter and the f-number (visionbook writes for the diameter). is a blur diameter on the sensor and the acceptable one. Visionbook calls the depth of field ; Levoy calls it .
Exact limits
With the sensor at the image distance of , the thin lens model gives the blur diameter of a point at as
Setting on each side of and solving the resulting linear equations gives (our derivation; the example checks it exactly and by root finding)
The far limit is finite only while . As the blur tends to , and it equals when
the exact hyperfocal distance in this model (our derivation). For every point beyond is sharp. At the near limit is , so focusing at the hyperfocal distance makes everything from to infinity acceptably sharp.
Levoy’s formulas
Levoy (slides 53–55) derives the limits from the object-space conjugate of the circle of confusion: a disc of diameter on the sensor corresponds to a disc of diameter in the focus plane, where is the transverse magnification, and he approximates it as . Visionbook (§6.3.1), which follows Levoy’s derivation, states the condition for this step, . Similar triangles then give
and their sum (slide 56)
where the term “can be ignored when conjugate of circle of confusion is small relative to the aperture” (slide 56). Visionbook prints the same exact and approximate forms of ; its sentence before the approximation names the dropped term , a typo for as on Levoy’s slide. Levoy (slide 67) defines the hyperfocal distance as the focus distance at which becomes infinite, , and shows that his then equals .
The two sets of formulas differ in one place (our derivation). In the thin-lens model the magnification at is , so the exact conjugate is , and the exact limits are Levoy’s with in place of in the denominators:
Levoy’s hyperfocal distance is therefore short of the exact one by exactly , and his formulas are the exact ones in the limit . The boxed approximation drops a second term: its ratio to Levoy’s own is , writing (our algebra from slide 56), so it underestimates the depth of field more and more as approaches the hyperfocal distance.
Properties
Scaling with f-number, distance and focal length
The approximation summarizes the trade-offs. Levoy’s slides 65, 66 and 68 state them: depth of field is linear in the f-number, quadratic in the subject distance and inverse quadratic in the focal length. Visionbook (Fig. 6.12) shows the first on photographs of a ruler taken at f/2, f/4 and f/8 from the same camera position, where the region of sharp focus doubles from each f-number to the next. All three statements hold only while is well below the hyperfocal distance (slide 56’s condition). Near it the exact depth grows much faster than the approximation, and beyond it the depth is infinite.
Asymmetry
Since whenever the far limit is finite (the denominators in the exact limits differ only in the sign of ), more depth lies behind the focus plane than in front. For a distant focus the back part becomes much larger than the front; at the hyperfocal distance the front is and the back is infinite. Close up, with , the two parts are nearly equal.
The hyperfocal distance
Focusing at maximizes the sharp range for a given aperture and : everything from to infinity. Levoy (slide 67) works an example from a photograph taken with a 27 mm lens at f/6.3, with set to one pixel of an HD projector, 2.5 µm × 2816/1920 on the sensor, and gets m: had he focused at 32 m, everything from 16 m to infinity would have been sharp on the projector. (Our arithmetic: µm and m; the exact is 27 mm longer.)
Sensor size
At the same field of view and pixel count, a smaller sensor has a shorter focal length and smaller pixels, so and shrink by the same factor. Levoy (slide 69) concludes from the approximation that depth of field then grows linearly as the sensor shrinks, and that this is why amateur cinematographers prefer the larger chips of SLRs, which give more control over depth of field; focal length and field of view relates the focal length to the format. In our reading of the same formula, a phone camera’s deep depth of field follows from its short focal length, which is why computational photography synthesizes shallow depth of field instead.
Dolly zoom and background blur
Multiplying and by the same factor leaves , and hence the approximate depth of field, unchanged. Levoy (slide 71) uses this: zooming in and stepping back keeps the subject the same size and the depth of field the same, “but background gets blurrier”. Slide 72 adds that both lenses then have the same depth of field on the subject, while the telephoto sees and enlarges a smaller part of the background.
The choice of C
Because is proportional to in the approximation, a factor-of-three change in the criterion, say from Levoy’s 6 µm pixel to his 0.02 mm film value, changes the depth of field by about a factor of three. Levoy’s slides 57–59 show this on three photographs: the same shot has one depth of field for the camera’s pixels and a larger effective one for a 1024-pixel projector. A depth of field quoted without its cannot be compared with another.
Depth of focus
On the image side, the blur at sensor distance for an image at (thin lens model) stays below while , so for distant objects () the depth of focus is about around the image plane (our derivation). With and µm that is about ±50 µm, which sets how precisely a sensor or a focus mechanism has to be positioned.
Diffraction
Stopping down extends depth of field in the geometric model without limit, but diffraction blur grows with the f-number. Image formation gives the arithmetic (an Airy radius of , 5.4 µm at f/8 and 10.7 µm at f/16 for green light), and the point spread function combines diffraction with the defocus disc. In our reading, once the diffraction blur approaches , a smaller aperture no longer makes anything sharper. Levoy’s rule of thumb (Optics II, slide 40) is to avoid f-numbers above f/13 on a full-frame camera.
Not a convolution
A defocused image is not a sharp image blurred with one kernel. Each depth has its own disc, and at occlusion boundaries the light reaching a pixel comes partly from the foreground and partly from what it hides. Levoy (slides 76–77) notes that a wide aperture can see past a small occluder such as a chain-link fence: for a pixel focused on the subject some rays strike the occluder and some pass beside it, so the occluder lowers the subject’s contrast without blocking it. Image deblurring describes the defocus PSF and its variation with depth; the example below renders each depth as a separate layer and so leaves occlusion out.
Bokeh
Out-of-focus highlights take the shape of the aperture, because the defocus disc is a scaled copy of the aperture (thin lens model). Levoy (slide 73) uses “bokeh” for the appearance of small out-of-focus features in a photograph with shallow depth of field, determined by the boundary of the aperture.
Examples
Exact limits against the approximations, and a rendered depth ramp
The script has two parts. Part (a) computes, for a 50 mm lens with mm (Levoy’s film value) at f/2, f/4, f/8 and f/16, the exact near and far limits at focus distances of 1, 3 and 10 m and at 0.5, 0.9 and 0.99 of the exact hyperfocal distance . It checks the closed forms against SciPy’s brentq root finder applied to , checks that Levoy’s slide-56 form equals his , and reports the relative errors of his , and approximate against the exact values. It then focuses at the exact and at Levoy’s .
Part (b) renders a receding row of bar targets. The lens is focused at m, the pixel pitch is 2.5 µm (so is 8 pixels), and 601 bar patches are placed at depths from 1500 to 2700 mm in 2 mm steps. Each patch is a periodic row of bars, 6 pixels white and 6 black, blurred by the uniform disc of its own exact circle of confusion. Because the bars vary only along , convolving the patch with the disc is the same as convolving one row with the disc’s projection (its chord length), which the code integrates exactly over each pixel. Each patch is blurred on its own: the rendering is layered, with no occlusion between depths, which is the simplification that Levoy’s “not a convolution” slides warn about. There is no noise and no randomness.
A patch counts as sharp when its Michelson contrast, , is at least the contrast of the same bars blurred by a disc of diameter exactly . The criterion and the blur therefore share one definition. Because a disc’s transfer function changes sign (point spread function), strongly defocused bars can regain some contrast, so the script checks on a 0.01-pixel grid of disc diameters up to 90 pixels that contrast is at least exactly when (check C3). The rendered near and far limits are the nearest and farthest sharp patches.
The checks and hypotheses, each with its bar, are:
- C0: closed form against
brentq, relative difference ≤ ; - C1: Levoy’s slide-56 equals his within ;
- H1a: wherever , the approximate is within 6% of exact;
- H1b: at its error grows and reaches at least 50% at ;
- H4a: the back depth exceeds the front depth in every finite row;
- H2a: at the exact , and , within ;
- H2b: at Levoy’s the far limit is finite and equals ;
- C2 (data checks): every disc kernel sums to 1, the bar row has mean 0.5, and the unblurred contrast is 1, within ;
- C3: contrast ≥ exactly when ;
- H3a: the rendered limits equal the exact limits rounded inwards to the 2 mm grid, and the sharp patches are contiguous;
- H3b: the rendered range doubles from f/2 to f/4 and from f/4 to f/8, within ±0.05;
- H4b: the rendered back depth exceeds the front depth.
import os
os.environ["OPENBLAS_NUM_THREADS"] = os.environ["OMP_NUM_THREADS"] = "1"
import numpy as np
from scipy.optimize import brentq
# Units: mm. Thin lens, distances positive when real. The sensor is focused for the
# object distance U; a point at distance z then blurs into a disc of diameter c(z).
f, C = 50.0, 0.02 # focal length, acceptable CoC diameter
coc = lambda z, U, N: f**2 * abs(z - U) / (N * z * (U - f))
def limits(U, N):
"""Exact near and far limits, where c(z) = C (far = inf beyond the hyperfocal)."""
a = N * C * (U - f)
far = f**2 * U / (f**2 - a) if f**2 > a else np.inf
return f**2 * U / (f**2 + a), far
def levoy(U, N):
"""Levoy's D1, D2 (slide 55), his D_tot (slide 56) and its approximation."""
k = N * C * U**2
D1 = k / (f**2 + N * C * U)
D2 = k / (f**2 - N * C * U) if f**2 > N * C * U else np.nan
D_full = 2 * k * f**2 / (f**4 - (N * C * U)**2)
return D1, D2, D_full, 2 * k / f**2
held = lambda ok: "held" if ok else "failed"
print("(a) f = 50 mm, C = 0.02 mm; relative errors are Levoy / exact - 1")
print("N U (mm) U/H near (mm) far (mm) D_tot exact D_tot approx "
"err D_tot err D1 err D2 root diff")
root_max = alg_max = 0.0
h1a, h1b_rows, h4a = [], {}, []
for N in (2, 4, 8, 16):
H = f**2 / (N * C) + f # exact hyperfocal distance
for q, U in ((None, 1000.0), (None, 3000.0), (None, 10000.0),
(0.5, 0.5 * H), (0.9, 0.9 * H), (0.99, 0.99 * H)):
near, far = limits(U, N)
g = lambda z: coc(z, U, N) - C
rn = brentq(g, f + 1e-6, U, xtol=1e-300, rtol=4 * np.finfo(float).eps, maxiter=500)
D1, D2, D_full, D_ap = levoy(U, N)
if np.isinf(far):
print(f"{N:<3} {U:<12.3f} {U / H:<7.4f} {near:<12.4f} inf inf "
f"{D_ap:<13.4f} -")
root_max = max(root_max, abs(rn / near - 1))
continue
rf = brentq(g, U, 1e12, xtol=1e-300, rtol=4 * np.finfo(float).eps, maxiter=500)
root_max = max(root_max, abs(rn / near - 1), abs(rf / far - 1))
alg_max = max(alg_max, abs(D_full / (D1 + D2) - 1))
e_tot, e1, e2 = D_ap / (far - near) - 1, D1 / (U - near) - 1, D2 / (far - U) - 1
print(f"{N:<3} {U:<12.3f} {U / H:<7.4f} {near:<12.4f} {far:<14.4f} {far - near:<13.4f} "
f"{D_ap:<13.4f} {100 * e_tot:+9.4f}% {100 * e1:+8.4f}% {100 * e2:+8.4f}% {abs(rf / far - 1):.1e}")
if U / H <= 0.2:
h1a.append(abs(e_tot))
if q is not None:
h1b_rows.setdefault(N, []).append(abs(e_tot))
h4a.append(far - U > U - near)
print(f"C0 closed form vs brentq, max rel diff {root_max:.1e} <= 1e-9: {held(root_max <= 1e-9)}")
print(f"C1 Levoy slide 56 D_tot = D1 + D2, max rel diff {alg_max:.1e} <= 1e-12: {held(alg_max <= 1e-12)}")
print(f"H1a U/H <= 0.2: max |err D_tot| {100 * max(h1a):.4f}% <= 6% over {len(h1a)} rows: {held(max(h1a) <= 0.06)}")
ok = all(len(r) == 3 and r[0] < r[1] < r[2] and r[1] >= 0.5 for r in h1b_rows.values())
print("H1b |err D_tot| at q = 0.5, 0.9, 0.99: " + "; ".join(
f"N={N} ({len(r)} rows) " + ", ".join(f"{100 * e:.4f}%" for e in r) for N, r in h1b_rows.items())
+ f": increasing and >= 50% at 0.9: {held(ok)}")
print(f"H4a back depth > front depth in all {len(h4a)} finite rows: {held(all(h4a))}")
print("\nHyperfocal focus")
h2a = h2b = True
for N in (2, 4, 8, 16):
HL = f**2 / (N * C); H = HL + f
c_inf = f**2 / (N * (H - f)) # blur of a point at infinity
near_H = limits(H, N)[0]
nL, fL = limits(HL, N)
rf = brentq(lambda z: coc(z, HL, N) - C, HL, 1e12, xtol=1e-300, rtol=4 * np.finfo(float).eps, maxiter=500)
e_a = max(abs(c_inf / C - 1), abs(near_H / (H / 2) - 1))
e_b = max(abs(fL / (HL**2 / f) - 1), abs(rf / fL - 1))
h2a &= e_a <= 1e-12; h2b &= np.isfinite(fL) and e_b <= 1e-9
print(f"N={N:<3} exact H {H:9.1f}: c(inf)/C {c_inf / C:.12f}, near/(H/2) {near_H / (H / 2):.12f} | "
f"Levoy H {HL:9.1f}: far {fL:14.3f} = H^2/f {HL**2 / f:14.3f} (rel {e_b:.1e}), "
f"near {nL:.4f} vs H/2 {HL / 2:.4f}")
print(f"H2a far limit infinite and near = H/2 at the exact H (<= 1e-12): {held(h2a)}")
print(f"H2b far limit finite and = H_Levoy^2/f at Levoy's H (<= 1e-9): {held(h2b)}")
# (b) Rendered depth ramp: bar patches at known depths, each blurred by its own disc
U, pitch, W, P = 2000.0, 0.0025, 192, 12 # focus (mm), pixel pitch (mm), row length, bar period (px)
row = (np.arange(W) % P < P // 2).astype(float) # 6 px white, 6 px black
def disc_kernel(c):
"""Uniform disc of diameter c px projected onto x (bars vary only in x) and
integrated exactly over each pixel; circular, centred at index 0."""
x = np.arange(W) - W // 2
r = c / 2
if r <= 0:
k = (x == 0).astype(float)
else:
def F(t): # integral of the chord length
t = np.clip(t, -r, r)
return r * r * (np.arcsin(t / r) + np.pi / 2) + t * np.sqrt(r * r - t * t)
k = (F(x + 0.5) - F(x - 0.5)) / (np.pi * r * r)
return np.roll(k, -(W // 2))
def contrast(c):
b = np.real(np.fft.ifft(np.fft.fft(row) * np.fft.fft(disc_kernel(c))))
return (b.max() - b.min()) / (b.max() + b.min())
T = contrast(C / pitch) # the C-sized disc's own contrast
cs = np.round(np.arange(0, 9001) * 0.01, 2)
con = np.array([contrast(c) for c in cs])
ksum = max(abs(disc_kernel(c).sum() - 1) for c in (0.0, 0.5, 8.0, 85.5))
print(f"\n(b) U = {U:.0f} mm, pixel {pitch * 1e3:.1f} um, C = {C / pitch:.0f} px, bars {P // 2}/{P // 2} px")
print(f"C2 kernel sums |sum-1| max {ksum:.1e} <= 1e-12, row mean {row.mean()}, contrast(0) {contrast(0.0)}: "
f"{held(ksum <= 1e-12 and row.mean() == 0.5 and abs(contrast(0.0) - 1) <= 1e-12)}")
lo, hi = con[cs <= 8].min(), con[cs > 8].max()
print(f"C3 threshold T {T:.6f}; min contrast c <= 8 px {lo:.6f}; max contrast 8 < c <= 90 px {hi:.6f}: "
f"{held(lo >= T and hi < T)}")
zs = np.arange(1500, 2701, 2)
print("N near grid (exact) far grid (exact) range front back contiguous")
rng = {}
h3a = h4b = True
for N in (2, 4, 8):
sharp = np.array([contrast(coc(z, U, N) / pitch) >= T for z in zs])
idx = np.flatnonzero(sharp)
zn, zf = zs[idx[0]], zs[idx[-1]]
en, ef = limits(U, N)
gn, gf = zs[zs >= en].min(), zs[zs <= ef].max()
contig = idx[-1] - idx[0] + 1 == len(idx)
rng[N] = zf - zn
h3a &= contig and zn == gn and zf == gf
h4b &= (zf - U) > (U - zn)
print(f"{N:<3} {zn} ({en:.4f}) {zf} ({ef:.4f}) {zf - zn:<6} {U - zn:<6.0f} {zf - U:<5.0f} {contig}")
print(f"H3a rendered limits = analytic grid limits (within one 2 mm step), contiguous: {held(h3a)}")
r42, r84 = rng[4] / rng[2], rng[8] / rng[4]
print(f"H3b range ratios f/4:f/2 {r42:.4f}, f/8:f/4 {r84:.4f}, within 2 +- 0.05: "
f"{held(abs(r42 - 2) <= 0.05 and abs(r84 - 2) <= 0.05)}")
print(f"H4b rendered back > front: {held(h4b)}")
Output (NumPy 2.3.5, SciPy 1.16.3; the script runs in under a second):
(a) f = 50 mm, C = 0.02 mm; relative errors are Levoy / exact - 1
N U (mm) U/H near (mm) far (mm) D_tot exact D_tot approx err D_tot err D1 err D2 root diff
2 1000.000 0.0160 985.0276 1015.4346 30.4070 32.0000 +5.2388% +5.1803% +5.3487% 0.0e+00
2 3000.000 0.0480 2864.7823 3148.6146 283.8323 288.0000 +1.4684% +1.6173% +1.7804% 0.0e+00
2 10000.000 0.1599 8626.6391 11893.4348 3266.7958 3200.0000 -2.0447% +0.4332% +0.5982% 0.0e+00
2 31275.000 0.5000 20855.5615 62500.0000 41644.4385 31300.0200 -24.8399% +0.1067% +0.3205% 2.2e-16
2 56295.000 0.9000 29630.1950 562500.0000 532869.8050 101412.0648 -80.9687% +0.0468% +0.8954% 1.0e-15
2 61924.500 0.9900 31117.9643 6187500.0000 6156382.0357 122708.5984 -98.0068% +0.0406% +8.7759% 6.9e-15
4 1000.000 0.0319 970.4969 1031.3531 60.8562 64.0000 +5.1659% +5.1000% +5.4371% 2.2e-16
4 3000.000 0.0958 2741.2281 3312.7208 571.4928 576.0000 +0.7887% +1.5465% +1.8749% 1.1e-16
4 10000.000 0.3195 7584.9515 14671.3615 7086.4100 6400.0000 -9.6863% +0.3807% +0.7390% 0.0e+00
4 15650.000 0.5000 10438.9007 31250.0000 20811.0993 15675.0400 -24.6794% +0.2136% +0.6421% 0.0e+00
4 28170.000 0.9000 14827.5644 281250.0000 266422.4356 50787.1296 -80.9374% +0.0935% +1.8041% 1.3e-15
4 30987.000 0.9900 15571.4820 3093750.0000 3078178.5180 61452.4268 -98.0036% +0.0812% +19.2038% 6.0e-15
8 1000.000 0.0638 942.6848 1064.7359 122.0512 128.0000 +4.8740% +4.9466% +5.6230% 2.2e-16
8 3000.000 0.1914 2523.5532 3698.2249 1174.6717 1152.0000 -1.9300% +1.4219% +2.0977% 0.0e+00
8 10000.000 0.6380 6109.4819 27533.0396 21423.5577 12800.0000 -40.2527% +0.3064% +1.3959% 0.0e+00
8 7837.500 0.5000 5230.5793 15625.0000 10394.4207 7862.5800 -24.3577% +0.4276% +1.2882% 2.2e-16
8 14107.500 0.9000 7426.2507 140625.0000 133198.7493 25474.7592 -80.8746% +0.1869% +3.6623% 6.7e-16
8 15518.250 0.9900 7798.2410 1546875.0000 1539076.7590 30824.4586 -97.9972% +0.1622% +47.3131% 5.3e-15
16 1000.000 0.1272 891.5835 1138.4335 246.8501 256.0000 +3.7067% +4.6659% +6.0357% 0.0e+00
16 3000.000 0.3816 2177.7003 4820.0514 2642.3511 2304.0000 -12.8049% +1.2246% +2.7515% 0.0e+00
16 10000.000 1.2719 4398.3110 inf inf 25600.0000 -
16 3931.250 0.5000 2626.4364 7812.5000 5186.0636 3956.4100 -23.7107% +0.8570% +2.5931% 1.1e-16
16 7076.250 0.9000 3725.5970 70312.5000 66586.9030 12818.7684 -80.7488% +0.3734% +7.5511% 0.0e+00
16 7783.875 0.9900 3911.6208 773437.5000 769525.8792 15510.7098 -97.9844% +0.3238% +176.4483% 7.8e-16
C0 closed form vs brentq, max rel diff 6.9e-15 <= 1e-9: held
C1 Levoy slide 56 D_tot = D1 + D2, max rel diff 8.4e-15 <= 1e-12: held
H1a U/H <= 0.2: max |err D_tot| 5.2388% <= 6% over 8 rows: held
H1b |err D_tot| at q = 0.5, 0.9, 0.99: N=2 (3 rows) 24.8399%, 80.9687%, 98.0068%; N=4 (3 rows) 24.6794%, 80.9374%, 98.0036%; N=8 (3 rows) 24.3577%, 80.8746%, 97.9972%; N=16 (3 rows) 23.7107%, 80.7488%, 97.9844%: increasing and >= 50% at 0.9: held
H4a back depth > front depth in all 23 finite rows: held
Hyperfocal focus
N=2 exact H 62550.0: c(inf)/C 1.000000000000, near/(H/2) 1.000000000000 | Levoy H 62500.0: far 78125000.000 = H^2/f 78125000.000 (rel 3.0e-14), near 31262.5050 vs H/2 31250.0000
N=4 exact H 31300.0: c(inf)/C 1.000000000000, near/(H/2) 1.000000000000 | Levoy H 31250.0: far 19531250.000 = H^2/f 19531250.000 (rel 4.9e-14), near 15637.5100 vs H/2 15625.0000
N=8 exact H 15675.0: c(inf)/C 1.000000000000, near/(H/2) 1.000000000000 | Levoy H 15625.0: far 4882812.500 = H^2/f 4882812.500 (rel 2.9e-14), near 7825.0200 vs H/2 7812.5000
N=16 exact H 7862.5: c(inf)/C 1.000000000000, near/(H/2) 1.000000000000 | Levoy H 7812.5: far 1220703.125 = H^2/f 1220703.125 (rel 1.5e-14), near 3918.7901 vs H/2 3906.2500
H2a far limit infinite and near = H/2 at the exact H (<= 1e-12): held
H2b far limit finite and = H_Levoy^2/f at Levoy's H (<= 1e-9): held
(b) U = 2000 mm, pixel 2.5 um, C = 8 px, bars 6/6 px
C2 kernel sums |sum-1| max 0.0e+00 <= 1e-12, row mean 0.5, contrast(0) 1.0000000000000002: held
C3 threshold T 0.688357; min contrast c <= 8 px 0.688357; max contrast 8 < c <= 90 px 0.686907: held
N near grid (exact) far grid (exact) range front back contiguous
2 1940 (1939.4880) 2064 (2064.4096) 124 60 64 True
4 1884 (1882.5301) 2132 (2133.1058) 248 116 132 True
8 1780 (1778.0939) 2284 (2285.1920) 504 220 284 True
H3a rendered limits = analytic grid limits (within one 2 mm step), contiguous: held
H3b range ratios f/4:f/2 2.0000, f/8:f/4 2.0323, within 2 +- 0.05: held
H4b rendered back > front: held
Every check and hypothesis held in this run. The root-finding check C0 held: the closed-form limits match brentq’s roots to , so they are the exact solutions of . Check C1 held: Levoy’s slide-56 form is his to .
Hypothesis H1a held. In the eight rows with the largest error of the approximate is +5.2388%, at f/2 and 1 m. The 1 m rows are where the approximation does worst at small : +5.2388%, +5.1659%, +4.8740% and +3.7067% at f/2 to f/16, with Levoy’s also about 5% long in each of these rows. In our reading this is mainly the step: Levoy’s conjugate exceeds the exact by the factor , which is 5.26% at 1 m (our arithmetic). The dropped term pulls the other way, by the factor , which at 1 m is 0.03% at f/2 and 1.6% at f/16 with the printed (our arithmetic), so the 1 m error falls as the f-number grows. At 10 m and f/2 the signs split, with and long by +0.4332% and +0.5982% but the approximate total short by 2.0447%; there the dropped term’s factor is , about 2.6% short (our arithmetic), and it outweighs the conjugate error.
Hypothesis H1b held: the error of the approximation grows towards the hyperfocal distance, from about 24% at through about 81% at to about 98% at , three rows per f-number. The percentages are nearly the same at every f-number for a given fraction of , which follows from the factor when (our reading). Levoy’s is within 8% of exact in every row short of , but at it is 8.7759% long at f/2 and 176.4483% long at f/16. In our reading this is because his diverges at his , which lies short of the exact ; at f/16 the printed hyperfocal distances are 7812.5 and 7862.5 mm, so (7783.875 mm) is within 30 mm of . One row, f/16 at 10 m (), is beyond the hyperfocal distance: the exact depth of field is infinite, while the approximation gives a finite 25.6 m.
Hypothesis H4a held: the back depth exceeds the front in all 23 rows with a finite far limit.
Both hyperfocal hypotheses held. H2a: at the exact the blur of a point at infinity is exactly and the near limit is exactly , both printed as 1.000000000000. H2b: focused at Levoy’s , the far limit is finite and equals , from 78,125 m at f/2 down to 1,220.7 m at f/16. For practical purposes that is still infinity, since is a large multiple of . The printed near limit at is slightly beyond : 31262.5050 mm against 31250 mm at f/2 (0.04% farther), and 3918.7901 mm against 3906.25 mm at f/16 (0.32%).
In part (b), the data checks C2 held. The unblurred contrast prints as 1.0000000000000002, within the tolerance; the last digit is floating-point round-off in the FFT. The validity check C3 held: the threshold contrast of the bars under the 8-pixel disc is 0.688357, every smaller disc gives at least that, and every larger disc up to 90 pixels gives at most 0.686907. The largest disc in the render, at f/2 and 1500 mm, has a diameter of 0.2137 mm, 85.5 pixels, by the blur formula above (our arithmetic), so the checked grid covers every patch. Contrast is thus a faithful stand-in for blur diameter on these bars.
Hypothesis H3a held. At each f-number the rendered limits are the exact limits rounded inwards to the 2 mm grid (1940 and 2064 mm at f/2, against 1939.4880 and 2064.4096 mm), and the sharp patches form one contiguous run. Hypothesis H3b held: the rendered range is 124, 248 and 504 mm, so the ratios are 2.0000 and 2.0323. The exact ranges from the printed limits are 124.9216, 250.5757 and 507.0981 mm, each a little more than double the previous one, which the 2 mm grid rounds. This is the doubling that visionbook’s ruler photographs show, here on a scene with known depths. Hypothesis H4b held: 60 mm in front against 64 mm behind at f/2, 116 against 132 at f/4 and 220 against 284 at f/8, so the asymmetry grows as the range gets longer.
Process note. The example illustrates exact relations rather than testing an open question. The PLAN records that the bars of H1a, H1b and H3b were set after a planning script had printed the values they bound: “All bars written after reachable.py printed the values: example presented as an illustration.” It listed nine departures from the batch plan’s entry for this example, before the pilot:
- mm, Levoy’s film value, where the batch plan asked for “a stated C”;
- focus distances of 1, 3 and 10 m and 0.5, 0.9 and 0.99 of ;
- and each compared with the exact values, and the added check C1;
- numeric bars for “a few percent”, “diverges” and “doubles”;
- the near limit at Levoy’s printed against ;
- the disc blur computed exactly through its projection on a periodic, noise-free row;
- the added checks C2 and C3;
- the render’s parameters, with the asymmetry checked both exactly and on the render;
- SciPy’s root finder as the only library cross-check, since no image library has a depth-of-field routine.
The first pilot found two faults in the code.
- H1b row selection. H1b selected its rows by a threshold, , instead of by the planned fractions of . This brought in the f/8 row at 10 m, and the check failed.
- C2 float comparison. C2 compared the unblurred contrast with 1 for floating-point equality, and that check failed.
With the editor’s approval both were repaired before this run. H1b now selects its rows by their fraction of and prints the number of rows per f-number, which must be 3. C2 now uses a tolerance of . Between the two pilots, H1b and C2 changed from failed to held; every other printed line is identical. This run is the repeated pilot.
Common Misconceptions
- “Depth of field is centred on the focus distance.” More of it lies behind: 64 against 60 mm at f/2 and 284 against 220 mm at f/8 in the example. At the hyperfocal distance the back part is infinite.
- “Depth of field is a property of the lens.” It depends on the acceptable blur , which is a choice that depends on the sensor, the output and the viewer (Levoy, slide 52). The same exposure has different depths of field for different .
- “Depth of field is proportional to the f-number.” Only in the approximation, and only well short of the hyperfocal distance. Near the exact depth grows much faster than linearly, and beyond it the depth is infinite.
- “Focus at infinity for maximum sharpness of a landscape.” With the sensor focused at infinity the near limit is at (our derivation, the limit of as ); focusing at brings it in to while keeping infinity sharp.
- “Levoy’s and are the same.” They differ by . The first comes from the approximation and leaves a finite (if distant) far limit, as the example prints; the second is exact in the thin-lens model.
- “Stopping down always makes more of the image sharp.” Past the point where diffraction blur approaches , the whole image gets softer (image formation).
- “Synthetic background blur is depth of field.” Phone portrait modes blur an image by an estimated depth map, deliberately not physically correct defocus (computational photography). In our reading, optical depth of field also mixes foreground and background at occlusions, which a blur applied per pixel does not.
- “A depth-of-field routine computes the exact limits.” ISETCam’s
opticsDoF.mdescribes its calculation as finding two points on either side of the focus distance with equal circles of confusion, but its code returns the approximation , with a comment attributing the formula to Wikipedia. Results from it inherit the approximation’s error near the hyperfocal distance.
Where It Is Used
- Camera set-up. Exposure treats depth of field as one of the costs of the aperture: one stop smaller shrinks the defocus blur by and halves the light, so a set-up that needs both a deep sharp range and short exposures has to add light. Vision system design lists the aperture’s effects on light, depth of field and diffraction among the optical choices. The digital camera article notes that the aperture sets both the light and the depth of field.
- Dataset capture. Tanks and Temples records that its capture lens was usually focused at the hyperfocal distance.
- Range from focus. Active perception describes Krotkov’s work, which modelled the depth of field to predict the precision of range from focus and opened the aperture to make it shallow. Depth from focus and depth from defocus, mentioned in depth estimation, turn the dependence of blur on depth into a measurement, so a shallow depth of field is what they need.
- Microscopy. At high magnification the depth of field is shallower than a tissue section is thick. Whole-slide imaging describes focus maps and extended depth of field, which combines images from several focal planes.
- Deblurring and synthesis. Image deblurring inverts defocus outside the depth of field, and computational photography synthesizes shallow depth of field and records light fields that can be refocused after capture.
Related
- Exposure
How much light a camera records in one frame, set by shutter time, aperture and gain; how exposure is counted in stops, metered and controlled automatically, and what each setting costs a vision system in motion blur, noise, depth of field and clipping.
- Point Spread Function
The image a camera forms of a single point of light, how diffraction, defocus, aberrations and the pixel aperture combine into it, its Fourier transform the optical transfer function and its magnitude the MTF, and how the MTF is measured from a slanted edge.
- Image Deblurring
Recovering a sharp image from a blurred one, covering the convolution model and point-spread function, inverse, Wiener and Tikhonov filtering, Landweber and Richardson–Lucy iterations, regularization and stopping, boundary handling and ringing, blind deconvolution, motion and defocus blur, and learned deblurring in outline.
- Computational Photography
Making photographs by combining capture and computation, from burst align-and-merge, HDR, multi-frame denoising and super-resolution to synthetic depth of field, panoramas, flash/no-flash pairs, light-field cameras and coded apertures and exposures; how these reached phones, and why phone images break the single-exposure assumptions of vision methods.
- Active Perception
The idea that a perceiving agent should decide why, what, how, when and where to sense, from Bajcsy's 1988 definition and the active vision of the late 1980s to next-best-view planning by information gain, active recognition and object search, learned exploration policies and active perception in embodied AI.
- Designing a Computer Vision System
How a working vision system is designed from its requirements, through the choice of sensor, optics, lighting, compute and model, to the data it is trained on, its validation in the field and its maintenance once deployed, with the requirement arithmetic for a measurement station worked through in code.
References
- Levoy, M. (2013). Optics I: Lenses and Apertures. Lecture slides, CS 178: Digital Photography, Stanford University, Spring 2013 (cited by slide number).
- Levoy, M. (2013). Optics II: Practical Photographic Lenses. Lecture slides, CS 178: Digital Photography, Stanford University, Spring 2013 (cited by slide number).
- Torralba, A., Isola, P. & Freeman, W. T. (2024). Foundations of Computer Vision. MIT Press. Chapter 6, Lenses, §6.3.1 Depth of Field (read in the online edition).
- ISETCam (Stanford Center for Image Systems Engineering). opticsDoF.m, at commit 3e0253421752eb72f2d1353327dffd0d433abdaf (MIT licence; code and header comments read).