Skip to content
Free public beta until December 4, 2026: every course is open, no card needed. After that, the first chapter of each course stays free and full access is a one-time $39 ($19 for up to 100 founding members chosen for helpful feedback). Your progress is kept. How the beta works

Formula & theorem reference

Concept clusters →

Every named result in this course, grouped by chapter. Each one links back to where it's derived.

What is a digital image?

Formula

Uniform Quantization

also known as: rounding to the center of a bucket

For a uniform quantizer with L levels spanning [0, 255], the step size is \Delta = 256/L. A value v is quantized to q(v) = \left\lfloor \frac{v}{\Delta} \right\rfloor \cdot \Delta + \frac{\Delta}{2}, rounding to the center of whichever bucket v falls in. The resulting quantization error, |v - q(v)|, is bounded by half a step, \Delta/2, in the worst case. Fewer levels means a larger \Delta, and therefore coarser, more visible banding.

Point operations and image enhancement

Formula

The Log Transformation

also known as: logarithmic contrast enhancement

The log transformation remaps a pixel value v as f(v) = c \cdot \log(1+v), where c = 255/\log(256) scales the output back into [0,255], fixed by requiring f(255)=255. The +1 inside the logarithm exists only so f(0)=0 is well-defined, since \log(0) itself is undefined. The logarithm grows quickly at small inputs and slowly at large ones. Because of that shape, this transformation expands the narrow low, dark end of the input range, and compresses the wide high, bright end. It is the standard first step for revealing shadow detail crammed into a small band of raw values.

Formula

The Gamma (Power-Law) Transformation

also known as: gamma correction

Applied to values normalized to [0,1], the gamma transformation is f(v) = v^{\gamma}, rescaled back to [0,255] for storage. For \gamma<1 the curve bows upward, boosting dark values. For \gamma>1 it bows downward instead, pushing dark values darker still. At \gamma=1 it is the identity, so nothing changes. Gamma correction exists because physical displays once produced light output proportional to voltage raised to a power near 2.2, not to voltage itself. Correcting ahead of time with the reciprocal exponent, \gamma=1/2.2\approx0.45, before display makes the final light output proportional to the intended intensity.

Formula

Histogram Equalization

Histogram equalization derives its point operation from an image's own cumulative histogram, written H(i): a running total of the histogram up to intensity i. H(i) = \sum_{k=0}^{i} h(k) For a tiny image with 4 pixels at intensities 50, 50, 90, and 130, H(50) = 2, since 2 of the 4 pixels are at or below 50. The equalization mapping turns that running total directly into the new intensity: f(v) = 255 \cdot \frac{H(v)}{N} Here N is the total pixel count in the image. H never decreases as v grows, and H reaches N once v = 255. So f maps the input range [0,255] onto the output range [0,255]. Intensities where the histogram was densely packed get stretched apart, since H rises steeply there. Intensities where the histogram was sparse get compressed together, since H rises slowly there. The output histogram ends up close to flat, which is what raises contrast.

Convolution and correlation for images

Formula

2D Discrete Convolution and Correlation

also known as: the sliding-window sum, filtering an image by a kernel

For an image I and a kernel H of size (2a+1)\times(2b+1), the 2D discrete correlation is (I \star H)(x,y) = \sum_{i=-a}^{a}\sum_{j=-b}^{b} I(x+i,\, y+j)\, H(i,j), and the 2D discrete convolution is (I * H)(x,y) = \sum_{i=-a}^{a}\sum_{j=-b}^{b} I(x-i,\, y-j)\, H(i,j). The two differ by exactly one sign inside the image's index — a 180° rotation of the kernel — and coincide whenever the kernel is symmetric under that rotation. Both are a weighted sum over a window of input pixels centered at (x,y), with H supplying the weights.

Formula

Convolution Output-Size Formula

also known as: the stride/padding output-size formula

Take one axis of an input of size N, a kernel of size K, total padding P added along that axis (for example P=2 for one pixel of padding per side), and stride S. The output size along that axis is O = \left\lfloor \frac{N - K + P}{S} \right\rfloor + 1. Valid padding sets P=0. Same-size padding at stride 1 instead chooses P so that O=N, which requires P=K-1.

Formula

Separable 2D Kernel Factoring

also known as: outer-product kernel factoring

