Bayer pattern & demosaicing

A sensor pixel only counts light; it cannot tell colors apart. Color cameras therefore place a tiny red, green or blue filter on every pixel, so each pixel measures just one of the three channels. Demosaicing estimates the two missing channels from the neighbors. Zoom in and compare what the sensor records with what the camera reconstructs.

Raw sensor mosaic click to select a pixel (and zoom center)
Demosaiced 192 × 144 px

The Bayer pattern

The most common color filter array repeats a 2×22 \times 2 block with one red, two green and one blue filter:

[RGGB](RGGB)\begin{bmatrix} \htmlClass{ch-r}{R} & \htmlClass{ch-g}{G} \\ \htmlClass{ch-g}{G} & \htmlClass{ch-b}{B} \end{bmatrix} \quad \text{(RGGB)}

Half of all pixels measure green, a quarter red and a quarter blue. Green gets twice the samples because it carries most of the brightness we perceive: the M and L cones of the eye are most sensitive to green-yellow light. The luminance of linear light, which models this sensitivity, is Y=0.2126 R+0.7152 G+0.0722 BY = 0.2126\,R + 0.7152\,G + 0.0722\,B for the sRGB primaries: green has by far the largest weight. Our visual system resolves fine detail mainly in brightness and much less in color, so it makes sense to spend the samples there.

The raw image has a single value per pixel. Shown in gray it looks like a normal black-and-white image with a fine checkerboard texture wherever the scene is colored.

Demosaicing

Every pixel knows one channel and has to estimate the other two. Nearest neighbor copies them from the same 2×22 \times 2 block. Bilinear interpolation averages the closest samples of the missing channel: the 4 direct neighbors for green, and 2 or 4 neighbors for red and blue. Written as a convolution of each sparse channel (zero where it was not measured):

KG=14[010141010],KR,B=14[121242121]K_G = \frac{1}{4} \begin{bmatrix} 0 & 1 & 0 \\ 1 & 4 & 1 \\ 0 & 1 & 0 \end{bmatrix}, \qquad K_{R,B} = \frac{1}{4} \begin{bmatrix} 1 & 2 & 1 \\ 2 & 4 & 2 \\ 1 & 2 & 1 \end{bmatrix}

At a measured pixel only the center weight hits a sample, so the value is kept. Elsewhere the kernel picks up exactly the neighbors described above. At the image border only the available samples are averaged.

Artifacts

Real cameras use edge-aware demosaicing that interpolates along edges instead of across them, and many place a slightly blurring optical filter in front of the sensor to remove detail that the mosaic cannot capture.

Measuring the error. The values panel compares the reconstruction with the original using the peak signal-to-noise ratio for values in [0,1][0, 1]: PSNR=10log⁡101MSE dB\mathrm{PSNR} = 10 \log_{10} \frac{1}{\mathrm{MSE}} \ \text{dB} Higher is better; each extra 6 dB halves the typical error.

Try this