Filtrage d'Images dans le Domaine Fréquentiel et Transformée de Fourier

Introduction aux Domaines Spatial et Fréquentiel

En traitement du signal, le théorème de Fourier établit que tout signal périodique peut être décomposé en une somme de fonctions sinusoïdales. Appliqué aux images numériques, ce principe permet de relier la notion de fréquence à la variation spatiale des niveaux de gris.

Le domaine spatial fait référence à la matrice de pixels elle-même, où les opérations sont effectuées directement sur les valeurs des pixels en fonction de leurs coordonnées spatiales. À l'inverse, le domaine fréquentiel représente l'image sous forme de spectre, décomposant les variations d'intensité en différentes composantes sinusoïdales caractérisées par leur amplitude, leur fréquence spatiale et leur phase.

La transition entre ces deux domaines s'effectue via la Transformée de Fourier Discrète (TFD) bidimensionnelle. Le processus de filtrage fréquentiel suit généralement trois étapes :

  1. Application de la TFD pour convertir l'image du domaine spatial au domaine fréquentiel.
  2. Multiplication du spectre par une fonction de transfert (le filtre) pour atténuer ou amplifier certaines fréquences.
  3. Application de la Transformée de Fourier Inverse (TFDI) pour revenir au domaine spatial.

Signification Physique de la Transformée de Fourier

La fréquence dans une image mesure le taux de variation de l'intensité lumineuse. Les zones uniformes correspondent à de basses fréquences, tandis que les contours et les textures détaillées génèrent de hautes fréquences.

Après la transformation, le spectre est généralement recentré pour placer la composante continue (fréquence nulle) au centre de l'image. Ainsi, le centre représente les basses fréquences, et la périphérie les hautes fréquences.

import cv2
import numpy as np
import matplotlib.pyplot as plt

def analyze_frequency_spectrum(image_path):
    # Chargement de l'image en niveaux de gris
    img = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
    
    # Transformation de Fourier 2D et décalage du spectre
    fourier_transform = np.fft.fft2(img)
    shifted_spectrum = np.fft.fftshift(fourier_transform)
    
    # Calcul du spectre d'amplitude (échelle logarithmique pour la visualisation)
    magnitude_spectrum = np.log1p(np.abs(shifted_spectrum))
    
    # Affichage
    fig, axes = plt.subplots(1, 3, figsize=(12, 4))
    axes[0].imshow(img, cmap='gray')
    axes[0].set_title("Image Originale")
    axes[1].imshow(np.log1p(np.abs(fourier_transform)), cmap='gray')
    axes[1].set_title("Spectre (Non centré)")
    axes[2].imshow(magnitude_spectrum, cmap='gray')
    axes[2].set_title("Spectre Centré")
    
    for ax in axes:
        ax.axis('off')
    plt.show()

# Exemple d'utilisation
# analyze_frequency_spectrum('sample_image.jpg')

Étapes du Filtrage Fréquentiel

Le processus mathématique de filtrage dans le domaine fréquentiel peut être résumé ainsi :

  1. Soit \( f(x,y) \) l'image d'entrée.
  2. Calcul de la TFD : \( F(u,v) = \mathcal{F}\{f(x,y)\} \).
  3. Recentrage du spectre.
  4. Application du filtre \( H(u,v) \) : \( G(u,v) = H(u,v) \cdot F(u,v) \).
  5. Recentrage inverse.
  6. Calcul de la TFDI pour obtenir l'image filtrée : \( g(x,y) = \mathcal{F}^{-1}\{G(u,v)\} \).

Conception des Filtres Fréquentiels

Les filtres sont classés selon les bandes de fréquences qu'ils laissent passer ou qu'ils bloquent.

Filtres Passe-Bas