A 2D convolution kernel H is separable if it factors as the outer product of two 1D kernels, H(i,j) = h_{\text{row}}(i)\, h_{\text{col}}(j), equivalently H = h_{\text{col}}\, h_{\text{row}}^{\mathsf T} as a matrix product of a column vector and a row vector. Suppose H is separable. Then running the full K\times K kernel gives the identical result as two smaller steps: h_{\text{row}} along one axis, then h_{\text{col}} along the other. This drops the cost from K^2 multiply-adds per pixel to 2K, a saving that grows linearly with K, not quadratically. It is why every real-world smoothing filter runs the separated two-pass version inside.

Formula

The 2D Gaussian Kernel

also known as: Gaussian blur kernel

The Gaussian kernel weights a convolution neighborhood by a 2D Gaussian bell curve, H(i,j) = \frac{1}{2\pi\sigma^2} e^{-(i^2+j^2)/(2\sigma^2)}, scaled to sum to 1. Unlike a box kernel's flat weights, the Gaussian weights the center of the neighborhood most heavily, and tapers off smoothly toward the edges. That gives a smoother blur, with fewer visible marks. The setting \sigma (the Greek letter sigma) controls how strong the smoothing is: a small \sigma gives light smoothing, a large \sigma gives heavy smoothing. The kernel is also separable, H(i,j)=g(i)\,g(j) for the 1D Gaussian g. That is why real image libraries build it from two 1D passes, not one 2D pass.

Spatial filtering: smoothing and sharpening

Formula

The Bilateral Filter Weight

The bilateral filter computes each output pixel as a weighted average of its neighborhood. The weight is the product of a domain (spatial) factor and a range (intensity) factor: w(i,j) = \underbrace{e^{-(i^2+j^2)/(2\sigma_d^2)}}_{\text{domain weight}} \cdot \underbrace{e^{-(I(x+i,y+j)-I(x,y))^2/(2\sigma_r^2)}}_{\text{range weight}}. The domain weight is the ordinary Gaussian spatial weight. Nearby pixels count more. The range weight shrinks toward 0 as a neighbor's intensity differs more from the center pixel's. So a spatially close neighbor on the far side of an edge gets suppressed, even though the domain weight alone would count it heavily. As \sigma_r\to\infty, the range weight approaches 1 everywhere, and the filter reduces exactly to ordinary Gaussian smoothing.

Formula

The Discrete Laplacian Kernel

The Laplacian is the second-derivative operator \nabla^2 f = \partial^2f/\partial x^2 + \partial^2f/\partial y^2. Its standard discrete kernel comes from the discrete second-difference approximation along each axis. Each axis is computed separately, then the two are summed: H_L = \begin{bmatrix} 0 & 1 & 0 \\ 1 & -4 & 1 \\ 0 & 1 & 0 \end{bmatrix}. Convolving an image with H_L produces a large response exactly where a pixel differs sharply from the average of its four neighbors. That happens near edges and fine detail. In flat regions the response stays near 0. Unlike a smoothing kernel, H_L's entries sum to zero. Its output is not a brightness value. It is a correction signal, the raw ingredient of unsharp masking.

Formula

Unsharp Masking

Unsharp masking produces a sharpened image \hat I from an original I. It first builds a mask, the high-frequency detail I contains, then adds a scaled copy of that mask back: M = I - \bar I, \qquad \hat I = I + a\cdot M, where \bar I is a blurred copy of I, typically Gaussian-smoothed, and a>0 is the sharpening strength. The mask M is the original minus its own blur. It is large near edges and fine texture, and near zero in flat regions. Adding a scaled copy of it back amplifies exactly the structure a blur would have erased. The result is clipped to the legal pixel range before it is stored.

Image gradients and edge detection

Formula

The Sobel and Prewitt Operators

The Prewitt operator computes the horizontal and vertical gradient components with H_x^P = \begin{bmatrix}-1&0&1\\-1&0&1\\-1&0&1\end{bmatrix}, \qquad H_y^P = \begin{bmatrix}-1&-1&-1\\0&0&0\\1&1&1\end{bmatrix}. Each factors as a central-difference kernel in one direction and a uniform box-average in the other — differentiate one way, smooth the other, in a single kernel. The Sobel operator uses the identical structure with a weighted average instead of a uniform one, H_x^S = \begin{bmatrix}-1&0&1\\-2&0&2\\-1&0&1\end{bmatrix}, weighting the center row (or column, for H_y^S) twice as heavily — a discrete approximation closer to Gaussian-weighted smoothing, giving Sobel a slightly better noise response than Prewitt at identical cost.

