IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

MATLAB Discussion :

FFT2 pour filtrer dans le domaine fréquentiel


Sujet :

MATLAB

  1. #1
    Membre habitué
    Homme Profil pro
    Ingénieur en analyse décisionnelle
    Inscrit en
    Juin 2013
    Messages
    113
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Ingénieur en analyse décisionnelle

    Informations forums :
    Inscription : Juin 2013
    Messages : 113
    Points : 133
    Points
    133
    Par défaut FFT2 pour filtrer dans le domaine fréquentiel
    Bonjour,

    À chaque fois que je reviens sur le domaine fréquentiel après l'avoir oublié faute de ne pas l'utiliser souvent, il y a quelque chose que je ne comprends pas.

    Voilà que cette fois je voulais tout simplement que mon filtre gaussien du domaine spatial soit plutôt calculé par le domaine fréquentiel.

    J'ai donc voulu faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ifft2(fft2(fspecial('gaussian', size(z), 651)) .* fft2(z))
    Où "z" est ma matrice 2D à filtrer.

    Mais je m'aperçois que la sortie est sens dessus dessous!

    Il faut donc que j'ajoute ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    fftshift(ifft2(fft2(fspecial('gaussian', size(z), 651)) .* fft2(z)))
    Pourquoi? Est-ce le bon? Est-ce au bon endroit? En tout cas, ça fonctionne...

    Merci!

  2. #2
    Membre habitué
    Homme Profil pro
    Ingénieur en science de l'environnement
    Inscrit en
    Août 2013
    Messages
    97
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur en science de l'environnement

    Informations forums :
    Inscription : Août 2013
    Messages : 97
    Points : 149
    Points
    149
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ifft2(fftshift(fft2(fspecial('gaussian', size(z), 651)) .* fft2(z)))
    devrait donner le même résultat. On applique fftshift pour centrer le vecteur fréquentiel en 0.

    Nom : fftshiftpic.gif
Affichages : 1220
Taille : 6,6 Ko

  3. #3
    Membre habitué
    Homme Profil pro
    Ingénieur en analyse décisionnelle
    Inscrit en
    Juin 2013
    Messages
    113
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Ingénieur en analyse décisionnelle

    Informations forums :
    Inscription : Juin 2013
    Messages : 113
    Points : 133
    Points
    133
    Par défaut
    Ça ne semble pas être équivalent, malheureusement.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    [x,y] = meshgrid(single(-5:0.01:5));
    z = peaks(x,y)*1000;
     
    z2 = fftshift(ifft2(fft2(fspecial('gaussian', size(z), 100)) .* fft2(z)));
    z3 = ifft2(fftshift(fft2(fspecial('gaussian', size(z), 100)) .* fft2(z)));
     
    figure;
    subplot(2,2,1);
    imagesc(z);colorbar;colormap(parula(256));title('z');
    subplot(2,2,2);
    imagesc(real(z2)-real(z3));colorbar;colormap(parula(256));title('z2 - z3');
    subplot(2,2,3);
    imagesc(real(z2));colorbar;colormap(parula(256));title('z2');
    subplot(2,2,4);
    imagesc(real(z3));colorbar;colormap(parula(256));title('z3');
    Et d'ailleurs, dans cet exemple, j'abuse du fait que le gaussien tend vers 0, mais si je veux convertir n'importe quel filtre spatial en son équivalent fréquentiel, comment dois-je faire? Par exemple, si ç'avait été un filtre moyenneur 5x5?

    De ce que j'ai vu, il faut padder avec des zéros pour obtenir la même dimension, puis effectuer le FFT2, la multiplication et finalement le IFFT2, mais on dirait que je n'y arrive plus maintenant, j'ai perdu la recette à l'épreuve de tout...

    En cherchant, je suis tombé là-dessus où les exemples sont fonctionnels : http://www.cs.uregina.ca/Links/class...b5/lesson.html

    MAIS, la fonction de padding me semble plutôt intense, j'avais une matrice 4001x4001 qui s'est retrouvée à 8002x8002, je ne crois pas que ce soit la solution et en plus, ça ne fonctionnait même pas lorsque j'utilisais mes données à moi!

    --------------------------------------------------------------

    J'arrive à convertir n'importe quel filtre spatial en filtre fréquentiel, mais je ne comprends toujours pas le fftshift. D'ailleurs, je dois utiliser padarray et je ne saurais quoi faire lorsque le padding ne peut pas correspondre exactement (par exemple, si mon "image" avait été 1000x1000 avec le filtre 601x601 ou si le filtre avait été 600x600 avec mon "image" 1001x1001). Alors, j'ai voulu utiliser les options de padding fournies directement dans les fonctions de FFT, mais ça ne fonctionne pas! En fait, il semblerait que ce padding ne fonctionne pas puisque j'en déduis que c'est un "post-padding", donc ce n'est pas centré, c'est ajouté à droite et en bas, et non pas tout autour.

    Voici mes tests.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    close all;
    clear;
    clc;
     
    [x,y] = meshgrid(single(-5:0.01:5));
    z = peaks(x,y)*1000;
     
    % figure;
    % imagesc(z);colorbar;colormap(parula(256));
     
    z2 = imfilter(z, fspecial('gaussian', [601,601], 101));
    z3 = real(fftshift(ifft2(fft2(padarray(fspecial('gaussian', [601,601], 101),[200,200])) .* fft2(z))));
    z4 = real(fftshift(ifftn(fftn(fspecial('gaussian', [601,601], 101), size(z)) .* fftn(z, size(z)), size(z))));
     
    % z2 = imfilter(z, ones(201)/201^2);
    % z3 = real(fftshift(ifft2(fft2(padarray(ones(201)/201^2,[400,400])) .* fft2(z))));
     
    % z2 = imfilter(z, fspecial('motion', 283, 45));
    % z3 = real(fftshift(ifft2(fft2(padarray(fspecial('motion', 283, 45),[400,400])) .* fft2(z))));
     
    figure;
    imagesc(z2);colorbar;colormap(parula(256));
     
    figure;
    imagesc(z3);colorbar;colormap(parula(256));
     
    figure;
    imagesc(z4);colorbar;colormap(parula(256));
     
    % figure;
    % imagesc(z3-z2);colorbar;colormap(parula(256));

Discussions similaires

  1. Réponses: 3
    Dernier message: 06/08/2012, 09h48
  2. Réponses: 3
    Dernier message: 13/07/2012, 17h46
  3. [XL-2003] Comment utiliser une variable pour filtrer dans Excel
    Par MichaSarah dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 23/06/2010, 16h40
  4. Réponses: 3
    Dernier message: 16/11/2007, 21h37
  5. Champs pour filtrer dans DataTable
    Par Elwe31 dans le forum JSF
    Réponses: 4
    Dernier message: 08/08/2007, 20h42

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo