
Lecture 5
Computer Science Department, Colorado School of Mines
By the end of this lecture, you should be able to:
Distinguish Fourier series, and the discrete Fourier transform (DFT)
Interpret amplitude, phase, and frequency locations in an image spectrum.
Predict how image structure, translation, rotation, and scale affect the Fourier transform.
Reconstruct images from selected complex coefficients and explain the connection to compression.
Apply the convolution theorem to image filtering, including our correlation convention.
Explain aliasing using the Nyquist condition and choose low-pass filtering before downsampling.

Can we build a complicated signal from simple waves?
Joseph Fourier (1768–1830)
The Fourier series claim (1807):
Any univariate function can be rewritten as a weighted sum of sines and cosines of different frequencies.
Malus
Lagrange
Legendre
Laplace
The initial reviewers (Lagrange, Laplace, Monge, and Lacroix) were skeptical, partly because the proofs lacked rigor. Publication of his work was initially withheld.
The later committee, which included Lagrange, Laplace, Malus, and Legendre, awarded Fourier a prize but criticized the generality and rigor of his analysis.
Well, almost.
The theorem requires additional conditions:
Very surprising result at the time, because it implied that
Joseph Fourier
A sinusoid:
\[ A\sin(\omega x + \phi) \]
\(A\): amplitude — controls the height of the oscillations.
\(\omega\): angular frequency — controls how rapidly the signal oscillates.
\(\phi\): phase — shifts the wave horizontally.
\(x\): variable — for example, time or spatial position.
Fourier’s idea: Build a periodic signal by adding sinusoids with different frequencies, amplitudes, and phases:
\[ y(x) = c_0 + \sum_{k=1}^{\infty} A_k \sin(2\pi k f_0 x + \phi_k) \]
How would you generate this function?



\[ y(x) = \sin(2\pi x) + \frac{1}{3}\sin(6\pi x) \]
How would you generate this function?


\[ \frac{4}{\pi} \left[ \sin(2\pi x) + \frac{1}{3}\sin(6\pi x) \right] \]
What happens if we add higher-frequency sinusoids?
Add the next harmonic at each step:

How would you express this mathematically?

General Fourier series:
\[ y(x) = c_0 + \sum_{k=1}^{\infty} A_k \sin(2\pi k f_0 x + \phi_k) \]
For this square wave, \(c_0=0\) and \(f_0=1\):
\[ y(x) = \sum_{\substack{k=1\\k\text{ odd}}}^{\infty} \frac{4}{k\pi}\sin(2\pi kx) \]



\[ y_6(x) = \frac{4}{\pi}\sin(2\pi x) + \frac{4}{3\pi}\sin(6\pi x) + \frac{4}{5\pi}\sin(10\pi x) + \frac{4}{7\pi}\sin(14\pi x) + \frac{4}{9\pi}\sin(18\pi x) + \frac{4}{11\pi}\sin(22\pi x) \]
Each sinusoid produces two peaks at frequencies \(\pm f\). Matching colors connect each sinusoid to its peaks.
The black curve in the middle shows the six-term sum; the ideal square wave requires infinitely many terms.
\[ f(x) = c_0 + \sin(2\pi x) + \frac{1}{3}\sin(6\pi x), \qquad c_0 = 1 \]



The constant \(c_0\) shifts the signal vertically without changing its oscillations.
How does each term appear in the frequency domain?


A sinusoid of amplitude \(A\) produces two peaks, each of height \(A/2\), at its positive and negative frequencies.


The DC component represents the signal’s mean value.
\[ c_0 = \frac{1}{N}\sum_{n=0}^{N-1} f(x_n) = 1 \]
The constant contributes one peak at zero frequency, with magnitude \(|c_0|\). It is not split into two peaks.
For images, the DC component corresponds to the average pixel intensity.
Repeat the same 1D intensity signal along every image row.


What do the three bright spots represent?
What changes when the stripes become narrower?


Does the Fourier intensity change along \(x\), along \(y\), or both?


Both. The sinusoid varies along a diagonal direction.
What happens when we average these two images?