Formula

Image Gradient Magnitude and Direction

Given horizontal and vertical gradient components G_x and G_y at a pixel, the gradient magnitude is |\nabla I| = \sqrt{G_x^2 + G_y^2}. This is a measure of edge strength that does not depend on which way the edge runs. It doesn't matter whether an edge is horizontal, vertical, or diagonal.

The gradient direction is \theta = \operatorname{atan2}(G_y,\ G_x), the angle of steepest increase. It uses \operatorname{atan2}, not plain \arctan(G_y/G_x), specifically to recover the correct quadrant when G_x is negative or zero. The gradient direction points across an edge, from its dark side to its bright side. The edge itself runs perpendicular to \theta, at a right angle to it.

Formula

The Laplacian of Gaussian

also known as: LoG, Marr-Hildreth edge kernel

The Laplacian of Gaussian (LoG) smooths an image with a Gaussian kernel and then applies the Laplacian. Equivalently, it convolves directly with one combined kernel, obtained by applying the Laplacian to the Gaussian function itself: \text{LoG}(x,y) = -\frac{1}{\pi\sigma^4}\left[1 - \frac{x^2+y^2}{2\sigma^2}\right]e^{-(x^2+y^2)/(2\sigma^2)}. Smoothing first makes LoG far less thrown off by noise than the raw Laplacian. LoG locates an edge as a zero crossing, a sign change in the response, rather than as a magnitude peak. A step-like brightness change makes the second derivative positive on one side of an edge and negative on the other. It crosses exactly zero at the edge itself.

Geometric transformations of images

Formula

Point Rotation, Reflection, and Shear

Rotation turns a point about the origin by angle \theta, measured the ordinary math way (positive angles turn counterclockwise): R(x,y) = (x\cos\theta - y\sin\theta,\ x\sin\theta + y\cos\theta). Reflection across an axis negates one coordinate. Reflecting across the x-axis sends (x,y) to (x,-y). Reflecting across the y-axis sends it to (-x,y). Shear slides points parallel to one axis, by an amount proportional to their position along the other axis. Horizontal shear with factor k sends (x,y) to (x+ky,\ y); vertical shear sends it to (x,\ y+kx). One image-specific catch: image coordinates put y increasing downward, not upward. So a positive \theta in the rotation formula looks clockwise on screen, even though the same formula turns counterclockwise on paper.

Formula

The Affine Transform in Homogeneous Coordinates

also known as: the 3×3 affine matrix

Append a 1 to every point, (x,y)\to(x,y,1). That one extra coordinate lets any affine map p'=Ap+t (a 2\times 2 linear part A, plus a translation vector t) become a single 3\times 3 matrix multiply: \begin{bmatrix}x'\\y'\\1\end{bmatrix} = \begin{bmatrix}a&b&t_x\\c&d&t_y\\0&0&1\end{bmatrix} \begin{bmatrix}x\\y\\1\end{bmatrix}. Translation, scaling, rotation, reflection, and shear are each one specific choice of a,b,c,d,t_x,t_y in this same shape. The bottom row is always [0,0,1] for an affine map.

Bilinear interpolation estimates a value at a non-integer source coordinate. It takes a weighted average of the surrounding 2\times2 pixel neighborhood, weighted by how close the coordinate sits to each of the four pixels. With fractional offsets (f_x,f_y) inside the cell and corner values p_{00},p_{01},p_{10},p_{11}: \text{top} = (1-f_x)\,p_{00} + f_x\,p_{01}, \quad \text{bottom} = (1-f_x)\,p_{10} + f_x\,p_{11}, \text{value} = (1-f_y)\,\text{top} + f_y\,\text{bottom}. This first blends horizontally along the top and bottom edges of the cell. It then blends those two results vertically. The result is smoother than nearest-neighbor sampling, though it softens sharp edges slightly, since it always averages.

Formula

The Perspective Divide

also known as: homogeneous-to-Cartesian conversion for a homography

