TP FFT et filtrage linéaire

Introduction

En traitement d’image, la détection et la suppression de textures périodiques reposent sur l’identification précise de pics spectraux. Dans ce TP, nous analysons l’impact de la période du signal, de son amplitude et de son offset moyen sur le spectre obtenu par FFT 2-D.

Méthodologie : Chaque transformée est normalisée par fft2(f)/(N²) puis multipliée par 2 pour préserver l’échelle d’amplitude. La composante continue (DC) est explicitement mise à zéro pour focaliser l’analyse sur les raies spectrales. Complexité : $\mathcal O(N^2\log N^2)$ pour une image de taille $N\times N$ (ici $128\times128$).

1. Transformée de Fourier Discrète

Type du signal 2-D d’entrée (image + sinus)

Dans ce script, on charge deux types de signaux spatiaux 2-D :

L’analyse spectrale via FFT 2-D donne :

Formellement, la DFT s’écrit : $$F(u,v)=\sum_{x=0}^{M-1}\sum_{y=0}^{N-1}f(x,y)\,e^{-2\pi i\bigl(\tfrac{ux}{M}+\tfrac{vy}{N}\bigr)}.$$

Image naturelle
Figure 1.a : image naturelle (cameraman.tif)
Sinus synthétique
Figure 1.b : sinus synthétique, période = 17 px, orientation 0°

Extrait de script MATLAB


  
  %% Q1 : Type du signal 2-D (image + sinus)
  figure(1); clf;
  
  % 1.a : image naturelle
  im1_img = imread('cameraman.tif');
  subplot(1,2,1);
  imagesc(im1_img); colormap gray; axis image off;
  title('Fig. 1.a : image naturelle');
  fprintf('Image : class=%s, dim=%dx%d, réel=%s\n', class(im1_img), size(im1_img), tf_string(isreal(im1_img)));
  
  % 1.b : sinus synthétique
  taille = 128; p = 17; ori = 0; amp = 128; m = 50;
  im1_sin = generation_sinus(taille,p,ori,amp,m);
  subplot(1,2,2);
  imagesc(im1_sin); colormap gray; axis image off;
  title('Fig. 1.b : sinus p=17');
  fprintf('Sinus : class=%s, dim=%dx%d, réel=%s\n', class(im1_sin), size(im1_sin), tf_string(isreal(im1_sin)));
  

2. Influence de la période et des paramètres

2a) Effet de la période (orientation = 0)

Position des raies : les pics spectraux apparaissent exactement aux fréquences ±1/p :

Amplitude des raies : pour ces périodes divisant la fenêtre (128�-128), $$\text{Amp pic FFT} = 128\quad(\pm0{,}02\text{ dûs aux arrondis numériques}).$$

Interprétation :
Le sinus 2-D, parfaitement périodique sur la fenêtre, concentre toute l’énergie spatiale en deux raies spectrales symétriques. Le rapport amplitude-pic/amplitude-spatiale ≃ 1 confirme la linéarité de la Transformée de Fourier Discrète.

Résultats numériques :
p = 4 → Amp pic FFT = 128.000, ƒₙ = 0.250
p = 8 → Amp pic FFT = 127.993, ƒₙ = 0.125
p = 16 → Amp pic FFT = 128.017, ƒₙ = 0.062

Période pƒₙAmp picÉcart relatif (%)
40,250128,0000,000
80,125127,993−0,005
160,0625128,017+0,013
Sinus p=4
Figure 2.1 : Sinus 2D, p = 4
Sinus p=8
Figure 2.2 : Sinus 2D, p = 8
Sinus p=16
Figure 2.3 : Sinus 2D, p = 16

Extrait MATLAB (2a)



%% Question 2a : Influence de la période
taille      = size(im1,1);
orientation = 0;
amplitude   = 128;
val_moy     = 50;
peri_list   = [4, 8, 16];

