Fourier Analysis - CFAImageFourier

2D FFT spectrum analysis, filtering, and image reconstruction for grayscale and RGB images

Application Scenarios

Usage Examples

Basic Usage

import cv2, numpy as np from FreeAeonFractal.FAImageFourier import CFAImageFourier image = cv2.imread('./images/face.png') fourier = CFAImageFourier(image) # FFT computed here raw_mag, raw_phase = fourier.get_raw_spectrum() # for reconstruction mag_disp, phase_disp = fourier.get_display_spectrum(alpha=1.5) # for display full_reconstructed = fourier.get_reconstruct() fourier.plot( raw_magnitude_disp=mag_disp, raw_phase_disp=phase_disp, full_reconstructed=full_reconstructed )

Frequency Domain Filtering with Custom Mask

h, w = raw_mag[0].shape Y, X = np.ogrid[:h, :w] # Keep only odd-frequency components (example mask) mask = ((X % 2 == 1) & (Y % 2 == 1)).astype(np.uint8) customized_mag = raw_mag * mask customized_phase = raw_phase * mask custom_mag_disp, custom_phase_disp = fourier.get_display_spectrum( alpha=1.5, magnitude=customized_mag, phase=customized_phase) masked_reconstructed = fourier.extract_by_freq_mask(mask) fourier.plot( raw_magnitude_disp=mag_disp, raw_phase_disp=phase_disp, customized_magnitude_disp=custom_mag_disp, customized_phase_disp=custom_phase_disp, full_reconstructed=full_reconstructed, mask_reconstructed=masked_reconstructed )

Low-pass Filter (smooth)

cy, cx = h // 2, w // 2 radius = 30 Y, X = np.ogrid[:h, :w] mask = ((X - cx)**2 + (Y - cy)**2 <= radius**2).astype(np.uint8) result = fourier.extract_by_freq_mask(mask)

Class Description

CFAImageFourier

Fourier analysis for grayscale or RGB images. 2D FFT computed at initialization. Supports decomposition, visualization, reconstruction, and custom frequency masking.

__init__(image)

image: Grayscale (H,W) or RGB (H,W,3). FFT is computed immediately; for grayscale one pair is stored, for RGB three channel pairs are stored.

get_raw_spectrum()

Returns (magnitude_list, phase_list) — raw (not log-scaled). Use these for reconstruction, not the display versions.

get_display_spectrum(alpha=1.0, beta=0, magnitude=array([]), phase=array([]))

Returns (display_mag, display_phase) — log-scaled 8-bit visualization. Pass custom magnitude/phase to visualize masked spectra.

get_reconstruct(magnitude=array([]), phase=array([]))

IFFT(IFFTSHIFT(mag * exp(1j * phase))), normalized to [0,255]. Returns uint8 image.

extract_by_freq_mask(mask_mag=array([]), mask_phase=array([]))

Apply binary mask to frequency domain, then reconstruct. Shape: same as frequency map (H,W).

plot(...)

Side-by-side 2-row grid: original, raw magnitude, raw phase, customized magnitude, customized phase, full reconstruction, masked reconstruction.

get_image_components(image) [static]

Returns (magnitude, phase) for a single-channel image using 2D FFT + fftshift.

normalize_and_enhance(array, alpha=1.0, beta=0) [static]

Normalize to [0,255] and apply linear contrast scaling. Returns uint8.

Algorithm

Forward FFT Pipeline

F = np.fft.fft2(image) F_shift = np.fft.fftshift(F) # DC to center magnitude = |F_shift| phase = angle(F_shift)

Reconstruction Pipeline

F_shift = magnitude * exp(1j * phase) F = np.fft.ifftshift(F_shift) img = Re(np.fft.ifft2(F)) # take real part img = normalize(img) to [0, 255]

Display Enhancement

display = normalize(log(1 + |magnitude|)) # log-scale phase_disp = normalize((phase + π) / (2π)) # shift to [0,1]

Important Notes

  1. Input: Only 2D grayscale or 3D RGB supported; others raise ValueError
  2. Raw vs Display: Use get_raw_spectrum() for reconstruction; display version is log-scaled
  3. Mask: Shape must match frequency map (H,W); 0=zero out, 1=keep
  4. RGB: Independent FFT per channel; reconstruction merges channels with cv2.merge

References