draft · v0.1.226
💬Comments welcome. To leave a note, select any text and click the note / highlight button that pops up — or open the panel with the tab at the top-right (‹). Notes are visible only inside our private review group.
💡 In a hurry? Jump to this chapter’s 9 big lessons ↓

2.13 Noise, signal-to-noise ratio and dynamic range

Noise earns a chapter of its own because, more than resolution or optics, noise is what ultimately limits our ability to measure and reconstruct an image. Almost everything else in this book — denoising, demosaicking, deblurring, HDR merging, depth from stereo, super-resolution — is at bottom an attempt to recover a clean signal from noisy measurements, and their performance is limited by how much noise corrupts the input. So understanding where noise comes from, how it scales with light, and which kind dominates when is not a side topic: it is the quiet constraint behind the whole field. It tells you what is recoverable and what is lost for good, how many photons or frames you need to reach a target quality, and — when a result disappoints — whether you are limited by your algorithm or by the physics of the measurement itself. Read this chapter as the floor under every later one.

2.13.1 Noise sources

Counting photons is what makes a sensor linear, but counting is also where noise comes from. Take two photos of the same still scene at the same settings and they are not byte-for-byte identical; each pixel value jitters from frame to frame. Several physical sources contribute, and because they are statistically independent, their variances add, so to combine them we add variances ($\sigma^2$), not standard deviations (Figure 2.13.3).

💡 Big lesson (L2.41) — variance is the mathematically meaningful quantity; standard deviation is the human-readable one

Two numbers describe noise spread, and it pays to know why both exist. Variance (the mean squared deviation) is the quantity the mathematics wants: it is additive for independent sources — exactly what we just used, and the basis of the $1/\sqrt N$ averaging law in Denoising basics — it is the second moment that falls out of every Gaussian and least-squares derivation, and it composes cleanly under linear operations. But its units are squared (squared gray-levels, squared photons), so it means nothing to the eye. The standard deviation $\sigma$ (its square root) is the one people should read: it is back in the original units, directly comparable to the signal — the "$\sigma$" of error bars and the grain you actually see. Rule of thumb: derive and combine in variance, report in standard deviation.

Photon (shot) noise is the deepest source, and it is not a defect of the sensor — it is the light itself. Light arrives as discrete photons at random times, so the count in a fixed interval fluctuates even from a perfectly steady source. The statistics are Poisson, and the defining property of a Poisson process is that its variance equals its mean (Hasinoff 2012 is the canonical short reference). So if a pixel collects $N$ photons on average, the variance of the count is $N$ and the standard deviation is

$$ \sigma = \sqrt{N}. $$

This is irreducible: no better sensor can remove it, because it is a property of light, not of electronics. It dominates the midtones and highlights, where $N$ is large. The only mitigation is averaging: average $N_f$ independent frames of the same scene and the shot noise drops by $\sqrt{N_f}$ — the statistical basis of burst denoising and astrophotography stacking.

Sidebar — what is a Poisson process?

A Poisson process is the standard model for events that occur independently and at random, at a steady average rate, with no two at exactly the same instant: raindrops striking a tile, clicks of a Geiger counter, and, for us, photons landing on a pixel. It rests on three assumptions: the counts in non-overlapping intervals are independent; events arrive at a constant mean rate $\lambda$; and the process is memoryless (how long you have already waited says nothing about when the next event comes, so the gaps between events are exponentially distributed). Under these, the number of events in a fixed interval follows the Poisson distribution,

$$ P(k) = \frac{\lambda^k e^{-\lambda}}{k!}, $$

whose single parameter $\lambda$ is both its mean and its variance. That coincidence, $\text{variance} = \text{mean}$, is the whole of shot noise: catch $N$ photons on average and the count wobbles with standard deviation $\sqrt{N}$, so the noise grows as the square root of the signal and can never be zero. (Ideal laser light is exactly Poisson; thermal light bunches very slightly above it, but for photography Poisson is the right model.)

💡 Big lesson (L2.42) — noise is fundamental: photon shot noise sets the floor

Even a flawless sensor is noisy, because light itself is grainy: photons arrive as discrete, randomly-timed events, so the count in any fixed interval follows Poisson statistics ($\sigma=\sqrt N$), and no electronics can remove it — the randomness is in the light, not the chip. The only true cure is collecting more photons: a bigger pixel, a wider aperture, a longer exposure, or averaging many frames. Crucially, raising ISO is not a cure — it is gain applied after capture, amplifying signal and shot noise together. This irreducible floor is why bigger sensors win, why shadows are noisy, and what every denoiser later in the book is ultimately fighting.

fig-poisson-noise
Figure 2.13.1. Photon shot noise, live and interactive. Photons rain from above into $K$ groups of $n$ buckets (pixels) — both are sliders. Each group fills at its own flux, chosen so its expected count is simple ($10, 100, 1000$ by default; a ratio slider spreads them around the middle), and the $n$ buckets in a group share that expectation, so their spread is exactly the shot noise at that level. Each exposure runs for the shutter time (1 s by default) and then we count. Because photon arrivals are independent and random the counts are Poisson, so the running mean and variance under each group stay nearly equal. Every exposure adds $K$ points to the upper plot, where you can read the spread as variance (climbing the line variance = mean), standard deviation, or SNR (both tracking $\sqrt N$); the lower plot scatters all $N\times K$ buckets, expected count vs. what each actually caught, so the cloud around $y=x$ visibly widens with brightness in absolute terms yet tightens in relative terms. It makes the defining fact of shot noise, $\sigma=\sqrt N$, something you watch happen. Log axes; no well saturation; reset clears the accumulated points.