Fourier series represent periodic signals as sums of sinusoids.


Fourier series
How can we represent a signal that does not repeat?
Spatial domain: \(f(x)\)

Frequency domain: \(\operatorname{Re}\{F(\nu)\}\)

A complex number has two parts:
\[ z = a + jb, \qquad j^2=-1 \]
For example:
\[ z=3+j4 \]
The point has coordinates \((a,b)=(3,4)\) in the complex plane.

Describe the same point using its distance and angle:
\[ z = r(\cos\theta + j\sin\theta) \]
How do we compute \(r\) and \(\theta\)?
\[ r = |z| = \sqrt{a^2+b^2} \]
\[ \theta = \operatorname{atan2}(b,a) \]
atan2 accounts for the correct quadrant.
For \(z=3+j4\):
\[ r=5, \qquad \theta\approx53.13^\circ \]

Same complex number, different coordinates: \((a,b)\) or \((r,\theta)\).
Euler’s formula:
\[ e^{j\theta} = \cos\theta + j\sin\theta \]
Therefore:
\[ z = r(\cos\theta+j\sin\theta) = re^{j\theta} \]
For our example, \(\theta\approx0.9273\) radians:
\[ 3+j4 \approx 5e^{j\,0.9273} \]

Euler’s formula lets us express the sine and cosine components of the Fourier transform using complex exponentials.
For a sampled signal \(f[n]\) containing \(N\) samples:
Discrete Fourier transform (DFT)
\[ F[k] = \frac{1}{N} \sum_{n=0}^{N-1} f[n]e^{-j2\pi kn/N} \]
Inverse DFT
\[ f[n] = \sum_{k=0}^{N-1} F[k]e^{j2\pi kn/N} \]
Where is the connection to our “ \(f[n]\) is a sum of sine waves” idea?
Recall Euler’s formula:
\[ e^{j\theta} = \cos\theta + j\sin\theta \]
Substitute it into the inverse DFT:
\[ f[n] = \sum_{k=0}^{N-1} F[k]e^{j2\pi kn/N} = \sum_{k=0}^{N-1} F[k] \left[ \cos\left(\frac{2\pi kn}{N}\right) + j\sin\left(\frac{2\pi kn}{N}\right) \right] \]
For an image \(I[m,n]\) with \(M\) rows and \(N\) columns:
Forward: image to frequency coefficients
\[ F[v,u] = \sum_{m=0}^{M-1}\sum_{n=0}^{N-1} I[m,n]\, e^{-j2\pi\left(\frac{vm}{M}+\frac{un}{N}\right)} \]
Inverse: frequency coefficients to image
\[ I[m,n] = \frac{1}{MN} \sum_{v=0}^{M-1}\sum_{u=0}^{N-1} F[v,u]\, e^{j2\pi\left(\frac{vm}{M}+\frac{un}{N}\right)} \]

A 1D DFT computes a weighted sum for each frequency:
\[ F[k] = \sum_{n=0}^{N-1} f[n]\, \underbrace{e^{-j2\pi kn/N}}_{\text{weight for sample }n} \]
Collect these weights into a matrix:
\[ W_N[k,n]=\omega^{kn}, \qquad \omega=e^{-j2\pi/N} \]
\[ \begin{bmatrix} F[0]\\ F[1]\\ \vdots\\ F[N-1] \end{bmatrix} = \underbrace{ \begin{bmatrix} 1 & 1 & \cdots & 1\\ 1 & \omega & \cdots & \omega^{N-1}\\ \vdots & \vdots & \ddots & \vdots\\ 1 & \omega^{N-1} & \cdots & \omega^{(N-1)^2} \end{bmatrix} }_{\mathbf{W}_N} \begin{bmatrix} f[0]\\ f[1]\\ \vdots\\ f[N-1] \end{bmatrix} \]
Each row of \(\mathbf{W}_N\) computes one frequency coefficient:
\[ \mathbf{F}=\mathbf{W}_N\mathbf{f} \]
The FFT computes this same DFT efficiently, without explicitly building large DFT matrices.
For our \(3\times3\) image, set \(N=3\) in the DFT matrix:
\[ \mathbf{W}_3 = \begin{bmatrix} 1 & 1 & 1\\ 1 & \omega & \omega^2\\ 1 & \omega^2 & \omega \end{bmatrix}, \qquad \omega=e^{-j2\pi/3} \]
Here \(\omega^3=1\), so \(\omega^4=\omega\).
\[ \underbrace{\mathbf{B}=\mathbf{I}\mathbf{W}_3^T} _{\text{Transform each row}} \qquad \underbrace{\mathbf{F}=\mathbf{W}_3\mathbf{B}} _{\text{Transform each column}} \]