A homography acts on homogeneous coordinates. Its bottom row need not be [0,0,1]: \begin{bmatrix}x_h\\y_h\\w\end{bmatrix} = \begin{bmatrix}h_{00}&h_{01}&h_{02}\\h_{10}&h_{11}&h_{12}\\h_{20}&h_{21}&h_{22}\end{bmatrix} \begin{bmatrix}x\\y\\1\end{bmatrix}. Dividing out the third coordinate recovers the actual point: (x',y') = (x_h/w,\ y_h/w). For an affine map, w always equals 1, so the divide is invisible. A homography's one defining trait is that w genuinely varies with (x,y).

Morphological image processing

Formula

Binary Erosion

also known as: A ⊖ B

Erosion of binary image A by structuring element B is written A\ominus B. It sets each output pixel p to foreground only if every foreground cell of B lands on a foreground pixel of A, once B's origin is aligned with p. If any aligned cell of B lands on background, or falls outside A's own bounds (also treated as background), the output at p is background. In short, p survives erosion only if B, placed with its origin at p, fits entirely inside A's foreground region. Shapes shrink inward from their own boundary, and anything smaller than B disappears completely.

Formula

Binary Dilation

also known as: A ⊕ B

Dilation of binary image A by structuring element B is written A\oplus B. It sets each output pixel p to foreground if at least one foreground cell of B lands on a foreground pixel of A, once B's origin is aligned with p. A structuring-element cell landing on background, or falling outside A's bounds, contributes nothing. Only if none of B's aligned foreground cells hit foreground does the output stay background. Shapes grow outward from their own boundary. They absorb small gaps and puff up thin or isolated features. Dilation is the set-theoretic mirror of erosion.

Formula

Morphological Opening and Closing

also known as: A ∘ B, A • B

Opening erodes a binary image A by structuring element B first, then dilates the result by the same B: A\circ B=(A\ominus B)\oplus B. Any foreground feature too small for B to fit inside vanishes in the erosion pass. It cannot come back in the dilation pass. A feature large enough to survive erosion has its original size restored. Closing runs the same two steps in the opposite order, A\bullet B=(A\oplus B)\ominus B. Small background gaps and notches smaller than B get filled during the dilation pass. They stay filled after the matching erosion, while the shape's overall size is otherwise preserved.

The frequency domain: 2D Fourier analysis for images

Formula

The 2D Discrete Fourier Transform

also known as: 2D DFT

For an H\times W image f(x,y), the 2D discrete Fourier transform is F(u,v) = \sum_{x=0}^{H-1}\sum_{y=0}^{W-1} f(x,y)\, e^{-j2\pi\left(\frac{ux}{H}+\frac{vy}{W}\right)}, \qquad u=0,\dots,H-1,\ v=0,\dots,W-1. Each F(u,v) is one complex number; a full H\times W image produces a full H\times W grid of them, no information lost or gained. The inverse DFT recovers the image exactly: f(x,y) = \frac{1}{HW}\sum_{u=0}^{H-1}\sum_{v=0}^{W-1} F(u,v)\, e^{+j2\pi\left(\frac{ux}{H}+\frac{vy}{W}\right)}. Because the exponential kernel factors as a product of a purely-x term and a purely-y term, the 2D sum separates into a 1D DFT along rows composed with a 1D DFT along columns.

Formula

Magnitude and Phase Spectrum

Every DFT value F(u,v) splits into a magnitude and a phase: |F(u,v)| = \sqrt{\operatorname{Re}(F(u,v))^2 + \operatorname{Im}(F(u,v))^2}, \qquad \angle F(u,v) = \operatorname{atan2}\big(\operatorname{Im}(F(u,v)),\ \operatorname{Re}(F(u,v))\big). The magnitude spectrum |F(u,v)| reports how much energy frequency (u,v) carries. That doesn't depend on where the pattern sits in the image. The phase spectrum \angle F(u,v) instead reports where that frequency component sits. Shifting a pattern sideways changes phase at every frequency it appears in, while leaving magnitude unchanged. Both are needed to rebuild the image exactly: magnitude alone or phase alone each discard real information.

Formula

The Convolution Theorem (2D DFT)

also known as: spatial convolution is frequency-domain multiplication

Convolving two images in the spatial domain is the same as pointwise multiplying their DFTs in the frequency domain. The correspondence runs both ways: f * g \;\Longleftrightarrow\; F(u,v)\cdot G(u,v), \qquad f\cdot g \;\Longleftrightarrow\; \frac{1}{HW}\,F * G. Concretely, \mathcal{F}\{f * g\} = F(u,v)\cdot G(u,v). Here F and G are the DFTs of f and the kernel g, both zero-padded to the same H\times W shape. This is the DFT's own circular convolution.