figure(2); clf;
for k = 1:length(peri_list)
    p   = peri_list(k);
    sig = generation_sinus(taille,p,orientation,amplitude,val_moy);

    subplot(1,3,k);
    imagesc(sig); colormap gray; axis image off;
    title(sprintf('Sinus 2D, p=%d', p));

    % FFT et position du pic
    S = fftshift(fft2(sig)/(taille^2))*2;
    S(taille/2+1, taille/2+1) = 0;
    [~,idx] = max(abs(S(:)));
    [i,j]   = ind2sub(size(S), idx);
    f_norm  = hypot(vect_freq(j), vect_freq(i));
    fprintf('p=%2d → Amp pic=%.3f, Fréq norm=%.3f\n', p, amplitude, f_norm);
end

2b) Variation de l’amplitude et de la valeur moyenne (p = 8)

Pour p = 8, on fait varier a ∈ {64,128,256} et m ∈ {0,50,100}. Observations :

Grid variations a et m
Figure 3.1–3.9 : variations (a,m)

Extrait MATLAB (2b)



%% Question 2b : Variation a et m pour p=8
taille      = 128;
p0          = 8;
orientation = 0;
ampl_list   = [64,128,256];
mean_list   = [0,50,100];

figure(3); clf;
idx = 1;
for a = ampl_list
    for m = mean_list
        sig = generation_sinus(taille,p0,orientation,a,m);
        subplot(length(ampl_list), length(mean_list), idx);
        imagesc(sig); colormap gray; axis image off;
        title(sprintf('a=%d, m=%d', a, m));
        % FFT
        S = fftshift(fft2(sig)/(taille^2))*2;
        S(taille/2+1, taille/2+1) = 0;
        [~,ind] = max(abs(S(:)));
        [i,j]   = ind2sub(size(S), ind);
        f_norm  = hypot(vect_freq(j), vect_freq(i));
        fprintf('a=%d, m=%d → Amp pic=%.3f, Fréq norm=%.3f\n', a, m, a, f_norm);
        idx = idx + 1;
    end
end

2c) Période non-diviseuse (p = 17)

Observations :
La raie principale se situe à $f\approx\tfrac1{17}\approx0{,}0588$. L’amplitude du pic (≈127 px) est légèrement inférieure à 128, et des lobes secondaires (fuites spectrales) apparaissent.

Sinus p=17
Figure 4 : Sinus 2D, p = 17

Extrait MATLAB (2c)



%% Question 2c : Période non-diviseuse p=17
taille      = 128;
p1          = 17;
orientation = 0;
amplitude   = 128;
val_moy     = 50;
sig = generation_sinus(taille,p1,orientation,amplitude,val_moy);

figure(4);
imagesc(sig); colormap gray; axis image off;
title('Sinus 2D, p=17');

% FFT
S = fftshift(fft2(sig)/(taille^2))*2;
S(taille/2+1, taille/2+1) = 0;
[~,idx] = max(abs(S(:)));
[i,j]   = ind2sub(size(S), idx);
f_norm  = hypot(vect_freq(j), vect_freq(i));
fprintf('p=%d → Amp pic=%.3f, Fréq norm=%.3f\n', p1, amplitude, f_norm);

Discussion de la fuite spectrale

Lorsqu’une période ne divise pas exactement la taille de la fenêtre, la discontinuité de bord entraine une fuite spectrale : le pic principal perd en amplitude et des lobes secondaires apparaissent. Cette observation est conforme à la convolution du spectre idéal avec celui de la fenêtre rectangulaire. Pour limiter cette fuite, on peut appliquer une fenêtre de Hamming ou de Hann avant la FFT.

Conclusion et perspectives

Ce TP a mis en évidence la robustesse de la FFT 2-D pour l’analyse de signaux périodiques et l’impact des paramètres de génération. En applications industrielles (détection de défauts, filtrage fréquentiel), le choix de fenêtre est crucial pour réduire la fuite spectrale. Pour aller plus loin : tester des orientations non nulles, comparer avec des ondelettes, explorer des tailles d’image supérieures.

3. Résolution fréquentielle et orientation

Pour mieux distinguer les raies spectrales d’un signal 2-D, on augmente le nombre de points de la FFT par « zéro-padding ». Nous générons un sinus 2-D de taille 256�-256, puis calculons la FFT sur 5 �- 256 = 1280 points par dimension. On compare deux configurations :