The remaining sources are added by the hardware:

💡 Big lesson (L2.43) — know the noise sources, and when each one dominates

Sensor noise is a sum of distinct sources whose variances add, but each rules a different regime — so diagnosing a noisy image means asking which one you are seeing. Photon shot noise ($\propto\sqrt{\text{signal}}$) dominates the midtones and highlights, and any well-lit shot. Read noise is signal-independent and dominates the deep shadows and short exposures, setting the floor. Thermal / dark-current noise grows with exposure time and temperature — the long-exposure and astrophotography enemy. Quantization matters only with too few bits (L2.49). And fixed-pattern noise / PRNU — static per-pixel gain and offset variation — reads as a structured pattern and is removed by calibration (dark and flat fields). Match the symptom to the source before reaching for a fix.

The same five sources, as a reference table — what each varies with, where it dominates, and whether you can remove it:

sourcewhat it isvaries withdominant regimeremovable?
photon (shot) noisePoisson statistics of photon arrival$\sigma=\sqrt{N}$ — grows as √(signal)midtones & highlights; every well-lit shotno (fundamental — only more light helps)
read noiseamplifier + ADC at read-outconstant per read-out; relatively lower at higher analog ISOdeep shadows, short exposures (sets the floor)no, but minimized; charge-binning pays it once
dark-current (thermal)electrons freed by heatexposure time × temperature (≈ doubles per ~6–8 °C)long exposures, hot sensors, astropartly — cooling + dark-frame subtraction
quantizationfinite ADC bit depthnumber of bits (negligible with enough)only with too few bits / a heavy pushyes — more bits, dithering
fixed-pattern / PRNUper-pixel gain & offset variation, hot pixelsstatic (same each frame); gain part scales with signalstructured pattern, visible in flats/darksyes — flat- & dark-field calibration
Sidebar — cooled cameras for astrophotography

Dark current is the one noise source you can attack with a refrigerator. Because thermally-freed electrons roughly double for every ~6–8 °C, cooling the sensor a few tens of degrees below ambient cuts dark-current noise by a large factor — which is why dedicated astrophotography cameras bolt a thermoelectric (Peltier) cooler to the sensor and run it at a regulated set-point (say −10 °C or −20 °C). The set-point matters as much as the cooling: holding a fixed temperature makes the dark frames repeatable, so a library of master darks taken once can be subtracted from every light frame to remove both the dark-current pedestal and the hot pixels. Combined with the $1/\sqrt N$ stacking of many long sub-exposures (a later chapter), regulated cooling is what lets amateurs pull faint galaxies out of the noise over a night of integration (Figure 2.13.2).

fig-cooled-camera
Figure 2.13.2. A dedicated cooled astrophotography camera (ZWO ASI2600MC Pro). Front: the sensor sits behind a sealed, desiccated window. Back: a finned heatsink and fan dump the heat that a thermoelectric (Peltier) cooler pumps off the sensor, powered by a dedicated 12 V line. Run at a regulated set-point tens of degrees below ambient, the cooler drives dark current down (it roughly halves per ~6–8 °C), so long deep-sky exposures stay clean and a library of dark frames stays repeatable. Photographs by Frédo Durand.
[figure fig-noise-histogram not built]
Figure 2.13.3. Noise sources and a noisy capture. A high-ISO photo (here ISO 3200) with a flat patch enlarged, beside its histogram — a spread, not a spike. The spread is the sum of independent sources whose variances add: photon/shot noise (Poisson, $\sigma = \sqrt{N}$, dominates midtones and highlights), read noise (signal-independent, dominates shadows, sets the floor), thermal/dark current (grows with time and heat), and structured fixed-pattern noise (removed by calibration).

We can see that noise directly. Shoot a burst of one static scene at high ISO and take, for every pixel, its variance across the frames: the result is a map of the noise itself, laid over the picture (Figure 2.13.4). The noise is not uniform — it is heavier in the brighter regions (shot noise) and along edges — which is the clue to the rule that follows.

fig-noise-variance-map
Figure 2.13.4. The noise of a real high-ISO image, and its SNR. From a 50-frame ISO-3200 burst of one static scene: the scene itself (left, mean of the burst), the per-pixel variance across the burst (middle), and the per-pixel SNR = signal/noise (right). Computed on linearized values, so shot noise behaves physically. The variance map is brightest where the scene is bright — absolute noise grows with signal — while the SNR map is also brightest in the bright areas and worst in the shadows, because noise only grows as √signal so the ratio improves with light. Bright pixels are noisier in absolute terms yet cleaner in relative terms. This is the raw material the affine model below summarizes.

2.13.2 Noise variance is affine in pixel brightness

Because the variances of these sources add, and because the dominant two scale so simply with the signal, the whole noise level follows a strikingly simple rule that we can measure directly from data.