An H\times W image convolved with an H\times W kernel by direct summation costs O(H^2W^2) per output pixel. The same result via two O(HW\log HW) FFTs and one pointwise multiply is far cheaper for any kernel that isn't tiny. That speed is also what licenses designing a filter directly as a frequency-domain mask, instead of a spatial kernel.

Image restoration

Formula

The Image Degradation Model

also known as: blur-plus-noise model, PSF degradation model

A degraded image g is modeled as the clean image f passed through a point spread function (PSF) h by convolution, plus additive noise: g(x,y) = (h * f)(x,y) + n(x,y). By the convolution theorem, the frequency-domain form is G(u,v) = H(u,v)\, F(u,v) + N(u,v), where H(u,v), the PSF's own DFT, is the system's frequency response. The PSF is the system's own response to one infinitesimal point of light, treated as a spatial kernel. Knowing it tells you exactly how the system blurs any image at all. A full image is just a huge collection of points. Each one gets smeared into its own copy of that same blob, and every smeared copy adds together to form the blurred result.

Formula

Naive Inverse Filtering

Inverse filtering estimates a degraded image's clean spectrum by dividing the observed spectrum G by the system's own H, its frequency response: \hat F(u,v) = \frac{G(u,v)}{H(u,v)}. Set noise aside for a moment: this is exact. G=HF implies \hat F=G/H=F wherever H(u,v)\neq0. With real noise present, \hat F(u,v) = F(u,v) + \frac{N(u,v)}{H(u,v)}, so wherever H(u,v) is small, this division makes the noise term much bigger than it really is. Where H(u,v)=0 exactly, the formula is undefined, since it divides by zero. A bin that is only close to zero already produces a huge, noise-heavy value that looks nothing like the true F(u,v). Real point spread functions often have H values close to zero somewhere in the spectrum. That is why naive inverse filtering is unstable to use in practice, even though the formula itself is simple.

Formula

The Wiener Filter

The Wiener filter estimates a degraded image's clean spectrum as \hat F(u,v) = \frac{H^*(u,v)}{|H(u,v)|^2 + K}\, G(u,v), where H^* is H's complex conjugate (flip the sign of its imaginary part) and K\ge0 is a constant. In the fullest version, K is the noise-to-signal power ratio at that frequency; this course treats it as one tunable number instead. As K\to0: H^*/|H|^2=1/H, so this becomes naive inverse filtering exactly. As K grows large next to |H(u,v)|^2, the whole fraction shrinks toward 0 instead. That damps a shaky bin's answer toward zero, rather than splitting by a near-zero number. At a frequency where H is genuinely close to zero, |H|^2 is even closer, since it is squared. So K takes over the bottom of the fraction right there: exactly the bins naive inverse filtering blows up.

Segmentation

Formula

Otsu's Method

also known as: between-class variance thresholding

Otsu's method picks the threshold T that best separates a histogram into two classes, by maximizing the between-class variance \sigma_B^2(T) = w_0(T)\,w_1(T)\,\big(\mu_0(T)-\mu_1(T)\big)^2, where w_0,w_1 are the two classes' own population fractions (v\le T and v>T respectively) and \mu_0,\mu_1 their own mean intensities. Evaluating this at every candidate split and keeping the largest is exhaustive but cheap (at most 255 candidates for an 8-bit image), and requires nothing but the image's own histogram — no assumption about where the "right" cutoff should sit. Otsu's method still produces a single global threshold; it removes the guesswork from choosing T, not the uneven-lighting weakness of using one T for the whole image.

Formula

Adaptive (Local) Thresholding

Adaptive thresholding computes a different threshold at every pixel. Each threshold comes from that pixel's own local neighborhood: T(x,y) = \bar f_{N(x,y)} - C, Here \bar f_{N(x,y)} is the mean intensity over a small window centered at (x,y). C is a fixed constant, chosen ahead of time. Classification then works exactly like global thresholding: g(x,y)=255 if f(x,y)\le T(x,y), else 0.

A pixel's own value is always part of its own neighborhood's mean. That is why the rule uses \le rather than <. Only a pixel sitting meaningfully below its own surroundings, by more than C, ever gets flagged. This isolates one genuine local anomaly instead of an entire flat region. It stays correct under uneven lighting, a case where a single global threshold fails.