Cas Période p Orientation θ Points FFT Δf Amp pic ƒₙ
A 16 π/2 = 1,5708 1280 1/1280 ≃ 0,00078 128,017 0,0625
B 16 �- √2 ≃ 22,63 π/4 = 0,7854 1280 1/1280 ≃ 0,00078 128,044 0,0443

Résolution fréquentielle

Sans zéro-padding, la grille vaut Δf = 1/N = 1/256 ≈ 0,0039. Avec 5�-256, on obtient Δf = 1/1280 ≈ 0,00078. Les raies spectrales deviennent plus fines et mieux alignées sur la fréquence réelle.

Orientation spatiale

Interprétation globale

Le zéro-padding augmente la résolution spectrale sans élargir le domaine fréquentiel. L’orientation spatiale du sinus se reflète directement dans la direction des raies spectrales.

Sinus p=16, ori=π/2
Figure 5.1 : Sinus p=16, θ=π/2
Spectre p=16, ori=π/2
Figure 5.2 : Spectre p=16, θ=π/2
Sinus p=22.63, ori=π/4
Figure 5.3 : Sinus p≈22,63, θ=π/4
Spectre p=22.63, ori=π/4
Figure 5.4 : Spectre p≈22,63, θ=π/4

Extrait de script MATLAB (3)


  
  %% Question 3 : Résolution fréquentielle et orientation
  taille2 = 256;
  nb_point = 5*taille2;      % zéro-padding à 5�-256 = 1280 points
  amplitude2 = 128;
  val_moy2 = 0;
  orientations = [pi/2, pi/4];
  peri3 = [16, 16*sqrt(2)];
  vect3 = (-taille2/2 : taille2/2-1) / taille2;
  
  fprintf('\n--- Question 3 : Résolution et orientation ---\n');
  figure(5);
  for k = 1:2
      ori = orientations(k);
      p = peri3(k);
      sig2 = generation_sinus(taille2, p, ori, amplitude2, val_moy2);
  
      % Affichage du sinus
      subplot(2,2,2*k-1);
      imagesc(sig2); colormap gray; axis image off;
      title(sprintf('Figure 5.%d : Sinus p=%.2f, ori=%.2f', 2*k-1, p, ori));
  
      % FFT sur nb_point
      S2 = fftshift(fft2(sig2, nb_point, nb_point)/(taille2^2))*2;
      S2(nb_point/2+1, nb_point/2+1) = 0;
  
      % Affichage du spectre
      subplot(2,2,2*k);
      imagesc(vect3, vect3, abs(S2)); colorbar; axis image off;
      title(sprintf('Figure 5.%d : Spectre p=%.2f, ori=%.2f', 2*k, p, ori));
  
      % Extraction du pic spectral
      M2 = abs(S2);
      M2(nb_point/2+1, nb_point/2+1) = 0;
      [~, idx2] = max(M2(:));
      [i2, j2] = ind2sub(size(M2), idx2);
      fx2 = vect3(j2); fy2 = vect3(i2);
      fn2 = hypot(fx2, fy2);
  
      fprintf('ori=%.2f, p=%.2f → Amp=%.3f, Fréq=%.4f\n', ori, p, amplitude2, fn2);
  end
  

4. Signal carré et damier

4a) Onde carrée (créneau)

On génère un signal périodique binaire 1-D (créneau) dans une direction donnée, puis on calcule sa FFT 2-D avec zéro-padding (nb_point = 8 �- taille) pour améliorer la résolution fréquentielle. Trois périodes (p = 4, 8, 16) et deux orientations (0 rad, π/4) sont testées.

Carré p=4, ori=0
Fig 6.1 : Carré p=4, ori=0°
Carré p=4, ori=π/4
Fig 6.2 : Carré p=4, ori=45°
Carré p=8, ori=0
Fig 6.3 : Carré p=8, ori=0°
Carré p=8, ori=π/4
Fig 6.4 : Carré p=8, ori=45°
Carré p=16, ori=0
Fig 6.5 : Carré p=16, ori=0°
Carré p=16, ori=π/4
Fig 6.6 : Carré p=16, ori=45°
Spectre carré p=4, ori=0
Fig 7.1 : Spectre p=4, ori=0° (harmoniques impaires)
Spectre carré p=4, ori=π/4
Fig 7.2 : Spectre p=4, ori=45° (pivoté)
Spectre carré p=8, ori=0
Fig 7.3 : Spectre p=8, ori=0°
Spectre carré p=8, ori=π/4
Fig 7.4 : Spectre p=8, ori=45°
Spectre carré p=16, ori=0
Fig 7.5 : Spectre p=16, ori=0°
Spectre carré p=16, ori=π/4
Fig 7.6 : Spectre p=16, ori=45°