These are the same Fourier coefficients as before, computed using row and column transforms.
At each frequency, the same coefficient has two representations:
Cartesian form:
\[ F=a+jb \]
Polar form:
\[ F=Ae^{j\theta} \]

Magnitude and phase together retain the information needed for reconstruction.
import cv2
import numpy as np
import matplotlib.pyplot as plt
I = cv2.imread("assets/05_fourier_transform/co_logo.png",
cv2.IMREAD_GRAYSCALE)
I = cv2.resize(I, (64, 64), interpolation=cv2.INTER_AREA)
I = I.astype(np.float32) / 255
H, W = I.shape
F_raw = cv2.dft(I, flags=cv2.DFT_COMPLEX_OUTPUT)
F = np.roll(F_raw, (H//2, W//2), axis=(0, 1))
a, b = F[:, :, 0], F[:, :, 1]
A, theta = cv2.cartToPolar(a, b)
theta = np.where(theta > np.pi, theta - 2*np.pi, theta)
theta[A == 0] = np.nan
# Compress contrast for display only.
real_view = np.sign(a) * np.log1p(np.abs(a))
imag_view = np.sign(b) * np.log1p(np.abs(b))
L = max(np.abs(real_view).max(), np.abs(imag_view).max())
views = [I, real_view, imag_view, np.log1p(A), theta]
titles = ["Image", "Real (signed log)", "Imaginary (signed log)",
"Magnitude (log)", "Phase"]
limits = [(0, 1), (-L, L), (-L, L), (0, None), (-np.pi, np.pi)]
fig, ax = plt.subplots(2, 3, figsize=(8.2, 6))
for axis, view, title, (lo, hi) in zip(ax.flat, views, titles, limits):
axis.imshow(view, cmap="gray", vmin=lo, vmax=hi,
interpolation="nearest")
axis.set_title(title, fontsize=14)
axis.axis("off")
ax.flat[-1].axis("off")
fig.tight_layout()
plt.show()
plt.close(fig)
OpenCV stores the zero-frequency coefficient at the upper-left corner.
For visualization, the convention is to move it to the center.

How do these images appear in the spectrum?

What frequencies are needed to represent each image?

A horizontal line is constant horizontally, but changes sharply vertically.

Along the line
There is no horizontal variation.
Only the horizontal frequency \(u=0\) is needed.
Across the line
A one-pixel change requires all vertical frequencies.
The spectrum extends along the \(v\) axis.
A horizontal line produces a vertical line in the Fourier magnitude.
A regular grid of bright pixels is called an impulse train or impulse comb.

Move the square without changing its shape or brightness.

Compare the same shape at two different sizes.

The spectrum follows the orientation of the image.

Match images A–H to the centered DFT amplitudes 1–8.

Explain your matches using frequency spread, orientation, and repeated patterns.

The inverse DFT reconstructs the image:
\[ I = \mathcal{F}^{-1}(F). \]
What if we retain only some coefficients?
\[ \widehat{I}_K = \mathcal{F}^{-1}(M_K \odot F) \]
Here, \(M_K\) is a binary mask selecting \(K\) coefficients.
Which selection works better: random frequencies or frequencies near the center?

Only DC remains: every pixel equals the original image’s mean intensity.
White pixels in the mask mark retained coefficients; black pixels mark discarded coefficients.















With all coefficients retained, the inverse DFT recovers the original image.
Can we obtain a useful reconstruction with far fewer coefficients?

Start with DC, then expand outward to include progressively higher frequencies.
We will use the same coefficient counts as before.







The scene is already recognizable using about 4.2% of the coefficients.








Both methods reach the same exact reconstruction when all coefficients are retained.

Compression idea: retain informative transform coefficients and encode them efficiently.

Each pixel is drawn independently from a uniform distribution between \(0\) and \(1\).

Keeping only low frequencies captures natural-image structure much better than random pixel detail.
Natural images often concentrate energy at low frequencies.
Are our eyes equally sensitive to all spatial frequencies?
Where do you see the stripes?


We typically detect lower contrast at intermediate spatial frequencies than at very low or very high frequencies.
Note: The curve illustrates the trend. Actual visibility depends on viewing distance, lighting, and the display.
A filter changes how strongly different spatial frequencies contribute to an image.
The convolution theorem
Let \(F=\mathcal{F}\{I\}\) and \(H=\mathcal{F}\{h\}\).
\[ y = I * h \qquad \Longleftrightarrow \qquad Y = FH \]
Therefore,
\[ \boxed{y=\mathcal{F}^{-1}\{FH\}} \]
Note
For the DFT, sufficient zero-padding may be needed. The DFT assumes the input is periodic. Zero-padding ensures that the filter does not wrap around and affect the opposite edge of the image.
In Lecture 3, we used
\[ y[m,n] = \sum_k\sum_l h[k,l]\,I[m+k,n+l]. \]
This is correlation, as implemented by cv2.filter2D().
For our real-valued kernels:
| Spatial operation | Frequency-domain operation |
|---|---|
| Convolution with \(h\) | \(Y=FH\) |
| Correlation with \(h\) | \(Y=F\overline{H}\) |
Here, \(\overline{H}\) is the complex conjugate of \(H\).
\[ y=\operatorname{corr}(I,h) \qquad \Longleftrightarrow \qquad Y=F\overline{H} \]

The Sobel x filter suppresses constant regions and responds to horizontal intensity changes, emphasizing vertical edges.
The spectrum’s dimensions are determined by the DFT grid—not by the number of kernel entries.
For an \(M\times N\) image and a \(P\times Q\) kernel, a sufficient grid size is
\[ (M+P-1)\times(N+Q-1). \]
| In the last example | Array size |
|---|---|
| Original image | \(128\times128\) |
| Sobel kernel | \(3\times3\) |
| Padded image and padded kernel | \(130\times130\) |
| Both DFTs | \(130\times130\) |
Both filters average neighboring pixels. Why do their results look different?

Their Fourier transforms reveal which frequencies each filter preserves or suppresses.


Match frequency-domain filters A–D to output images 1–4.
White passes frequencies; black removes them.

Which filters retain broad structures, intermediate details, or the finest texture?
A band-limited signal with highest frequency \(f_{\max}\) can be reconstructed from ideal samples when
\[ \boxed{f_s > 2f_{\max}} \]
| Term | Meaning |
|---|---|
| Nyquist rate: \(2f_{\max}\) | Sampling-rate threshold determined by the signal |
| Nyquist frequency: \(f_s/2\) | Frequency limit determined by the sampling rate |
What happens when we downsample an image?
Downsampling by 4 lowers the frequency limit to \(1/8\) cycle per original pixel in each direction.

Both downsampled images keep every fourth row and column.

Losing detail is preferable to inventing a different pattern.
Fourier representation: an image can be expressed as a weighted combination of spatial waves.
Amplitude and phase: amplitude describes each component’s strength; phase determines its alignment. Reconstruction requires both.
Reconstruction and compression: selected coefficients can capture much of an image’s structure; discarded coefficients represent lost information.
Filtering: convolution uses \(Y=FH\); correlation with our real-valued kernels uses \(Y=F\overline{H}\). Padding and kernel alignment matter.
Sampling: retain frequencies below the new Nyquist limit. Low-pass filtering must happen before downsampling.
Computer Vision; Colorado School of Mines | Kaveh Fathian