Les filtres passe-bas atténuent les hautes fréquences, ce qui a pour effet de lisser l'image et de réduire le bruit. Les trois modèles classiques sont :

  • Filtre Idéal : Coupe brutalement les fréquences au-delà d'un rayon \( D_0 \).
  • Filtre Gaussien : Offre une transition douce, évitant les artefacts de tremblement (ringing).
  • Filtre de Butterworth : Paramétrable via un ordre \( n \), offrant un compromis entre le filtre idéal et le gaussien.

Les fonctions de transfert \( H(u,v) \) pour un filtre passe-bas, où \( D(u,v) \) est la distance au centre du spectre, sont définies par :

\[ H_{ideal}(u,v) = \begin{cases} 1 & \text{si } D(u,v) \leq D_0 \\ 0 & \text{si } D(u,v) > D_0 \end{cases} \]

\[ H_{gaussien}(u,v) = e^{-\frac{D^2(u,v)}{2D_0^2}} \]

\[ H_{butterworth}(u,v) = \frac{1}{1 + \left(\frac{D(u,v)}{D_0}\right)^{2n}} \]

Filtres Passe-Haut

Les filtres passe-haut accentuent les hautes fréquences, ce qui permet de détecter les contours et d'augmenter la netteté. Leur fonction de transfert est simplement l'inverse de celle des filtres passe-bas :

\[ H_{haut}(u,v) = 1 - H_{bas}(u,v) \]

Filtres Sélectifs (Passe-Bande et Coupe-Bande)

Ces filtres ciblent des intervalles de fréquences spécifiques. Ils sont particulièrement utiles pour éliminer des bruits périodiques. Un filtre coupe-bande (notch filter) bloque des fréquences très localisées.

import numpy as np

def generate_distance_matrix(rows, cols):
    """Génère une matrice des distances par rapport au centre de l'image."""
    u = np.arange(rows) - rows / 2
    v = np.arange(cols) - cols / 2
    U, V = np.meshgrid(u, v, indexing='ij')
    return np.sqrt(U**2 + V**2)

def butterworth_lowpass(shape, cutoff_freq, order=2):
    """Crée un masque de Butterworth passe-bas vectorisé."""
    D = generate_distance_matrix(shape[0], shape[1])
    return 1.0 / (1.0 + (D / cutoff_freq) ** (2 * order))

def butterworth_highpass(shape, cutoff_freq, order=2):
    """Crée un masque de Butterworth passe-haut."""
    return 1.0 - butterworth_lowpass(shape, cutoff_freq, order)

def gaussian_bandreject(shape, center_freq, width):
    """Crée un filtre gaussien coupe-bande."""
    D = generate_distance_matrix(shape[0], shape[1])
    return 1.0 - np.exp(-((D**2 - center_freq**2) / (D * width + 1e-6))**2)

# Application sur une image
def apply_frequency_filter(image, filter_mask):
    f_transform = np.fft.fftshift(np.fft.fft2(image))
    filtered_spectrum = f_transform * filter_mask
    return np.abs(np.fft.ifft2(np.fft.ifftshift(filtered_spectrum)))

Correspondance entre les Domaines Spatial et Fréquentiel

Le théorème de convolution établit un lien fondamental entre ces deux domaines : une convolution dans le domaine spatial équivaut à une multiplication dans le domaine fréquentiel, et vice versa.

\[ f(x,y) * h(x,y) \iff F(u,v) \cdot H(u,v) \]

Bien que les opérations de convolution spatiale soient très efficaces pour des noyaux de petite taille, le filtrage fréquentiel via l'algorithme de la Transformée de Fourier Rapide (FFT) devient considérablement plus rapide lorsque la taille du noyau augmente. De plus, le domaine fréquentiel offre une intuition visuelle directe pour la conception de filtres complexes. Une approche courante consiste à concevoir un filtre dans le domaine fréquentiel, puis à calculer sa transformée inverse pour obtenir un noyau de convolution spatial optimisé.

Étiquettes: traitement-d-image transformee-de-fourier filtrage-frequentiel Python NumPy

Publié le 11 juin à 20h06