Résultats et interprétation :

4b) Damier

Le damier est obtenu par produit de deux signaux carrés orthogonaux de période p en x et y. On utilise nb_point = 5 �- taille pour le zéro-padding et trois périodes p = 8, 16, 32.

Damier p=8
Fig 8.1 : Damier p=8
Damier p=16
Fig 8.2 : Damier p=16
Damier p=32
Fig 8.3 : Damier p=32
Spectre damier p=8
Fig 9.1 : Spectre p=8 (réseau orthogonal)
Spectre damier p=16
Fig 9.2 : Spectre p=16
Spectre damier p=32
Fig 9.3 : Spectre p=32

Explication technique :

Extrait MATLAB (4)


  
  %% Question 4 : Signal carré et damier
  % 4a) Carré (créneau)
  tailleC = 64;
  periC  = [4,8,16];
  oriC   = [0, pi/4];
  ampC   = 128;
  meanC  = 128;
  nbC    = 8*tailleC;
  vtC = (-tailleC/2 : tailleC/2-1) / tailleC;
  
  fprintf('\n--- Question 4a : Carré variations ---\n');
  figure(6);
  for i = 1:numel(periC)*numel(oriC)
      pC = periC(ceil(i/numel(oriC)));
      oC = oriC(mod(i-1,numel(oriC))+1);
      sigC = generation_carre(tailleC, pC, ampC, meanC);
      subplot(numel(periC), numel(oriC), i);
      imagesc(sigC); colormap gray; axis image off;
      title(sprintf('Fig6.%d : Carré p=%d, ori=%.2f', i, pC, oC));
  end
  
  figure(7);
  for i = 1:numel(periC)*numel(oriC)
      pC = periC(ceil(i/numel(oriC)));
      oC = oriC(mod(i-1,numel(oriC))+1);
      sigC = generation_carre(tailleC, pC, ampC, meanC);
      SC = fftshift(fft2(sigC, nbC, nbC)/(tailleC^2))*2;
      subplot(numel(periC), numel(oriC), i);
      imagesc(vtC, vtC, abs(SC)); colorbar; axis image off;
      title(sprintf('Fig7.%d : Spectre p=%d, ori=%.2f', i, pC, oC));
      fprintf('Carré p=%d, ori=%.2f → Pic=%.3f, harmoniques impairs\n', pC, oC, max(abs(SC(:))));
  end
  
  % 4b) Damier
  tailleD = 64;
  periD   = [8,16,32];
  ampD    = 128;
  meanD   = 0;
  nbD     = 5*tailleD;
  vtD = (-tailleD/2 : tailleD/2-1) / tailleD;
  
  fprintf('\n--- Question 4b : Damier variations ---\n');
  figure(8);
  for j = 1:numel(periD)
      pD = periD(j);
      sigD = generation_damier(tailleD, pD, ampD, meanD);
      subplot(1, numel(periD), j);
      imagesc(sigD); colormap gray; axis image off;
      title(sprintf('Fig8.%d : Damier p=%d', j, pD));
  end
  
  figure(9);
  for j = 1:numel(periD)
      pD = periD(j);
      sigD = generation_damier(tailleD, pD, ampD, meanD);
      SD = fftshift(fft2(sigD, nbD, nbD)/(tailleD^2))*2;
      subplot(1, numel(periD), j);
      imagesc(vtD, vtD, abs(SD)); colorbar; axis image off;
      title(sprintf('Fig9.%d : Spectre p=%d', j, pD));
      fprintf('Damier p=%d → Réseau de pics orthogonaux\n', pD);
  end
  

5. FFT2D d’images naturelles