💡 Big lesson (L2.44) — in a linear image, noise variance is an affine function of brightness

The variances add, and two terms dominate: shot noise contributes an amount proportional to the signal (Poisson, variance = mean, scaled by the gain) and read noise a constant floor. So the total is variance ≈ gain·signal + read² — a straight line in brightness (Figure 2.13.5). The slope is the photon gain (it steepens with ISO, which amplifies the signal and its shot noise together); the intercept is the read-noise floor. We can measure it without any model: take an aligned burst of a static scene and, per pixel, plot the variance across frames against the mean. And a single pixel's value over many frames is ≈ Gaussian (Figure 2.13.6) — which is what licenses modeling per-pixel noise as additive Gaussian.

fig-noise-affine
Figure 2.13.5. Noise variance is affine in brightness — measured. From a 50-frame burst of one static scene at ISO 3200, the per-pixel variance plotted against the per-pixel mean (in the linearized domain, on flat patches so mis-alignment doesn't masquerade as noise) traces a straight line: a constant read-noise floor (intercept) plus a shot-noise term proportional to the signal (slope = gain), $\sigma^2 \approx a\,I + b$. Toward the bright end the camera's highlight roll-off and clipping pull the measured variance below the line — the truncation taken up next.
fig-noise-gaussian-pixels
Figure 2.13.6. A single pixel, over many frames, is ≈ Gaussian. Histograms of a few flat pixels' values across the 50 frames, at increasing brightness, each with a fitted Gaussian: the spread is well described by a normal distribution (the central-limit sum of many small effects). This is the empirical basis for the additive-Gaussian noise model used throughout denoising.

Read the affine model the other way and it becomes a noise simulator: the quickest way to turn a clean image into realistic noisy data, for stress-testing a denoiser or building the synthetic training pairs this book leans on (Deep learning). The one rule that makes or breaks it is to work on a linear image, never a gamma-encoded one. Variance is affine in brightness only in linear light; add the noise after the tone curve and you inject the wrong amount in the shadows, exactly where it shows, and the result looks plainly fake. So, on a linear image with values $I\in[0,1]$, walk the pixels and give each a Gaussian kick whose variance the affine model prescribes (Algorithm 2.13.1):

Algorithm 2.13.1
for each pixel value I:                  # I is LINEAR, in [0, 1]  (not gamma-encoded)
    var   = a * I + b                    # affine model (L2.44): shot slope a, read floor b
    noise = gaussian(mean = 0, std = sqrt(var))
    I     = I + noise
    I     = min(I, 1)                    # clamp to full well: highlights clip at 1
    # I   = max(I, 0)                    # optionally clamp to 0 — but SKIP this if the
                                         #   simulated sensor adds a black-level pedestal (a
                                         #   constant), which legitimately lifts small negatives
# apply gamma / the display curve only AFTER this loop, never before

The two constants set how noisy the "camera" is, and they span a wide range with sensor size and ISO (values for $I$ scaled to $[0,1]$). A large full-frame sensor runs from about $a\approx10^{-5},\ b\approx10^{-9}$ at base ISO to $a\approx10^{-3},\ b\approx10^{-7}$ pushed to high ISO; a small phone sensor from about $a\approx10^{-4},\ b\approx10^{-8}$ at base ISO to $a\approx10^{-2},\ b\approx10^{-6}$ at high ISO. Smaller wells (the phone) and more amplification (high ISO) both steepen the slope $a$ and lift the floor $b$. This Gaussian kick is the fast approximation; for a more physical version that draws the shot term from a Poisson distribution in electrons and applies the sources in capture order, see the fuller recipe later in this section.

Sidebar — who was Gauss?

Portrait of Carl Friedrich Gauss, by Christian Albrecht Jensen Carl Friedrich Gauss (1777–1855) — the "prince of mathematicians" — appears repeatedly in this book, and you have just met him in the bell curve. The Gaussian (normal) distribution that a noisy pixel traces over many frames is his, and so is least squares, which he used in 1801 to recover the orbit of the dwarf planet Ceres from a handful of sightings and which underlies nearly every fit and reconstruction we do. The same name returns as the Gaussian blur, Gaussian elimination inside our linear solvers, and the Gauss–Seidel iteration. That a sum of many small independent effects collapses into one bell shape — the central limit theorem — is exactly why the additive-Gaussian noise model keeps working. Portrait: painting by Christian Albrecht Jensen, 1840, public domain (via Wikimedia Commons).

The affine model and the Gaussian shape are the ideal. Real recorded values break the ideal in one important way at the extremes.

💡 Big lesson (L2.45) — noise is clipped at black and white, so near the extremes it is not zero-mean

A recorded value is clamped to $[0,\text{max}]$. Near black the negative half of the noise is cut off and frames pile up at 0; near white the positive half is. So at the extremes the noise distribution is asymmetric, with its mean pushed inward (Figure 2.13.7). The consequence for denoising: a naive average or smoothing returns that biased mean, so it makes shadows come out too bright and highlights too dark — a bias every denoiser must correct for (we return to it in Denoising, BASIC).

That clipping caveat is the first crack in the affine model, and a larger one is worth planting now. The law $\sigma^2 \approx a\,I + b$ describes the noise as the sensor hands it over — the raw mosaic, straight off the ADC; it is a fact about the sensor, not about the final photograph. Run that raw through the computational-photography pipeline and the clean affine line bends. A burst merge (align-and-average $N$ frames, Denoising basics) drives the variance toward $1/N$ of a single frame, but unevenly — the robust merge keeps more frames in still regions than near moving edges — so the noise becomes spatially varying, and highlight clipping means it is no longer even affine in brightness. Demosaicking (Demosaicking) bends it too: an interpolated color is a weighted average of neighboring pixels, and averaging shrinks variance, so reconstructed pixels are quieter than the ones actually measured — by different amounts, pixel to pixel. After a few ISP stages the tidy 'gain·signal + read²' line is gone, and a downstream algorithm that still assumes it (a plain AWGN denoiser, say) is fitting a model the data no longer obeys.

fig-noise-truncation
Figure 2.13.7. Clipping makes noise asymmetric at the extremes. A near-black pixel spends about 44% of its frames pinned at 0 — the negative half of its noise is clamped away — so the average of its frames (what naive denoising returns) sits well above 0: biased bright. A clean midtone pixel, by contrast, is a symmetric Gaussian whose average is unbiased. Averaging therefore lifts shadows too bright and, symmetrically, pulls clipped highlights too dark.

Manufacturers know this and design around it: many sensors deliberately lift the black point before digitizing. They add a fixed offset — a "black level" or bias, a few hundred code values — to the signal, so the whole bell of the read noise, negative excursions included, lands above zero and is recorded rather than clipped (Canon, for instance, sits its black level around code 512 or 2048 on 14-bit raw; other makers similar). The raw file then carries an explicit black-level tag that the converter subtracts back out. Keeping the noise unclipped this way is exactly what lets noise-weighted averaging, flat/dark calibration, and shadow-lifting stay unbiased down in the darkest tones — at the cost of a sliver of headroom. One discipline follows: after subtracting the black level, near-black pixels can legitimately go slightly negative, and that must be preserved, not clamped, all the way until display, or the bias creeps right back in.

Sidebar — how to simulate sensor noise

The affine model is also a recipe: it is how you turn a clean image into realistic noisy data — for testing a denoiser, or for the synthetic training pairs this book leans on (→ synthetic data in Deep learning). Work in linear light, think in electrons, and apply the sources in capture order:

  1. Scale to electrons. Map the clean linear image to a photon count, $N = I\cdot N_{\text{full}}$ — or pick an exposure level; fewer electrons means a noisier result. This chooses where on the SNR curve you land.
  2. Shot noise. Replace each pixel by a Poisson draw with mean $N$ (numpy.random.poisson(N)), or a Gaussian of variance $N$ when $N$ is large. This is the $\sigma=\sqrt N$ floor — it is signal-dependent, drawn per pixel, not added as a constant.
  3. Read noise. Add zero-mean Gaussian noise of standard deviation $\sigma_r$ electrons (the floor; larger at higher ISO).
  4. Gain, black level, clip, quantize. Multiply by the analog/ISO gain, add the black-level offset, clip at full-well (highlights), and quantize to the bit depth.
  5. Re-encode. Apply gamma / the camera curve last, so the noise you built in linear light decodes correctly.

The cardinal mistake is adding a single constant-σ Gaussian to a gamma-encoded image: that is neither signal-dependent (no shot noise) nor in the right space, and it looks wrong in exactly the shadows where it matters. Real noise is Poisson + Gaussian, in linear electrons; everything else is a shortcut.

2.13.3 The algebra of noise

Because the sources are independent, their variances add — the single most useful fact for reasoning about noise, and worth turning into a tool. For $N$ independent measurements each of variance $\sigma^2$, the sum has variance $N\sigma^2$ (standard deviation $\sqrt N\,\sigma$), while the average has variance $\sigma^2/N$ (standard deviation $\sigma/\sqrt N$). That $1/\sqrt N$ is the engine of all averaging-based denoising (a whole chapter later). The same algebra settles a subtler, very practical question: is it better to measure light with one big pixel, or with several small ones and add them up?

Take a patch that collects $N$ photons. Capture it with one big pixel: it counts $N$ photons (shot variance $N$, since Poisson variance $=$ mean) and adds the read noise once, $\sigma_r^2$. Now split the same patch into four small pixels, each catching $N/4$ photons. Summing their four readings recovers the signal $N$, and the shot noise is identical — the four shot variances $N/4$ add back to $N$, exactly the big pixel's. But each small pixel contributes its own read noise, so the sum carries $4\sigma_r^2$: the read noise is paid four times over. So, provided no light is lost in the gaps between photosites, the big pixel's only real advantage is read noise, not shot noise. Shot noise depends solely on how many photons you caught, never on how you diced up the sensor; read noise is charged once per read-out.

This is exactly why binning matters, and why how you bin matters. Charge binning — pooling the pixels' charge in the analog domain before it reaches the amplifier and ADC — reads the combined charge once, paying read noise a single time and recovering the full big-pixel advantage; this is the trick a good quad-Bayer sensor uses in low light. Digital binning — reading the four pixels separately and adding the numbers afterward — pays read noise four times and captures only the shot-noise equivalence. The gap is invisible in bright light (shot-noise-dominated) and decisive in the dark (read-noise-dominated). It also restates the affine model $\sigma^2 = g\,I + \sigma_r^2$ from a new angle: aggregating $k$ measurements multiplies the read-noise term's contribution by $k$ unless you combine before read-out.

💡 Big lesson (L2.46) — aggregating measurements keeps the shot noise but multiplies the read noise

Add the readings of $k$ small pixels and you get the same Poisson (shot) noise as one big super-pixel that caught the same photons — but you pay the read noise $k$ times, once per read-out, instead of once. So the only fundamental advantage of a bigger pixel (or one longer exposure) over many smaller ones is the read noise, not the photon statistics — as long as no light is lost in the gaps. The same holds for aggregating along any dimension: summing $k$ short exposures, or $k$ burst frames, keeps the shot noise of the total light but charges read noise $k$ times. This is precisely why charge-domain binning (combine, then read once) beats digital summation (read $k$ times, then add) in the dark.

2.13.4 Signal-to-noise ratio: it's about ratios

Here is the fact that surprises people and ties the whole part together. Since shot noise is $\sigma = \sqrt{N}$, the absolute noise is actually larger in the bright parts of the image than in the dark parts — a highlight collecting 10,000 photons has $\sigma = 100$, while a shadow collecting 100 photons has only $\sigma = 10$. And yet noise looks worst in the shadows. The resolution is that perception cares about the signal-to-noise ratio (SNR), not the absolute noise. For shot noise,

$$ \mathrm{SNR} = \frac{N}{\sqrt{N}} = \sqrt{N}. $$

The SNR grows with brightness, so it is worst where the light is faintest — the shadows — even though the raw noise magnitude is smallest there (Figure 2.13.8). Ratios are all that matters. This is the same lesson that drives gamma/log encoding (we encode so that equal ratios get equal steps) and exactly why exposing to the right works: collecting more photons everywhere, especially in the shadows, raises $N$ and therefore raises the SNR where it is worst.

One caution before we go on, because the acronyms collide: SNR is not PSNR. The signal-to-noise ratio here is a property of a capture — the true signal at a pixel relative to the sensor's noise there ($\sqrt N$ for shot noise) — and it answers how clean is this measurement? Peak signal-to-noise ratio (PSNR), which you meet whenever an algorithm is evaluated, is a different animal: a full-reference quality metric that compares a processed image $\hat I$ against a ground-truth reference $I$, computed from their mean-squared error as

$$ \mathrm{PSNR} = 10\log_{10}\!\frac{\mathrm{peak}^2}{\mathrm{MSE}}\quad\text{(dB)}, $$

where $\mathrm{peak}$ is the largest possible value (255 for 8-bit) and $\mathrm{MSE}=\tfrac1n\sum(\hat I-I)^2$. So SNR describes a photograph (how much noise a single measurement carries, with no reference needed), while PSNR scores a reconstruction against a known truth (how close a denoiser or codec got). They share "signal-to-noise" and a decibel scale and nothing else — one is a fact about the sensor, the other a yardstick for algorithms (and, as the metrics discussion later notes, a flawed one: because PSNR is just re-scaled MSE, it quietly rewards the blurry, safe answer).

💡 Big lesson (L2.47) — bright pixels are noisier (more absolute noise) but have better SNR

Shot noise is Poisson, so its variance grows linearly with the signal ($\sigma^2 \propto N$) and its standard deviation grows only as the square root ($\sigma \propto \sqrt{N}$). Two consequences pull in opposite directions: the absolute noise is larger in highlights than in shadows (a 10,000-photon highlight has $\sigma=100$; a 100-photon shadow has $\sigma=10$), yet the SNR $= N/\sqrt{N} = \sqrt{N}$ is higher in the highlights — the signal outgrows the noise. So bright areas are noisier in absolute terms but cleaner to the eye; the shadows have the worst SNR (Figure 2.13.4, Figure 2.13.8). This is why exposing to the right and brighter scenes look smoother, and why we gamma/log-encode so equal ratios get equal steps.

fig-snr-vs-stddev
Figure 2.13.8. Noise is numerically worse in highlights but looks worse in shadows. Two maps of the same brightness ramp: a standard-deviation map (absolute noise) is brightest in the highlights, since shot noise $\sigma = \sqrt{N}$ grows with brightness; an SNR map ($=\sqrt{N}$) is worst in the shadows, since the ratio falls where photons are few. Perception tracks the ratio, so shadows look noisiest — the reason for exposing-to-the-right and for gamma/log encoding.

The affine model settles a lot of everyday "will this help my noise?" questions at a glance. Read each move against $\sigma^2 = g\,I + \sigma_r^2$ (signal $I$, photon-gain slope $g$, read-noise floor $\sigma_r$), tracking what happens to the signal, the noise $\sigma$, and their ratio. The entries below are for the shot-noise-dominated regime (well-lit midtones); the read-noise term $\sigma_r$ changes only the two rows that mention it.

scenariosignalnoise $\sigma$SNRwhat is really going on
raise ISO by 1 stop (×2 analog gain)×2×2≈ sameamplifies signal and noise together and adds no photons. Read noise, applied after the gain, shrinks relative to the signal, so deep shadows come out a touch cleaner. Not a substitute for light.
brighten by 1 EV in software (×2)×2×2unchangedmultiplies values already recorded, so it amplifies the noise baked in at capture. No shadow benefit, unlike raising ISO at capture.
darken by 1 EV in software (×½)×½×½unchangedpure scaling; the ratio is untouched (though it can still clip or quantize).
average $N$ frames×1÷$\sqrt N$×$\sqrt N$independent noise partly cancels while the signal stays: the $1/\sqrt N$ law behind burst denoising and stacking.
sum $N$ values×$N$×$\sqrt N$×$\sqrt N$variances add, so SNR grows just like averaging; but read noise is paid $N$ times if the values are read separately.
charge-bin $N$ pixels (combine, then read once)×$N$×$\sqrt N$×$\sqrt N$, cleaner shadowssame shot noise as a digital sum, but read noise is paid once, not $N$ times. Why quad-Bayer binning wins in low light.
gather 2× the light (wider aperture or longer exposure)×2×$\sqrt 2$×$\sqrt 2$the only move that collects more photons, so the only real, fundamental gain in SNR. Read noise unchanged.

The pattern is stark: rescaling the numbers you already have (ISO, software exposure) never improves the signal-to-noise ratio; combining $N$ independent measurements improves it as $\sqrt N$; and the one thing that genuinely beats noise is collecting more light.

2.13.5 Dynamic range

Two extremes bound what a single exposure can hold. At the top, a pixel's well saturates: once it has counted its full-well capacity of electrons, more light adds nothing and the highlight clips to white. At the bottom, the read-noise floor sets the dimmest signal still distinguishable from noise. The ratio of the two is the sensor's dynamic range — how much of a high-contrast scene a single exposure can capture. When a scene's range exceeds the sensor's — a bright window and a dim interior in one frame — no single exposure holds both ends, which is the motivation for high-dynamic-range (HDR) imaging, merging several exposures (Multiple-exposure part) (Figure 2.13.9). Like everything else a photographer counts, dynamic range is quoted in stops — factors of two — which connects it straight to the exposure controls.

There is one more limit that no sensor spec sheet lists: the lens. Bright parts of a scene scatter stray light inside the lens and camera body — faint reflections off every element surface, the diaphragm blades, and the barrel walls — that settle as a veil of light spread across the whole frame. This veiling glare, the diffuse cousin of lens flare, lifts the darkest tones off true black, raising the effective noise floor from the optical side just as read noise raises it from the electronic side. It therefore caps the dynamic range a real photograph can reach below whatever the bare sensor could deliver, and it bites hardest exactly when dynamic range matters most, shooting a dim subject against a bright source. It is why lens coatings, hoods, and a clean front element buy real shadow contrast, and why the deepest blacks in a studio shot are easier to protect than those in a backlit scene. Flare and veiling glare get their full treatment as optical defects in Aberrations and optical challenges (§10.1).

fig-dynamic-range-problem
Figure 2.13.9. The dynamic-range problem. One high-contrast scene (a sunset over water) developed at three exposures: expose for the highlights and the foreground is crushed to black; expose for the shadows and the sky blows out to white; the compromise loses both ends. No single exposure holds the full range — the motivation for high-dynamic-range merging of multiple exposures.

How wide a range, exactly? It helps to put numbers on it, because the dynamic ranges of real media and of the eye differ by a lot (Figure 2.13.10). A color slide is narrow, only about 5–6 stops; a reflective print about 6–7; a film negative is famously forgiving at roughly 12–13 stops of latitude; a phone sensor manages about 10–12 and a full-frame sensor about 14. The human eye sees about 10–14 stops instantaneously, but allow it to adapt — the slow re-centering of the retinal response covered with perception — and it spans 20+ stops over time; some animals do better still within their niche. Against all of these, an outdoor sun-and-shadow scene can exceed 20 stops in a single frame — which is precisely why no single capture holds it, and why HDR exists.

fig-dynamic-range-comparison
Figure 2.13.10. (Deferred — to be generated.) Dynamic range across media and eyes, as a ladder of stops: color slide (~5–6 stops), reflective print (~6–7), film negative (~12–13 latitude), phone sensor (~10–12), full-frame sensor (~14), and the human eye (~10–14 instantaneous, ~20+ once adaptation is allowed), with an animal example, set against a real sun-and-shadow scene exceeding 20 stops — which no single capture spans, the motivation for HDR.

Recovering an underexposed shot: full-frame vs. phone. The clearest way to feel that dynamic range scales with photosite size is to break one. Shoot the same underexposed scene as raw on a full-frame camera and on a phone, then push the exposure up in software by three or four stops (Figure 2.13.11). The full-frame frame cleans up — its deep full-well and low read-noise floor give it the headroom to be lifted — while the phone frame breaks into shadow noise and banding, because lifting the exposure also amplifies its read-noise floor, which sat much closer to the signal to begin with. That is a direct, visible demonstration that dynamic range scales with photosite (and sensor) size, and exactly why phones lean on burst capture and HDR+ (Multiple-exposure part) rather than trusting a single exposure. It is also a coding exercise — see Exercises & Experiments.

[figure fig-underexposure-recovery-ff-vs-phone not built]
Figure 2.13.11. (Deferred — to be generated.) The same underexposed scene, shot as raw on a full-frame camera and on a phone, then pushed up about 3–4 stops in software: the full-frame frame cleans up (deep full-well, low read-noise floor → wide dynamic range), while the phone frame reveals amplified shadow noise and banding (its read-noise floor lifted with the signal) — dynamic range scaling with sensor size.
💡 Big lesson (L2.48) — dynamic range = full-well capacity ÷ noise floor

A single exposure records from a top — the photosite's full-well capacity, where it saturates and clips to white — down to a bottom — the noise floor, the read noise that drowns the shadows. Their ratio is the dynamic range, quoted in stops. You widen it with a bigger well (larger photosites — why a full-frame sensor out-ranges a phone) or a lower floor (cooling, lower read noise), and you beat it altogether by merging multiple exposures (HDR). This is the capture-side companion to the quantization lesson below: what bounds a single shot is this range — full-well over floor — not the number of bits.

This is also the right moment to deflate a worry beginners often have about digital capture: that the image is quantized into a finite number of levels, and that this stair-stepping is what limits quality. It almost never is.

💡 Big lesson (L2.49) — quantization is rarely the real problem

With enough bits and a sane encoding, what limits image quality is noise and dynamic range — the two quantities of this section — not the number of levels the analog-to-digital converter (ADC) offers. The noise floor and the full well bound what you can record; the quantization step, once it sits below the noise, is invisible. (Indeed, a little noise dithers the quantization, hiding it further.) The one place levels do bite is banding in the deep shadows of a linearly-encoded image — too few codes where the eye, working in ratios, is most sensitive — and that is exactly the problem gamma encoding exists to solve, by spending code levels perceptually (Color technology). So "rarely" is not "never." We meet this lesson again in BASIC → Image representation → Float vs 8-bit, where floats with headroom are the sane default.

These three facts — that noise is the jitter of a photon count, that the signal-to-noise ratio is worst in the shadows, and that dynamic range is the full-well-over-floor a single exposure can hold — recur on nearly every later page: in how a photographer exposes to the right, in high-dynamic-range merging (Multiple-exposure part), and in the denoising of the basic pipeline. With measurement and its limits now in hand, the part turns next to what a second viewpoint buys you — depth — and then to the eye that will finally judge the result.


2.13.6 Regimes, and how close we are to the limits

Pulling the chapter together: which noise matters depends entirely on how much light you have, and a single picture usually spans several regimes at once.

The same three regimes bound dynamic range, which is just full-well capacity ÷ read-noise floor (L2.48): the top set by how many electrons a pixel holds before clipping, the bottom by the read noise.

How close are we to the theoretical limits? On two of the three axes, modern sensors are already close to their physical limits.

So the photons themselves are nearly free and nearly all counted; what stays scarce is holding and reading them without adding noise, and there physics has almost run out of room. That is exactly why the frontier moved off the single capture and onto multi-frame computation — averaging down the floor and merging exposures to beat the well — the bridge from this chapter's physics to the rest of the book.

The whole budget is easiest to feel by turning the dials yourself (Figure 2.13.12).

fig-noise-calculator
Figure 2.13.12. Sensor noise calculator (interactive). Choose the sensor size, resolution, ISO, shutter duration, quantum efficiency, read noise, and the minimum SNR you will accept, all at typical values. From the pixel area it derives the full-well capacity and, for the chosen ISO, the saturation level, then reports the noise in electrons at black, at 18% grey, and at saturation, the corresponding SNR in decibels, and the affine noise model $\mathrm{Var}(I)=a+b\,I$ (read-noise floor $a$, photon slope $b$). A stacked bar splits the variance at 18% grey into photon, read, dark-current, and quantization shares — showing that the midtones are photon-limited and read noise only bites in the shadows. It gives the dynamic range two ways (full-well ÷ read noise, and the range down to your minimum SNR), in stops and decibels, and renders a log-spaced grey ramp with the model's real per-pixel noise so you can see the shadows go grainy while the highlights stay clean. Interactive: set sensor size, ISO, and read noise and read off the SNR, the per-source noise breakdown, the dynamic range, and a grey ramp rendered with the actual noise.

Recap: big lessons of this chapter

(L2.41) — variance is the mathematically meaningful quantity; standard deviation is the human-readable one

Two numbers describe noise spread, and it pays to know why both exist. Variance (the mean squared deviation) is the quantity the mathematics wants: it is additive for independent sources — exactly what we just used, and the basis of the $1/\sqrt N$ averaging law in Denoising basics — it is the second moment that falls out of every Gaussian and least-squares derivation, and it composes cleanly under linear operations. But its units are squared (squared gray-levels, squared photons), so it means nothing to the eye. The standard deviation $\sigma$ (its square root) is the one people should read: it is back in the original units, directly comparable to the signal — the "$\sigma$" of error bars and the grain you actually see. Rule of thumb: derive and combine in variance, report in standard deviation.

(L2.42) — noise is fundamental: photon shot noise sets the floor

Even a flawless sensor is noisy, because light itself is grainy: photons arrive as discrete, randomly-timed events, so the count in any fixed interval follows Poisson statistics ($\sigma=\sqrt N$), and no electronics can remove it — the randomness is in the light, not the chip. The only true cure is collecting more photons: a bigger pixel, a wider aperture, a longer exposure, or averaging many frames. Crucially, raising ISO is not a cure — it is gain applied after capture, amplifying signal and shot noise together. This irreducible floor is why bigger sensors win, why shadows are noisy, and what every denoiser later in the book is ultimately fighting.

(L2.43) — know the noise sources, and when each one dominates

Sensor noise is a sum of distinct sources whose variances add, but each rules a different regime — so diagnosing a noisy image means asking which one you are seeing. Photon shot noise ($\propto\sqrt{\text{signal}}$) dominates the midtones and highlights, and any well-lit shot. Read noise is signal-independent and dominates the deep shadows and short exposures, setting the floor. Thermal / dark-current noise grows with exposure time and temperature — the long-exposure and astrophotography enemy. Quantization matters only with too few bits (L2.49). And fixed-pattern noise / PRNU — static per-pixel gain and offset variation — reads as a structured pattern and is removed by calibration (dark and flat fields). Match the symptom to the source before reaching for a fix.

(L2.44) — in a linear image, noise variance is an affine function of brightness

The variances add, and two terms dominate: shot noise contributes an amount proportional to the signal (Poisson, variance = mean, scaled by the gain) and read noise a constant floor. So the total is variance ≈ gain·signal + read² — a straight line in brightness (Figure 2.13.5). The slope is the photon gain (it steepens with ISO, which amplifies the signal and its shot noise together); the intercept is the read-noise floor. We can measure it without any model: take an aligned burst of a static scene and, per pixel, plot the variance across frames against the mean. And a single pixel's value over many frames is ≈ Gaussian (Figure 2.13.6) — which is what licenses modeling per-pixel noise as additive Gaussian.

(L2.45) — noise is clipped at black and white, so near the extremes it is not zero-mean

A recorded value is clamped to $[0,\text{max}]$. Near black the negative half of the noise is cut off and frames pile up at 0; near white the positive half is. So at the extremes the noise distribution is asymmetric, with its mean pushed inward (Figure 2.13.7). The consequence for denoising: a naive average or smoothing returns that biased mean, so it makes shadows come out too bright and highlights too dark — a bias every denoiser must correct for (we return to it in Denoising, BASIC).

(L2.46) — aggregating measurements keeps the shot noise but multiplies the read noise

Add the readings of $k$ small pixels and you get the same Poisson (shot) noise as one big super-pixel that caught the same photons — but you pay the read noise $k$ times, once per read-out, instead of once. So the only fundamental advantage of a bigger pixel (or one longer exposure) over many smaller ones is the read noise, not the photon statistics — as long as no light is lost in the gaps. The same holds for aggregating along any dimension: summing $k$ short exposures, or $k$ burst frames, keeps the shot noise of the total light but charges read noise $k$ times. This is precisely why charge-domain binning (combine, then read once) beats digital summation (read $k$ times, then add) in the dark.

(L2.47) — bright pixels are noisier (more absolute noise) but have better SNR

Shot noise is Poisson, so its variance grows linearly with the signal ($\sigma^2 \propto N$) and its standard deviation grows only as the square root ($\sigma \propto \sqrt{N}$). Two consequences pull in opposite directions: the absolute noise is larger in highlights than in shadows (a 10,000-photon highlight has $\sigma=100$; a 100-photon shadow has $\sigma=10$), yet the SNR $= N/\sqrt{N} = \sqrt{N}$ is higher in the highlights — the signal outgrows the noise. So bright areas are noisier in absolute terms but cleaner to the eye; the shadows have the worst SNR (Figure 2.13.4, Figure 2.13.8). This is why exposing to the right and brighter scenes look smoother, and why we gamma/log-encode so equal ratios get equal steps.

(L2.48) — dynamic range = full-well capacity ÷ noise floor

A single exposure records from a top — the photosite's full-well capacity, where it saturates and clips to white — down to a bottom — the noise floor, the read noise that drowns the shadows. Their ratio is the dynamic range, quoted in stops. You widen it with a bigger well (larger photosites — why a full-frame sensor out-ranges a phone) or a lower floor (cooling, lower read noise), and you beat it altogether by merging multiple exposures (HDR). This is the capture-side companion to the quantization lesson below: what bounds a single shot is this range — full-well over floor — not the number of bits.

(L2.49) — quantization is rarely the real problem

With enough bits and a sane encoding, what limits image quality is noise and dynamic range — the two quantities of this section — not the number of levels the analog-to-digital converter (ADC) offers. The noise floor and the full well bound what you can record; the quantization step, once it sits below the noise, is invisible. (Indeed, a little noise dithers the quantization, hiding it further.) The one place levels do bite is banding in the deep shadows of a linearly-encoded image — too few codes where the eye, working in ratios, is most sensitive — and that is exactly the problem gamma encoding exists to solve, by spending code levels perceptually (Color technology). So "rarely" is not "never." We meet this lesson again in BASIC → Image representation → Float vs 8-bit, where floats with headroom are the sane default.