Color image processing

Formula

RGB-to-CMY(K) Conversion

CMY (cyan, magenta, yellow) is directly complementary to RGB. Normalizing R,G,B to [0,1] gives C = 1 - R, \qquad M = 1 - G, \qquad Y = 1 - B. CMYK adds a fourth channel, K (black), by pulling out the darkness that all three ink channels share: K = \min(C, M, Y), \qquad C' = \frac{C-K}{1-K}, \quad M' = \frac{M-K}{1-K}, \quad Y' = \frac{Y-K}{1-K} (with C'=M'=Y'=0 when K=1, to avoid a division by zero). K alone carries as much of the darkness as every channel shares. Mixing C=M=Y=1, full ink on all three channels, would otherwise make a muddy brown instead of a clean black. One black ink replaces that mixture, and C', M', Y' carry only the leftover color the black ink cannot supply.

Formula

RGB-to-HSV/HSL Conversion

Normalize R,G,B to [0,1] as r',g',b' and let C_{max}=\max(r',g',b'), C_{min}=\min(r',g',b'), \Delta=C_{max}-C_{min}. Hue (shared by HSV and HSL) is H = \begin{cases} 0 & \Delta = 0 \\ 60°\times\left(\dfrac{g'-b'}{\Delta}\bmod 6\right) & C_{max}=r' \\ 60°\times\left(\dfrac{b'-r'}{\Delta}+2\right) & C_{max}=g' \\ 60°\times\left(\dfrac{r'-g'}{\Delta}+4\right) & C_{max}=b' \end{cases} HSV sets V=C_{max} and S_{HSV}=0 if C_{max}=0 else \Delta/C_{max}. HSL instead sets L=(C_{max}+C_{min})/2 and S_{HSL}=0 if \Delta=0 else \Delta/(1-|2L-1|). The two disagree about "brightness": a pure, fully-saturated primary has V=100\% but L=50\%, since HSL reserves L=100\% for white alone.

Formula

RGB-to-YCbCr Conversion

also known as: ITU-R BT.601 luma/chroma

YCbCr separates luma (Y, a brightness-like weighted sum) from two chroma channels: C_b and C_r, the blue-difference and red-difference. The full-range ITU-R BT.601 form is Y = 0.299R + 0.587G + 0.114B, C_b = 128 + 0.564\,(B - Y), \qquad C_r = 128 + 0.713\,(R - Y). The 0.299/0.587/0.114 weights approximate human sensitivity to brightness, which peaks in green light and is weakest in blue light. The human visual system reads fine spatial detail in brightness far better than in color. Video and JPEG use that gap: they subsample chroma, storing C_b, C_r at lower resolution than Y. That step cuts data roughly in half with little visible loss, a trick with no equivalent in plain RGB.

Compression

Formula

The 2D Discrete Cosine Transform

also known as: DCT-II, JPEG transform

The 2D discrete cosine transform (DCT-II), for an N\times N block f(x,y), is F(u,v) = \frac{2}{N}\,C(u)\,C(v)\sum_{x=0}^{N-1}\sum_{y=0}^{N-1} f(x,y)\, \cos\!\left[\frac{(2x+1)u\pi}{2N}\right]\cos\!\left[\frac{(2y+1)v\pi}{2N}\right] with C(0)=\tfrac{1}{\sqrt2} and C(k)=1 for k>0. The inverse (IDCT) reconstructs f exactly from F using the same basis, run in reverse. Unlike the DFT, every F(u,v) is a single real number, with no magnitude/phase pair, since the cosine basis is real-valued. The DC coefficient F(0,0)=N\cdot\overline{f} is exactly N times the block's own mean. Every other, AC, coefficient measures how strongly the block matches a specific horizontal/vertical cosine "wiggle rate." A smooth block needs almost none of the fast-wiggling ones.

Formula

JPEG DCT Coefficient Quantization

JPEG quantization divides each DCT coefficient by its own quantization step and rounds to the nearest whole number. F_q(u,v) = \operatorname{round}\!\left(\frac{F(u,v)}{Q(u,v)}\right), \qquad \hat F(u,v) = F_q(u,v)\cdot Q(u,v). \hat F is the value actually used to rebuild the image, and it can be recovered exactly. F itself usually cannot. This is JPEG's first truly lossy step. The quantization matrix Q is weighted on purpose, to match human vision. Low-frequency entries are small: a fine step, little loss. High-frequency entries are large: a coarse step, more loss. Small coefficients often round straight down to 0.

Eigenimages, PCA, and optimization-based processing

Formula

PCA Reconstruction from Top-K Components

also known as: eigenimage reconstruction

Given a dataset's mean \bar{\mathbf x} and eigenpairs (\lambda_k,\mathbf v_k) of its covariance matrix, any image \mathbf x is approximately rebuilt from only its top K components: \hat{\mathbf x} = \bar{\mathbf x} + \sum_{k=1}^{K} c_k\mathbf v_k, \qquad c_k = \mathbf v_k^{\mathsf T}(\mathbf x-\bar{\mathbf x}). Each c_k is \mathbf x's own coordinate along eigenvector k. It is the projection of \mathbf x onto that one direction. At K=n, every eigenvector kept, \hat{\mathbf x}=\mathbf x exactly. That holds because the eigenvectors together span every direction in the space, each one at a right angle to all the rest.

At K<n, the squared error \lVert\mathbf x-\hat{\mathbf x}\rVert^2 equals exactly the sum of the discarded directions' own squared coordinates, \sum_{k=K+1}^n c_k^2. That is the reason K leading coefficients work as a compact stand-in for the whole image.

Formula

Total Variation

also known as: TV, TV denoising penalty

Total variation (TV) measures a signal's overall "roughness." It sums how big every pixel-to-pixel jump is, one at a time. In 1D, for a signal x of length n: \mathrm{TV}(x) = \sum_{i=1}^{n-1} |x_{i+1}-x_i|. The 2D version sums both horizontal and vertical jumps the same way: \sum_{r,c}|I(r,c{+}1){-}I(r,c)| + |I(r{+}1,c){-}I(r,c)|.

Using R(\mathbf x)=\mathrm{TV}(\mathbf x) as a penalty term gives TV denoising. TV does not square each jump, so a single large jump, a real edge, costs it only that jump's own size, never a much bigger, squared cost. That makes TV edge-preserving: it smooths away small wiggles, ordinary noise, while tolerating one genuine large jump instead of penalizing it away.

Formula

The Gradient Descent Update Rule

To search for a local minimum of a differentiable function f, starting from a point \mathbf{x}_0, repeat \mathbf{x}_{n+1} = \mathbf{x}_n - \alpha\,\nabla f(\mathbf{x}_n), where \alpha>0 is a fixed (or shrinking) learning rate. Each step moves from \mathbf{x}_n a small distance in the direction of steepest descent, -\nabla f(\mathbf{x}_n), and stops improving (to first order) once \nabla f(\mathbf{x}_n)\approx\mathbf{0}.

An introduction to computer vision

Formula

The Harris Corner Response

Around a candidate pixel, the structure tensor M=\sum_{(x,y)\in W}\begin{bmatrix}I_x^2 & I_xI_y\\ I_xI_y & I_y^2\end{bmatrix} is built from a window's own gradient products. Computing M's eigenvalues by hand takes more work than needed. The Harris and Stephens response function avoids it: R = \det(M) - k\,\operatorname{trace}(M)^2. Here, \det(M)=\lambda_1\lambda_2 and \operatorname{trace}(M)=\lambda_1+\lambda_2 combine M's two eigenvalues, and the constant k is chosen by hand, usually 0.04–0.06. This number, R, alone sorts the window into one of three classes. A positive R means both eigenvalues are large and close in size: a corner. A negative R means one eigenvalue is near zero: an edge. A small trace, regardless of R, means flat.

Formula

SSD and Normalized Cross-Correlation

also known as: template matching scores

Given a template T and a search image I, template matching scores each candidate position (u,v). It compares T to the image patch under it.

Sum of squared differences, \mathrm{SSD}(u,v) = \sum_{(x,y)\in T}\big(I(u+x,v+y)-T(x,y)\big)^2, is smallest, =0, at the best match.

Normalized cross-correlation, \mathrm{NCC}(u,v) = \frac{\sum(I-\bar I)(T-\bar T)}{\sqrt{\sum(I-\bar I)^2\sum(T-\bar T)^2}}, is largest, =1, at the best match instead. Both patches are mean-subtracted first, then scaled by their own sizes. Because of that, NCC recognizes a perfect structural match even under a uniform brightness offset, one that would inflate SSD by a lot.

Graph settings

Calculator