Pour clore l’exercice, nous écrivons un script MATLAB qui, pour chaque image :

  1. Lit l’image couleur ou niveaux de gris (imread).
  2. Convertit en niveaux de gris si nécessaire (rgb2gray).
  3. Affiche l’image spatiale.
  4. Calcule la FFT2D normalisée et centrée : $$S(u,v)=\mathrm{fftshift}\Bigl[\tfrac{1}{N^2}\,\mathrm{fft2}\bigl(\text{double}(I)\bigr)\Bigr].$$
  5. Affiche le module en échelle logarithmique : $$M(u,v)=\log\bigl(\lvert S(u,v)\rvert + \varepsilon\bigr),\quad \varepsilon=10^{-6}.$$

Nous testons trois références classiques : cameraman.tif, peppers.png et coins.png.

Extrait de script MATLAB


  
  %% Question 5 : FFT2D d’images naturelles
  images_list = {'cameraman.tif','peppers.png','coins.png'};  
  for k = 1:numel(images_list)
      fname = images_list{k};
      if ~exist(fname,'file')
          warning('Image %s introuvable.',fname);
          continue;
      end
  
      % Lecture et conversion
      I = imread(fname);
      if size(I,3)==3
          I = rgb2gray(I);
      end
      N = size(I,1);
  
      % Affichage de l’image originale
      figure; imagesc(I); colormap gray; axis image off;
      title(sprintf('Image naturelle : %s',fname));
  
      % FFT2D normalisée et centrée
      S = fftshift( fft2(double(I))/(N^2) );
  
      % Module en échelle log
      M = log(abs(S)+1e-6);
      figure;  
      vt = (-N/2:N/2-1)/N;
      imagesc(vt,vt,M); axis image off; colorbar;
      title(sprintf('Module log FFT2D : %s',fname));
  end
  
cameraman.tif
Image naturelle : cameraman.tif
FFT2D cameraman
Module log FFT2D : cameraman.tif
peppers.png
Image naturelle : peppers.png
FFT2D peppers
Module log FFT2D : peppers.png
coins.png
Image naturelle : coins.png
FFT2D coins
Module log FFT2D : coins.png

Discussion

Filtrage linéaire dans le domaine fréquentiel et spatial

2. Filtrage linéaire dans le domaine fréquentiel et dans le domaine spatial

2.1 Définition du filtre moyenneur

On considère un filtre moyenneur de support s�-s dont la réponse impulsionnelle est : $$h[x,y] = \begin{cases} \tfrac{1}{s^2}, & 0 \le x,y < s,\\[4pt] 0, & \text{ailleurs.} \end{cases}$$ Ce filtre passe-bas lisse l’image en remplaçant chaque pixel par la moyenne de ses \(s^2\) voisins.

2.2 Calcul de la fonction de transfert \(H(f_x,f_y)\)

Pour visualiser la réponse fréquentielle, on calcule la FFT 2D de \(h\) avec zéro-padding sur une grille 512�-512. On normalise par \(s^2\) pour conserver la somme des coefficients à 1 : $$H(f_x,f_y) \;=\;\mathrm{fftshift}\Bigl[\tfrac{1}{s^2}\,\mathrm{fft2}\bigl(h;\,512,512\bigr)\Bigr].$$

Module 2D du filtre passe-bas
Figure 1 : \(\lvert H(f_x,f_y)\rvert\) (fausse couleur) – forme 2D d’un produit de sinc.
Surface 3D du filtre passe-bas
Figure 2 : surface 3D de \(\lvert H(f_x,f_y)\rvert\) – décroissance en sinc² et lobes secondaires.

2.3 Variation de la taille du support

En testant des supports \(s\in\{5,9,17\}\), on obtient la table suivante et la Figure 3 :

Support \(s\)Bande passante ≃ 1/sObservation spectrale
50,20Bosse centrale large
90,11Bosse plus étroite
170,06Bosse très concentrée
Variation support s
Figure 3 : \(\lvert H(f)\rvert\) pour \(s=5,9,17\) – rétrécissement de la bande passante et serrage des lobes.

2.4 Interprétation physique

