Fourier optics offers a robust analytical approach to understanding light propagation through optical systems by employing Fourier analysis techniques on optical fields. This framework elegantly connects image formation and optical resolution to the transmission of spatial information via light waves. Our exploration begins with examining complex transmittance functions, which give us fundamental insights into how various samples shape optical wavefronts. From this foundation, we will progress to the essential principles of Fourier optics and the associated diffraction integrals.
Transmission
When light interacts with an optical component or object, its amplitude and phase can be modified. Following Saleh and Teich’s formalism, we can characterize this interaction using the complex transmission factor \(t(x,y)\), which is defined as the ratio of the output field amplitude to the input field amplitude at each point \((x,y)\) in a plane:
This transmission factor is generally complex-valued, with its magnitude representing amplitude modulation and its phase representing phase modulation of the incident light.
For a thin lens, the primary effect is phase modulation. To derive the transmission function for a thin lens, we need to consider the optical path length through the lens at each point. Consider a planoconvex lens with one flat surface and one spherical surface of radius \(R\). The thickness of the lens varies with position according to:
\[d(x,y) = d_0 - \frac{(x^2+y^2)}{2R}\]
where \(d_0\) is the thickness at the center. As light passes through the lens, it experiences a phase delay proportional to the optical path length, which is the product of the refractive index \(n\) and the physical path length:
\[\phi(x,y) = k \cdot n \cdot d(x,y) - k \cdot d(x,y)_{\text{air}}\]
where \(k = 2\pi/\lambda\) is the wavenumber. Simplifying:
The first term represents a constant phase shift that we can ignore, and the second term gives us the position-dependent phase modulation. For a lens with focal length \(f\), the relationship between \(R\) and \(f\) is given by the lensmaker’s formula, which for a planoconvex lens simplifies to:
This quadratic phase factor represents the position-dependent phase delay introduced by the lens, with greater delays at the thicker portions of the lens.
Code
# Parameterswavelength =0.5# arbitrary unitsk =2*np.pi/wavelengthf =10# focal lengthx = np.linspace(-5, 5, 400)z = np.linspace(0, 15, 400)X, Z = np.meshgrid(x, z)# Calculate the phase profile at the lens (z=0)# Using positive sign to make the phase retardation largest at the center (x=0)lens_phase = k*(x**2)/(2*f)# Calculate the phase in the x-z plane after the lens# For each z position, the phase evolves according to the wave equationphase_xz = np.zeros_like(X)for i, z_val inenumerate(z):if z_val ==0:# At z=0, the phase is just the lens phase profile phase_xz[i,:] = lens_phaseelse:# After the lens, we model the converging wavefront# The phase at each point is approximately:# φ(x,z) = k*((x²/(2f)) - z) for a converging wave# Negative sign for z to represent forward propagation phase_xz[i,:] = k*((X[i,:]**2)/(2*f) - z_val)# Wrap phase to [-π,π] for visualizationphase_xz_wrapped = np.angle(np.exp(1j*phase_xz))# Create figure with two subplotsfig, ax = plt.subplots(1, 2, figsize=get_size(12,6))# Plot the phase profile at the lens (z=0)ax[0].plot(x, lens_phase)ax[0].set_xlabel('x')ax[0].set_ylabel('Phase [rad]')ax[0].set_title('Lens Phase Profile (z=0)')ax[0].grid(True)# Plot the phase in the x-z plane after the lensim = ax[1].imshow(phase_xz_wrapped, extent=[x.min(), x.max(), z.min(), z.max()], origin='lower', cmap='twilight', aspect='auto')ax[1].set_xlabel('x')ax[1].set_ylabel('z')ax[1].set_title('Wavefront Phase in x-z Plane')ax[1].axhline(y=f, color='r', linestyle='--', alpha=0.7)ax[1].text(x.max()-0.5, f+0.3, 'f', color='red')# Add a colorbarcbar = fig.colorbar(im, ax=ax[1], ticks=[-np.pi, 0, np.pi])cbar.set_label('Phase [rad]')cbar.ax.set_yticklabels(['-π', '0', 'π'])plt.tight_layout()plt.show()
Figure 1— Phase modulation effect of a thin lens on an incident plane wave. (a) The quadratic phase profile introduced by the lens at z=0. (b) The wavefront shape in the x-z plane after passing through the lens, showing how the initially flat wavefront is transformed into a converging spherical wavefront.
This transmission function is crucial in Fourier optics as it allows us to mathematically model how a lens transforms an incident field. When placed in the path of a light wave, the lens modifies the wavefront according to this transmission factor, effectively performing a spatial Fourier transform of the input field at its focal plane.
Generalization to Arbitrary Thickness Objects
For arbitrary thickness objects, we can extend our treatment beyond the thin-element approximation. When light propagates through a medium of varying thickness and refractive index, the transmission function becomes:
\[t(x,y) = A(x,y) e^{i\phi(x,y)}\]
where \(A(x,y)\) represents amplitude modulation (absorption or gain) and \(\phi(x,y)\) represents phase modulation. For a thick object, the phase shift is given by the path integral through the object:
\[\phi(x,y) = k \int_\text{path} [n(x,y,z) - n_0] dz\]
where \(n(x,y,z)\) is the spatially varying refractive index within the object, \(n_0\) is the refractive index of the surrounding medium, and the integration is performed along the light path through the object.
This formulation accounts for complex three-dimensional objects where both the thickness and the refractive index may vary with position. For inhomogeneous media, we can express the transmission function as:
\[t(x,y) = \exp\left[ -\frac{1}{2}\alpha(x,y) + i k\int_0^{d(x,y)} n(x,y,z)dz \right]\]
where \(\alpha(x,y)\) is the absorption coefficient integrated along the path, and \(d(x,y)\) is the thickness at position \((x,y)\).
For many practical applications, this can be approximated by considering the effective phase and amplitude changes, leading to the more manageable form:
\[t(x,y) = \tau(x,y) e^{i k(n-n_0)d(x,y)}\]
where \(\tau(x,y)\) is the amplitude transmission coefficient accounting for reflection and absorption losses.
This mathematical framework will become crucially important later when we describe image formation from waves that have propagated through an object. The transmission function directly encodes how an object modifies both the amplitude and phase of the incident light field, which determines how the object appears in an imaging system. Different imaging modalities (such as bright-field, phase-contrast, or differential interference contrast microscopy) essentially measure different aspects of this complex transmission function, revealing different properties of the object being imaged.
Wave Propagation Through Objects
When a plane wave propagating along the z-axis encounters an object, its wavefronts are modified according to the object’s transmission function. This section explores how different types of objects transform incident wavefronts, which is fundamental to understanding phenomena from simple refraction to complex wavefront shaping.
Code
# Parameterswavelength =0.5# arbitrary unitsk =2*np.pi/wavelengthx = np.linspace(-5, 5, 400)z = np.linspace(0, 15, 400)X, Z = np.meshgrid(x, z)# Create figure with four subplotsfig, ax = plt.subplots(2, 2, figsize=get_size(12,12))ax = ax.flatten()# (a) Plane wave in free space - flat wavefrontsphase_free_space = k*Zphase_free_space_wrapped = np.angle(np.exp(1j*phase_free_space))im1 = ax[0].imshow(phase_free_space_wrapped, extent=[x.min(), x.max(), z.min(), z.max()], origin='lower', cmap='twilight', aspect='auto')ax[0].set_xlabel('x')ax[0].set_ylabel('z')ax[0].set_title('(a) Free Space Propagation')# (b) Converging lens - spherical wavefrontsf =10# focal lengthlens_phase = np.zeros_like(X)for i, z_val inenumerate(z):if z_val <0.1: # At z=0, apply lens phase lens_phase[i,:] = k*(x**2)/(2*f)else:# After the lens, we model spherical wavefronts converging to focal point lens_phase[i,:] = k*((X[i,:]**2)/(2*f) - z_val)lens_phase_wrapped = np.angle(np.exp(1j*lens_phase))im2 = ax[1].imshow(lens_phase_wrapped, extent=[x.min(), x.max(), z.min(), z.max()], origin='lower', cmap='twilight', aspect='auto')ax[1].set_xlabel('x')ax[1].set_ylabel('z')ax[1].set_title('(b) Converging Lens')ax[1].axhline(y=f, color='r', linestyle='--', alpha=0.7)ax[1].text(x.max()-0.5, f+0.3, 'f', color='red')# (c) Prism - tilted wavefrontstilt_angle =10# degreesprism_phase = np.zeros_like(X)for i, z_val inenumerate(z):if z_val <0.1: # At z=0, apply linear phase (prism) prism_phase[i,:] = k*np.tan(np.deg2rad(tilt_angle))*xelse:# After the prism, wavefronts are tilted prism_phase[i,:] = k*(np.tan(np.deg2rad(tilt_angle))*x + z_val/np.cos(np.deg2rad(tilt_angle)))prism_phase_wrapped = np.angle(np.exp(1j*prism_phase))im3 = ax[2].imshow(prism_phase_wrapped, extent=[x.min(), x.max(), z.min(), z.max()], origin='lower', cmap='twilight', aspect='auto')ax[2].set_xlabel('x')ax[2].set_ylabel('z')ax[2].set_title('(c) Prism')# (d) Arbitrary phase object - custom wavefrontsdef arbitrary_phase(x):return2*np.sin(x) +0.5*np.sin(3*x)arb_phase = np.zeros_like(X)for i, z_val inenumerate(z):if z_val <0.1: # At z=0, apply arbitrary phase arb_phase[i,:] = k*arbitrary_phase(x)else:# After the object, wavefronts are deformed# This is a simplified model that propagates the phase deformation arb_phase[i,:] = k*(arbitrary_phase(x) + z_val)arb_phase_wrapped = np.angle(np.exp(1j*arb_phase))im4 = ax[3].imshow(arb_phase_wrapped, extent=[x.min(), x.max(), z.min(), z.max()], origin='lower', cmap='twilight', aspect='auto')ax[3].set_xlabel('x')ax[3].set_ylabel('z')ax[3].set_title('(d) Arbitrary Phase Object')# Add a colorbar for reference#cbar = fig.colorbar(im1, ax=ax, ticks=[-np.pi, 0, np.pi], orientation='horizontal', pad=0.02)#cbar.set_label('Phase [rad]')#cbar.ax.set_xticklabels(['-π', '0', 'π'])plt.tight_layout()plt.show()
Figure 2— Wavefront propagation after transmission through different optical elements. (a) A plane wave passing through free space maintains flat wavefronts. (b) After passing through a converging lens, the wavefronts become spherical, converging toward the focal point. (c) Transmission through a prism tilts the wavefronts, changing the propagation direction. (d) A phase plate with arbitrary phase profile creates custom-shaped wavefronts.
The wavefront visualizations above illustrate how different optical elements transform an incident plane wave:
Free Space Propagation: In the absence of any optical element, a plane wave maintains flat wavefronts perpendicular to the propagation direction.
Lens Effect: A converging lens introduces a quadratic phase modulation, transforming plane wavefronts into converging spherical wavefronts that focus at the focal point.
Prism Effect: A prism applies a linear phase gradient across the wavefront, tilting the wavefronts and changing the propagation direction according to Snell’s law.
Arbitrary Phase Objects: More complex phase profiles create correspondingly complex wavefront shapes, which can be designed for specific applications like wavefront correction or beam shaping.
Understanding these wavefront transformations is essential in optical system design, as the shape of the wavefront directly determines how light propagates through subsequent optical elements and ultimately forms images or interference patterns.
Spatial Frequencies and Angular Spectrum
Building on our analysis of wave propagation through various optical elements, we now explore a fundamental concept in Fourier optics that connects spatial patterns to wave propagation directions. This relationship between spatial structure and angular distribution is a direct extension of how different optical elements transform wavefronts, as visualized in the previous section. Just as a lens converts a plane wave into a converging spherical wave and a prism tilts the wavefront to change the propagation direction, complex spatial patterns decompose into multiple propagation directions—a relationship that will become essential when we discuss optical imaging systems, diffraction limits, and the resolution capabilities of microscopes and telescopes.
Code
# Load and display a sample image with different spatial frequenciesfrom PIL import Imageimport matplotlib.pyplot as pltimport numpy as np# Load image and convert to grayscaleimg = plt.imread('img/frank.png')iflen(img.shape) >2: img_gray = np.mean(img, axis=2) # Convert RGB to grayscaleelse: img_gray = img# Compute 2D FFTimg_fft = np.fft.fftshift(np.fft.fft2(img_gray))freq_x = np.fft.fftshift(np.fft.fftfreq(img_gray.shape[1]))freq_y = np.fft.fftshift(np.fft.fftfreq(img_gray.shape[0]))# Create figure for original image and its Fourier transformfig, ax = plt.subplots(1, 3, figsize=get_size(12, 5))# Display original imageax[0].imshow(img_gray, cmap='gray')ax[0].set_title('(a) Original Image')ax[0].set_axis_off()# Display 2D FFT magnitudeax[1].imshow(np.log(np.abs(img_fft) +1), cmap='viridis', extent=[freq_x.min(), freq_x.max(), freq_y.min(), freq_y.max()])ax[1].set_title('(b) Magnitude')ax[1].set_xlabel(r'$\nu_x$')ax[1].set_ylabel(r'$\nu_y$')ax[1].set_xticks([])ax[1].set_yticks([])# Display 2D FFT phaseax[2].imshow(np.angle(img_fft), cmap='twilight', extent=[freq_x.min(), freq_x.max(), freq_y.min(), freq_y.max()])ax[2].set_title('(c) Phase')ax[2].set_xlabel(r'$\nu_x$')ax[2].set_ylabel(r'$\nu_y$')ax[2].set_xticks([])ax[2].set_yticks([])plt.tight_layout()plt.show()
Figure 3— Spatial frequency analysis of an image. (a) Original grayscale image. (b) Magnitude of the 2D Fourier transform, showing the distribution of spatial frequencies. (c) Phase of the Fourier transform.
The Concept of Spatial Frequencies
Just as a temporal signal can be decomposed into frequency components through Fourier analysis, a spatial pattern or object can be represented as a superposition of spatial harmonic functions with different spatial frequencies. The spatial frequency \(\nu\) represents how rapidly the intensity or phase of an optical field changes with distance.
For a two-dimensional complex spatial harmonic function:
\[f(x,y) = A e^{i 2\pi(\nu_x x + \nu_y y)}\]
where:
\(\nu_x\) and \(\nu_y\) are the spatial frequencies in the x and y directions (in cycles per unit length)
\(A\) is the complex amplitude
Higher spatial frequencies correspond to finer details in an object, while lower spatial frequencies represent coarser features.
Overall, the function \(f(x,y)\) can be expressed as the Fourier transform of its spatial frequency components:
In optics, \(x\) typically represents spatial coordinates and \(k\) represents spatial frequencies. When working with discrete data, as you will in your computational exercises, you’ll use the Discrete Fourier Transform (DFT), which is efficiently computed using the Fast Fourier Transform (FFT) algorithm:
Code
import numpy as npfrom scipy import fftpack# Generate a simple signalx = np.linspace(0, 1, 1000) # spatial coordinatef = np.sin(2*np.pi*5*x) +0.5*np.sin(2*np.pi*10*x) # signal with 5 Hz and 10 Hz components# Compute the FFTF = fftpack.fft(f)freqs = fftpack.fftfreq(len(x), x[1]-x[0]) # frequency coordinates# For display, often use fftshift to center the zero frequencyF_shifted = fftpack.fftshift(F)freqs_shifted = fftpack.fftshift(freqs)# Plot the original signal and its spectrumplt.figure(figsize=get_size(12, 5))plt.subplot(121)plt.plot(x, f)plt.xlabel('position x')plt.ylabel('amplitude')plt.title('original signal')plt.subplot(122)plt.plot(freqs_shifted, np.abs(F_shifted))plt.xlabel('spatial frequency k')plt.ylabel('magnitude |F(k)|')plt.title('fourier spectrum')plt.xlim(-20, 20) # Zoom in on relevant frequenciesplt.tight_layout()plt.show()
This means the Fourier transform of a sum is the sum of the Fourier transforms, allowing us to analyze complex signals by breaking them into simpler components.
A shift in the spatial domain corresponds to a phase change in the frequency domain, critical for understanding how optical elements that cause phase shifts affect the spectrum.
Convolution in the spatial domain becomes multiplication in the frequency domain. This is particularly useful in optics, where the effect of a lens or aperture can be modeled as a convolution operation.
This theorem establishes energy conservation between domains, showing that the total energy in a signal is preserved in its Fourier transform.
Common Fourier Transform Pairs
Function
Fourier Transform
\(\delta(x)\) (Delta function)
\(1\) (constant)
\(1\) (constant)
\(\delta(k)\) (Delta function)
\(\text{rect}(x)\) (Rectangle function)
\(\text{sinc}(k)\) (Sinc function)
\(e^{-\pi x^2}\) (Gaussian)
\(e^{-\pi k^2}\) (Gaussian)
\(\cos(2\pi ax)\)
\(\frac{1}{2}[\delta(k-a) + \delta(k+a)]\)
Understanding these transform pairs is essential for optical analysis. For example, a rectangular aperture produces a sinc-function diffraction pattern, and a Gaussian beam maintains its Gaussian profile under propagation.
Code
# Demonstrate the rect-sinc transform pairdef rect(x, width=1.0):return np.where(np.abs(x) <= width/2, 1.0, 0.0)def sinc(k):# Handle the case where k=0 directly to avoid division by zero warning result = np.ones_like(k, dtype=float) non_zero = k !=0 result[non_zero] = np.sin(np.pi * k[non_zero]) / (np.pi * k[non_zero])return result# Create a rectangular functionx_fine = np.linspace(-5, 5, 1000)rect_func = rect(x_fine, width=2.0)# Calculate its Fourier transformrect_ft = fftpack.fftshift(fftpack.fft(rect_func))k_values = fftpack.fftshift(fftpack.fftfreq(len(x_fine), x_fine[1]-x_fine[0]))# Also plot the analytical sinc function for comparisontheoretical_sinc =2.0* sinc(2.0*k_values)plt.figure(figsize=get_size(12, 5))plt.subplot(121)plt.plot(x_fine, rect_func)plt.xlabel('position x')plt.title('rectangle function')plt.subplot(122)plt.plot(k_values, np.abs(rect_ft)/np.max(np.abs(rect_ft)), 'b-', label='FFT Result')plt.plot(k_values, np.abs(theoretical_sinc), 'r--', label='Theoretical Sinc')plt.xlabel('spatial frequency k')plt.xlim(-2, 2)plt.tight_layout()plt.show()
Correspondence to Plane Wave Angular Components
One of the most profound insights in Fourier optics is the relationship between spatial frequencies and the angular spectrum of plane waves. To understand this relationship, consider a plane wave \(U(x,y,z)\) with wavevector \(\mathbf{k}\) and wavelength \(\lambda\) incident on the plane \(z=0\). The wavevector can be written as:
where \(|\mathbf{k}| = 2\pi/\lambda\). The components of this wavevector can be expressed in terms of the propagation angles \(\theta_x\) and \(\theta_y\) (with respect to the \(z\)-axis):
where \(\cos\theta_z = \sqrt{1-\sin^2\theta_x-\sin^2\theta_y}\) from the constraint that \(|\mathbf{k}| = 2\pi/\lambda\).
Figure 4— Principle of plane wave angular decomposition. (Image taken from Saleh/Teich “Principles of Photonics”)
At the plane \(z=0\), this plane wave can be represented as:
\[U(x,y,0) = U_0 e^{j(k_x x + k_y y)}\]
where \(k_x/2\pi\) and \(k_x/2\pi\) are the spatial frequencies of the plane wave along the x- and y direction. This equation shows that a plane wave propagating at angles \(\theta_x\) and \(\theta_y\) manifests as a spatial harmonic function at the \(z=0\) plane, with spatial frequencies directly related to the propagation angles:
We can match now the spatial frequencies of the object \(f(x,y)\) to the plane wave \(U(x,y,0)\) by adjusting the wavevector angles \(\theta_x, \theta_y\) to yield the same periodicity.
This means each spatial frequency of the sample \(f(x,y)\) is diffracting the incident plane wave \(U(x,y,z)\) into a certain angle, when the frequencies are matched. Behind the sample, the plane wave is propagating further without any change with the additional phase factor \(e^{-i k_z z}\) such that
This expression for \(k_z\) shows how the propagation along the z-direction depends on the spatial frequencies in the x and y directions. This relationship provides a direct connection between the spatial structure of an object and the directions in which light propagates after interacting with it.
Spatial Frequency and Propagation Angles of a Grating
We saw this principle in action when analyzing diffraction gratings, where we decomposed the grating’s periodic structure into angular components using the grating vector. For a grating with period \(d\), the spatial frequency is \(\nu_x = 1/d\), and the directions of diffracted orders are given by:
\[\sin\theta_m = m\lambda/d = m\lambda\nu_x\]
where \(m\) is the diffraction order. This shows how the grating’s spatial frequency determines the angles of diffracted light, which is a specific application of the more general Fourier relationship between spatial frequencies and propagation angles.
Code
# Create a 2D object with a single spatial frequency in the x directionx = np.linspace(-5, 5, 400)y = np.linspace(-5, 5, 400)X, Y = np.meshgrid(x, y)# Define the spatial frequencyspatial_freq =1.0# cycles per unit lengthwavelength =0.5# arbitrary units# Create the sinusoidal pattern objectobject_pattern = np.cos(2* np.pi * spatial_freq * X)# Calculate the corresponding diffraction anglediffraction_angle = np.rad2deg(np.arcsin(wavelength * spatial_freq))# Calculate the 1D FFT of a single row of the object (at y=0)row_index =len(y) //2# Middle rowobject_row = object_pattern[row_index, :]ft_1d = np.fft.fftshift(np.fft.fft(object_row))ft_magnitude_1d = np.abs(ft_1d)# Create frequency axis for the 1D Fourier transformfx = np.fft.fftshift(np.fft.fftfreq(len(x), x[1]-x[0]))# Calculate the corresponding diffraction anglestheta_x = np.rad2deg(np.arcsin(np.clip(wavelength * fx, -1, 1)))# Create a figure with 3 subplotsfig, axs = plt.subplots(1, 3, figsize=get_size(12, 4))# Plot the object pattern (2D image)im0 = axs[0].imshow(object_pattern, extent=[x.min(), x.max(), y.min(), y.max()], cmap='gray', origin='lower')axs[0].set_xlabel('x ')axs[0].set_ylabel('y ')#fig.colorbar(im0, ax=axs[0], label='Amplitude')# Plot the spatial frequency spectrum (1D line plot)axs[1].plot(fx, ft_magnitude_1d)axs[1].set_xlabel(r'$\nu_x$')axs[1].set_ylabel('magnitude')axs[1].set_xlim(-3, 3)axs[1].grid(True)axs[1].axvline(x=spatial_freq, color='r', linestyle='--', alpha=0.7)axs[1].axvline(x=-spatial_freq, color='r', linestyle='--', alpha=0.7)axs[1].text(spatial_freq, 0.7*np.max(ft_magnitude_1d), f"+νₓ", color='red', ha='left')axs[1].text(-spatial_freq, 0.7*np.max(ft_magnitude_1d), f"-νₓ", color='red', ha='right')# Plot the angular spectrum representation (1D line plot)# Only display points where |fx| < 1/wavelength (propagating waves)valid_indices = np.abs(fx) <=1/wavelengthaxs[2].plot(theta_x[valid_indices], ft_magnitude_1d[valid_indices])axs[2].set_xlabel(r'$\theta_x$[°]')axs[2].set_ylabel('magnitude')axs[2].grid(True)axs[2].axvline(x=diffraction_angle, color='r', linestyle='--', alpha=0.7)axs[2].axvline(x=-diffraction_angle, color='r', linestyle='--', alpha=0.7)axs[2].text(diffraction_angle, 0.7*np.max(ft_magnitude_1d[valid_indices]), f"+θ", color='red', ha='left')axs[2].text(-diffraction_angle, 0.7*np.max(ft_magnitude_1d[valid_indices]), f"-θ", color='red', ha='right')plt.tight_layout()plt.show()
Figure 5— Visualization of a 2D object containing a single spatial frequency in the x-direction. (a) The object pattern showing sinusoidal variation along x with frequency νₓ. (b) The Fourier transform magnitude of the object, showing two symmetric points corresponding to ±νₓ. (c) The corresponding angular spectrum representation, where the spatial frequency νₓ maps to specific diffraction angles ±θ according to sin(θ) = λνₓ.