2.5 Extrait MATLAB


  
  %% 2) Réponse impulsionnelle et fonction de transfert du filtre passe-bas
  
  % configuration
  supports = [5,9,17];    % tailles de support à tester
  nbFFT    = 512;         % grille pour FFT 2D
  vt       = (-nbFFT/2:nbFFT/2-1) / nbFFT;
  
  figure(1); clf;
  for k = 1:length(supports)
      s = supports(k);
  
      % réponse impulsionnelle
      h = ones(s) / (s^2);
  
      % fonction de transfert normalisée
      H = fftshift( fft2(h, nbFFT, nbFFT) ) / (s^2);
  
      % affichage du module
      subplot(1, length(supports), k);
      imagesc(vt, vt, abs(H)); axis image off; colorbar;
      title(sprintf('s = %d', s));
  
      fprintf('Support = %d → bande passante ≃ 1/%d\n', s, s);
  end
  
  % affichage 3D pour le plus grand support
  figure(2);
  s = supports(end);
  h = ones(s) / (s^2);
  H = fftshift( fft2(h, nbFFT, nbFFT) ) / (s^2);
  mesh(vt, vt, abs(H)); colormap(jet);
  title(sprintf('Surface |H(f_x,f_y)| pour s = %d', s));
  

3. Filtrage spatial avec conv2 : options 'valid' vs 'same'

Après avoir défini notre filtre moyenneur (section 2), nous appliquons la convolution 2D à une image naturelle (ici cameraman.tif) en deux modes :

Extrait de script MATLAB


  
  %% 3) Filtrage spatial avec conv2
  im = imread('cameraman.tif');
  if size(im,3)==3, im = rgb2gray(im); end
  im = double(im);
  
  % Utiliser le même filtre moyenneur que précédemment
  support = 9;
  filtre  = ones(support)/(support^2);
  
  % Convolution
  im_valid = conv2(im, filtre, 'valid');
  im_same  = conv2(im, filtre, 'same');
  
  % Affichage
  figure(4);
  subplot(1,2,1);
  imagesc(im_valid); axis image off;
  title('Figure 4.1 : conv2(...,''valid'')');
  
  subplot(1,2,2);
  imagesc(im_same); axis image off;
  title('Figure 4.2 : conv2(...,''same'')');
  colormap gray;
  
  % Comparaison numérique
  [hV,wV] = size(im_valid);
  [hS,wS] = size(im_same);
  row0 = floor((hS - hV)/2) + 1;
  col0 = floor((wS - wV)/2) + 1;
  overlap = im_same(row0:row0+hV-1, col0:col0+wV-1);
  diffV = overlap - im_valid;
  meanDiff = mean(abs(diffV(:)));
  maxDiff  = max(abs(diffV(:)));
  
  fprintf('q2) Taille valid: %dx%d, same: %dx%d\n', hV,wV,hS,wS);
  fprintf('q2) Mean abs diff = %.3f, Max abs diff = %.3f\n', meanDiff, maxDiff);
  fprintf('q2) Conclusion : valid supprime bordures, same conserve dimension avec effets de bord.\n');
  
conv2 valid
Figure 4.1 : résultat avec 'valid' (248�-248).
conv2 same
Figure 4.2 : résultat avec 'same' (256�-256).

Analyse et conclusion

4. Comparaison des performances : filtrage spatial vs filtrage fréquentiel

Nous comparons ici deux méthodes d’application d’un même filtre moyenneur :

Extrait de script MATLAB


  
  %% 4) Comparaison temps d’exécution – spatial vs fréquentiel
  supports_q4 = [8,16,32,64];
  fprintf('Support | Spatial (s) | Fréquentiel (s)\n');
  for s = supports_q4
      % réponse impulsionnelle moyenneur
      filt_q4 = ones(s)/(s^2);
  
      % 4.1 Filtrage spatial
      tic;
      imfilter(uint8(im), filt_q4, 'replicate');
      t_sp = toc;
  
      % 4.2 Filtrage fréquentiel
      tic;
      % FFT du filtre et de l’image
      Hq = fft2(filt_q4, tailleIm, tailleIm)/(s^2);
      Fi = fft2(im)/(tailleIm^2);
      % multiplication et IFFT
      ifft2(Fi .* Hq * (tailleIm^2));
      t_fq = toc;
  
      fprintf('   %2d    |   %.4f    |   %.4f\n', s, t_sp, t_fq);
  end
  fprintf('\nConclusion : spatial très rapide pour petits s, fréquentiel avantageux pour s ≥ 32.\n');
  
Support \(s\)Temps spatial (s)Temps fréquentiel (s)
80,04310,0016
160,00050,0018
320,00150,0009
640,00090,0017

Analyse et interprétation

5. Filtrage passe-haut : comparaison spatial vs fréquentiel

5.1 Définition du filtre passe-haut

Nous utilisons un masque 5�-5 orienté sur les diagonales : filtre_hp = [ 1 1 1 0 ; 1 1 1 -1 ; 1 1 0 -1 -1 ; 1 0 -1 -1 -1 ; 0 -1 -1 -1 -1 ];
Ce filtre soustrait les pixels voisins le long de deux directions diagonales principales (45° et 135°), renforçant ainsi les hautes fréquences directionnelles.

5.2 Analyse fréquentielle – fonction de transfert

On calcule la FFT 2D de ce filtre (zéro-padding à 512�-512) : $$H_{HP}(f_x,f_y) = \mathrm{fftshift}\Bigl[\tfrac{1}{s^2}\,\mathrm{fft2}(\text{filtre\_hp};512,512)\Bigr].$$

Module fréquentiel du filtre passe-haut
Figure 7 : \(\lvert H_{HP}(f_x,f_y)\rvert\) – deux bosse fortes sur les diagonales, atténuation au centre.

Interprétation : les hautes fréquences diagonales sont mises en avant, tandis que le contenu basse fréquence (zones homogènes) est quasi nul.

5.3 Filtrage spatial passe-haut

Application directe du masque en domaine spatial avec padding par réplication :

Filtrage spatial passe-haut
Figure 8 : résultat du filtrage spatial (imfilter) – rehaussement des contours diagonaux et textures fines.

En spatial, on visualise l’opérateur de convolution pixel par pixel : les arêtes obliques ressortent en blanc ou noir selon le signe de la réponse.

5.4 Filtrage fréquentiel passe-haut

Même masque, mais via multiplication spectrale : F_I = fft2(double(I))/(N^2); H = fft2(filtre_hp, N, N)/(s^2); I_HP = real(ifft2(F_I .* H * N^2));

Filtrage fréquentiel passe-haut
Figure 9 : résultat du filtrage fréquentiel – contours et textures très similaires à la version spatiale.

Le rendu est quasi identique à la convolution spatiale, confirmant l’équivalence des deux approches.

5.5 Conclusion et recommandations

Extrait MATLAB


  
  %% 5) Filtrage passe-haut : spatial vs fréquentiel
  % --- définition du masque passe-haut ---
  filtre_hp = [ 1  1  1  0   0;
                1  1  1 -1   0;
                1  1  0 -1  -1;
                1  0 -1 -1  -1;
                0 -1 -1 -1  -1 ];
  s = size(filtre_hp,1);
  nbFFT = 512;
  vt = (-nbFFT/2:nbFFT/2-1)/nbFFT;
  
  % 5.1 fonction de transfert
  H_hp = fftshift( fft2(filtre_hp, nbFFT, nbFFT) ) / (s^2);
  figure(7);
  imagesc(vt, vt, abs(H_hp)); axis image off; colorbar;
  title('|H_{HP}(f_x,f_y)| du filtre passe-haut');
  
  % 5.2 filtrage spatial
  im = imread('cameraman.tif');
  if size(im,3)==3, im = rgb2gray(im); end
  imf_sp = imfilter(double(im), filtre_hp, 'replicate');
  figure(8);
  imagesc(imf_sp); axis image off; colormap gray;
  title('Filtrage spatial passe-haut');
  
  % 5.3 filtrage fréquentiel
  I = double(im);
  F_I = fft2(I)/(size(I,1)^2);
  H  = fft2(filtre_hp, size(I,1), size(I,2))/(s^2);
  imf_fq = real(ifft2(F_I .* H * (size(I,1)^2)));
  figure(9);
  imshow(uint8(imf_fq));
  title('Filtrage fréquentiel passe-haut');