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

Traitement du signal Discussion :

Filtre de Butterworth d'ordre 4


Sujet :

Traitement du signal

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    76
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 76
    Points : 56
    Points
    56
    Par défaut Filtre de Butterworth d'ordre 4
    Bonjour,

    Je reviens sur ce sujet parce que j'ai justement un problème du même type que dans cette discussion [Signal] Implémentation filtres Passe-Bas en C

    Citation Envoyé par pseudocode Voir le message
    J'en profite aussi pour dire que le circuit RC n'est pas très performant comme filtre passe-bas. Il vaut mieux prendre un Butterworth d'ordre 2.
    Tout est dit.
    Je cherche à programmer en C/C++ un filtre de Butterworth d'ordre 4, où l'on peut régler la fréquence de coupure (edit : et la fréquence d'échantillonnage).

    Pour revenir sur le contexte, je travaille sur des signaux cardiaques. Je détecte donc mes pics R sur mon ECG (le grand pic du signal qui fait bip dans les séries médicales) pour avoir une référence du rythme cardiaque.
    Ensuite, je traite un second signal, que j'ai besoin de filtrer au plus prêt de ce qui m'intéresse (Passe bas à 15x la fréquence cardiaque et passe haut à 0.7x la fréquence cardiaque).
    Jusque là, je faisais mon passe-bas sous Scilab (Butterworth d'ordre 4, appliqué 2x, 1 fois dans le sens classique, et une fois dans le sens rétrograde -> élimination de la phase du filtre). Mais j'arrive à la fin de ma thèse, et je dois remettre certains de mes algos en C pour l'inclure dans l'appli de ma boite.

    C'est là qu'est mon problème : reprogrammer le filtre de Butterworth.
    J'ai bien trouvé une fonction de transfert (http://fr.wikipedia.org/wiki/Filtre_...de_Butterworth) ou encore une méthode pour écrire "l'équation aux différences" à partir d'une fonction de transfert (http://forums.futura-sciences.com/el...worth-iir.html)... Mais cela fait trop longtemps pour que j'arrive à m'y remettre sans un coup de main (faut dire, j'étais déjà pas doué à l'époque ), et ça ne me dit toujours pas comment régler la fréquence de coupure de mon filtre.

    J'ai pas mal fouillé sur Internet, mais soit je trouve un algo générique, sans avoir ce satané filtre de Butterworth ni la manière de régler le filtre en fonction de la fréquence, soit les gens l'ont déjà fait... mais ne postent pas leur code parce qu'ils partent sur une autre discussion.


    Voilà pourquoi je viens demander un coup de main concernant ce si connu filtre de Butterworth.
    Merci d'avance.


    PS: Si vous pensez que personne ne saura me répondre, n'hésitez pas à me le dire. C'est mieux que de rester le bec dans l'eau sans savoir si quelqu'un a vu le message, ou si beaucoup de gens l'ont vu mais personne ne saurait m'aider/m'aiguiller.

  2. #2
    Rédacteur

    Homme Profil pro
    Comme retraité, des masses
    Inscrit en
    Avril 2007
    Messages
    2 978
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 83
    Localisation : Suisse

    Informations professionnelles :
    Activité : Comme retraité, des masses
    Secteur : Industrie

    Informations forums :
    Inscription : Avril 2007
    Messages : 2 978
    Points : 5 179
    Points
    5 179
    Par défaut
    Salut!
    Je cherche à programmer en C/C++ un filtre de Butterworth d'ordre 4
    Que veut dire pour toi programmer un filtre? Certainement écrire un programme. Mais qu'est-ce que ce programme doit faire? Te donner les valeurs des divers composants pour obtenir des caractéristiques données (méthode de Cauer)? Te donner le signal de sortie échantillonné pour un signal d'entrée échantillonné donné? Ou quoi encore?
    Jean-Marc Blanc
    Calcul numérique de processus industriels
    Formation, conseil, développement

    Point n'est besoin d'espérer pour entreprendre, ni de réussir pour persévérer. (Guillaume le Taiseux)

  3. #3
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Points : 16 081
    Points
    16 081
    Par défaut
    Moi je comprend pas bien ce que tu veux dire par "régler le filtre en fonction de la fréquence". Etant donné que tu connais déja la fréquence de coupure (15x la fréquence cardiaque) je vois pas ce que tu veux de plus.
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  4. #4
    Membre émérite
    Homme Profil pro
    Inscrit en
    Mai 2008
    Messages
    2 040
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 2 040
    Points : 2 841
    Points
    2 841
    Par défaut
    Bonjour.
    Tu calcules les coefficients du filtre ([b,a] = butter(4,omegac/(Fe/2),'low')
    puis tu programmes l'équation récurrente. Exemple sous matlab :
    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
    clear
    Fe=1000;Te=1/Fe;
    omegac=300;
    [b,a] = butter(4,omegac/(Fe/2),'low')
    freqz(b,a,128,Fe)
    duree=5;
    sem1=0;sem2=0;sem3=0;
    sfm1=0;sfm2=0;sfm3=0;
    n=0;
    for t=0:Te:duree
        n=n+1;
        se=5*sin(2*pi*0.5*t);
    sf=b(1)*se+b(2)*sem1+b(3)*sem2+b(4)*sem3-a(2)*sfm1-a(3)*sfm2-a(4)*sfm3;
    sfm3=sfm2;sfm2=sfm1;sfm1=sf;
    sem3=sem2;sem2=sem1;sem1=se;
    enreg_se(n)=se;
    enreg_sf(n)=sf;
    end
    dt=0:Te:duree;
    plot(dt,enreg_sf,'r')
    hold on
    plot(dt,enreg_se)
    grid

  5. #5
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    76
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 76
    Points : 56
    Points
    56
    Par défaut
    Citation Envoyé par FR119492 Voir le message
    Que veut dire pour toi programmer un filtre?
    Citation Envoyé par pseudocode Voir le message
    Moi je comprend pas bien ce que tu veux dire par "régler le filtre en fonction de la fréquence".
    Oula, ça doit faire trop longtemps que je suis la tête dans le guidon. J'explique si mal que ça?

    Jean-Marc, pour essayer d'être plus explicite, je me place comme quelqu'un qui nettoie son signal avant de l'étudier. J'ai un signal "bruité" (50Hz, bruit d'acquisition, artefacts liés à l'acquisition), et mon but bête et méchant est de récupérer mon signal sans le bruit.

    Ensuite, pseudocode, pour te répondre, je dirai simplement que je dois traiter des signaux, indifféremment du signal d'entrée. Si la personne a un coeur battant à 60bpm (1Hz), je veux que ma fonction me renvoie un signal "débruité", le filtre passe bas utilisé ayant une fréquence de coupure à 15Hz. Si la personne suivante a un coeur battant la chamade à 180bpm (3Hz), mon filtre devra avoir une fréquence de coupure à 45Hz.
    De même, je ne sais pas quelle sera la fréquence d'échantillonnage utilisée par les utilisateurs finaux, cela pourra donc être 100Hz ou bien 10kHz.

    La fréquence de coupure et la fréquence d'échantillonnage sont donc des paramètres d'entrées de ma fonction.

    Voilà un prototype de ce que je souhaite :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    double * filtre_passe_bas ( const double * signal_brut , const unsigned long nb_elements , const double frequence_coupure , const unsigned int frequence_echantillonnage )
    {
      double * signal_sans_bruit = malloc ( nb_elements * sizeof ( double ) ) ;
      // Traitement de mon signal brut
      // ...
      return signal_sans_bruit ;
    }
    Je vous mets aussi mon code Scilab dont je voudrais l'équivalent, en C.
    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
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
     
    // -------------------------------------------------------------------------
    function [vect_filt]=filt_pb_iir(vect_donnees,freq_coupure,freq_echant,ordre)
     
    Z = vect_donnees;
    vect_filt = Z ;
     
    N = length ( Z ) ;
    dim = size ( Z ) ;
    moy_Z = mean ( Z ) ;
    Z = Z - moy_Z ;
     
    // Recherche d'un IIR stable
    [nu_c_est, num, den, bStable] = filnum_RII_pb(ordre,freq_coupure/freq_echant,'butt',-0.1,-40,512)
    while ( bStable == %F ) & ( ordre > 0 )
      ordre = ordre - 1 ;
      [nu_c_est, num, den, bStable] = filnum_RII_pb(ordre,freq_coupure/freq_echant,'butt',-0.1,-40,512)
    end;
     
     
    if ( bStable ) & ( N == max ( dim(1) , dim(2) ) ) then
     
      // ----- Filtrage dans le domaine temporel -----
     
      // Filtrage dans le sens directe
      Z_filt_f = zeros ( N , 1 ) ;
      for i=(ordre+1):N
        Z_in = Z ( i:-1:i-ordre ) ;
        Y_in = Z_filt_f ( i:-1:i-ordre ) ;
        Z_filt_f ( i ) = num * Z_in - den * Y_in ;
      end ;
     
      // Filtrage dans le sens retrograde
      Z_filt_b = zeros ( N , 1 ) ;
      for i=N-ordre:-1:1
        Z_in = Z_filt_f ( i:i+ordre ) ;
        Y_in = Z_filt_b ( i:i+ordre ) ;
        Z_filt_b ( i ) = num * Z_in - den * Y_in ;
      end ;
     
      vect_filt ( : ) = Z_filt_b ( : ) + moy_Z ;
     
    end;
     
    endfunction
     
    // -------------------------------------------------------------------------
    function [nu_c_est, num, den, bStable] = filnum_RII_pb(ordre,nu_c,meth,GdB_min_bp, GdB_max_bc,N)
     
    // entrées :
    // ordre : ordre des polynômes numérateur et dénominateur
    // nu_c : fréquence de coupure
    // meth = 'cheb1', 'cheb2','ellip','butt'
    // GdB_min_bp : Gain en dB minimum dans la bande passante - utile uniquement pour 'cheb1' et 'ellip'
    // GdB_max_bc : Gain en dB maximum dans la bande coupée - utile uniquement pour 'cheb2' et 'ellip'
     
    // sorties :
    // nu_c_est : fréquence de coupure estimée à partir des N points
    // num : coefficients du polynôme numérateur (puissance décroissante)
    // den : coefficients du polynôme dénominateur (puissance décroissante)
    // bStable : booleen permettant de savoir si le filtre est stable au sens EBSB ou non
     
    gain_min_bp = 1-10^(GdB_min_bp/20);
    gain_max_bc = 10^(GdB_max_bc/20);
     
    for r = 1 : N
    	if((r-1)/(2*N) < nu_c)
          		Gab_id(r) = 1;
       	else
          		Gab_id(r) = 0;
       	end
     
       	D_m3dB(r) = -3;
    end
     
    if meth == 'cheb1' then
    	H = iir(ordre,'lp',meth,[nu_c 0], [gain_min_bp 0]);
    	str1 = 'Gain d''une fonction de transfert d''un filtre passe-bas RII obtenue avec la méthode de Chebyshev 1'; 
    	str2 = 'Gain en dB d''une fonction de transfert d''un filtre passe-bas RII obtenue avec la méthode de Chebyshev 1'; 
    elseif meth == 'cheb2' then
    	H = iir(ordre,'lp',meth,[nu_c 0], [0 gain_max_bc]);
    	str1 = 'Gain d''une fonction de transfert d''un filtre passe-bas RII obtenue avec la méthode de Chebyshev 2'; 
    	str2 = 'Gain en dB d''une fonction de transfert d''un filtre passe-bas RII obtenue avec la méthode de Chebyshev 2'; 
    elseif meth == 'ellip' then
    	H = iir(ordre,'lp',meth,[nu_c 0], [gain_min_bp gain_max_bc]);
    	str1 = 'Gain d''une fonction de transfert d''un filtre passe-bas RII obtenue avec la méthode elliptique'; 
    	str2 = 'Gain en dB d''une fonction de transfert d''un filtre passe-bas RII obtenue avec la méthode elliptique'; 
    else
    	H = iir(ordre,'lp','butt',[nu_c 0], [0 0]);
    	str1 = 'Gain d''une fonction de transfert d''un filtre passe-bas RII obtenue avec la méthode de Butterworth'; 
    	str2 = 'Gain en dB d''une fonction de transfert d''un filtre passe-bas RII obtenue avec la méthode de Butterworth'; 
    end
     
    [H_m,nu] = frmag(H,N);
    z = poly(0,'z');
    Hz=horner(H,1/z);
    num = coeff(numer(Hz));
    den = coeff(denom(Hz));
     
    bStable = stable_EBSB(den(2:length(den)));
     
    I = find(20*log10(abs(H_m)) < -3)
     
    nu_c_est = nu(I(1));
     
    endfunction
     
    // -------------------------------------------------------------------------
    function [bStable] = stable_EBSB(coeff_Den)
    // Coeff_Den : contient les coefficients du dénominateur d'une fonction de transfert du type 
    //             quotient de polynômes en z. Ne pas inclure le coefficient égal à 1
    //             les coefficients sont rangés suivant des puissances décroissantes.
     
    // bStable : booléen
     
    P = length(coeff_Den);
    coeff2 = zeros(P,1);
    for r = 1 : P
    	coeff2(r) = coeff_Den(P - r + 1);
    end
     
    mod_poles = abs(roots(poly([coeff2 ; 1],'z','coeff')));
     
    I = find(mod_poles >= 1)
    if(length(I) >= 1)
    	bStable = %F; // Pas stable au sens EBSB
    else
    	bStable = %T; // Stable au sens EBSB
    end
     
    endfunction
    Seule la première fonction est de moi, les 2 suivantes m'ont été données par mon chef. Mais elle résume assez bien ce que je souhaite faire, en C.

    (Edit : J'ai remodelé la suite de mon texte pour que mon problème soit, je l'espère, un peu plus compréhensible)

    En Scilab / Matlab, il y a donc bien les fonctions qui me permettent d'obtenir ce que je cherche. Mais pour l'utiliser en C, c'est râté.

    J'ai bien une fonction de transfert donnée par Wiki, et la méthode pour arrivée à une équation aux différences, mais je suis incapable de faire la transformée en Z de la fonction de transfert. Et en plus, je ne sais pas à quel moment je peux introduire la fréquence de coupure ou encore la fréquence d'échantillonnage.

    Je suis donc preneur de tout conseil qui pourrait m'aider à aboutir au même résultat que ce que j'obtiens en Scilab.

    PS : J'viens de penser que j'ai pas cherché du côté des librairies de filtrage plus générique. Une dll m'irait très bien aussi, tant que ça me fait mon filtre de Butterworth... J'vais voir ce que j'arrive à trouver.

  6. #6
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Points : 16 081
    Points
    16 081
    Par défaut
    Citation Envoyé par Cyborg Voir le message
    Ensuite, pseudocode, pour te répondre, je dirai simplement que je dois traiter des signaux, indifféremment du signal d'entrée. Si la personne a un coeur battant à 60bpm (1Hz), je veux que ma fonction me renvoie un signal "débruité", le filtre passe bas utilisé ayant une fréquence de coupure à 15Hz. Si la personne suivante a un coeur battant la chamade à 180bpm (3Hz), mon filtre devra avoir une fréquence de coupure à 45Hz.
    De même, je ne sais pas quelle sera la fréquence d'échantillonnage utilisée par les utilisateurs finaux, cela pourra donc être 100Hz ou bien 10kHz.

    La fréquence de coupure et la fréquence d'échantillonnage sont donc des paramètres d'entrées de ma fonction.
    Voyons voir si j'ai compris.

    Bon, commencons par la fréquence d'échantillonnage. Elle te permet de définir un facteur d'échelle entre le domaine "discret" des echantillons (= leur indice dans le tableau) et le domaine "réel" de la mesure.

    Fe = fréquence d'échantillonnage
    N = Nombre d'échantillons

    echelle Temporelle : 1 échantillon dure 1/Fe seconde.

    echelle Fréquentielle : les N/2 bins de fréquence (tableau de la FFT) couvrent les fréquences de 0 hz à Fe/2 hz (th de Nyquist-Shannon). L'echelle est donc de (N/2)/(Fe/2) = N/Fe

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

    Le filtre de Butterworth d'ordre 4 et de fréquence de coupure "1" a comme fonction de transfert: H4(s) = 1/B4(s) avec s=jw et w la fréquence angulaire.

    Pour avoir une fréquence de coupure "fc", on change d'échelle wa = w/fc

    Pour se placer dans le domaine "discret", on change a nouveau d'echelle : wb = wa/( N/Fe ) = wa*Fe/N = (w*Fe)/(fc*N)

    => filtre de Butterworth d'ordre 4 et de fréquence de coupure "fc" dans l'espace discretisé est:

    H4(s,fc,Fe,N) = 1/B4(j.wb) = 1/B4(j.(w*Fe)/(fc*N))

    Reste a séparer les parties réelles et imaginaires de H4() pour pouvoir effectuer le filtrage (= multiplication complexe dans le domaine de Fourier)

    Est-ce bien cela ?


    Edit : j'ai essayé d'expliquer un peu mieux les changements d'echelles
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    76
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 76
    Points : 56
    Points
    56
    Par défaut
    Burp...

    J'vais déjà essayer de digérer ça, mais a priori, je pense qu'on est bon.

    Il faudra certainement que je relise 25x ton message pour arriver à intégrer la théorie qui est derrière (ça peut toujours servir).

    Concernant l'intégration dans du code, j'ai une librairie qui me fournit une fft, donc pas de soucis de ce côté-là. Et une multiplication complexe, c'est pas la mort.
    Par contre, je ne vois pas bien ce qu'il faut "multiplier". Je verrai peut-être mieux ça demain à tête reposée.

    de plus, si j'arrive à transposer la transformation dans le domaine temporel, ça m'économise l'utilisation d'une librairie de fft.
    Je revois ça demain et je vous tiens au courant.

    En tout cas, merci beaucoup.

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    76
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 76
    Points : 56
    Points
    56
    Par défaut
    Citation Envoyé par pseudocode Voir le message
    echelle Temporelle : 1 échantillon dure 1/Fe seconde.

    echelle Fréquentielle : les N/2 bins de fréquence (tableau de la FFT) couvrent les fréquences de 0 hz à Fe/2 hz (th de Nyquist-Shannon). L'echelle est donc de (N/2)/(Fe/2) = N/Fe
    Dans le domaine temporel, l'écart entre 2 échantillons est donc de 1/Fe seconde, et le signal représente N/Fe secondes, de 1/Fe s à N/Fes.
    Dans le domaine fréquentiel, l'écart entre 2 échantillons (ou points) est de Fe/N Hz si je comprend bien, et les fréquences sont représentées de Fe/N Hz à Fe/2, la seconde partie de la FFT étant simplement le symétrique de la première, donc seulement N/2 fréquences intéressantes.

    J'ai du mal avec le sens du mot échelle et son application, mais j'ai compris la méthode que tu utilises pour intégrer la fréquence de coupure, ainsi que la fréquence d'échantillonnage.

    Alors revenons à présent sur la fonction de transfert. Avec s=jw et w=2.pi.f, ça nous donne :
    H4(f,fc,Fe,N) = 1/B4(j.2.pi.f.(Fe)/(fc*N))

    Je n'ai plus qu'à convoluer la fft de mon signal par cette fonction de transfert, c'est bien ça?

    Par contre, appliquer le filtre dans le sens direct correspond à cette fonction de transfert. Si je souhaite l'appliquer dans le sens retrograde, est-ce que c'est :
    Hr4(f,fc,Fe,N) = 1/B4(-j.2.pi.f.(Fe)/(fc*N))

  9. #9
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Points : 16 081
    Points
    16 081
    Par défaut
    Citation Envoyé par Cyborg Voir le message
    J'ai du mal avec le sens du mot échelle et son application, mais j'ai compris la méthode que tu utilises pour intégrer la fréquence de coupure, ainsi que la fréquence d'échantillonnage.
    Tableau de la FFT : |_|_|_|_|_|_|_|_|_|

    - la case d'index "0" de la FFT correspond à la contribution de la fréquence "0 hz" dans le signal
    - la case d'index "N/2" de la FFT correspond à la contribution de la fréquence "Fe/2 hz" dans le signal
    - entre ces deux cases, les correspondances varient linéairement.

    Il y a donc un facteur d'échelle linéaire entre le numero d'index et la fréquence. Facteur que l'on détermine par une surpuissante règle de 3.

    Voila, c'est pas plus compliqué que cela.

    Alors revenons à présent sur la fonction de transfert. Avec s=jw et w=2.pi.f, ça nous donne :
    H4(f,fc,Fe,N) = 1/B4(j.2.pi.f.(Fe)/(fc*N))

    Je n'ai plus qu'à convoluer la fft de mon signal par cette fonction de transfert, c'est bien ça?
    Oui.

    Par contre, appliquer le filtre dans le sens direct correspond à cette fonction de transfert. Si je souhaite l'appliquer dans le sens retrograde, est-ce que c'est :
    Hr4(f,fc,Fe,N) = 1/B4(-j.2.pi.f.(Fe)/(fc*N))
    Oui. Hr4(f) = H4(-f)

    Dans le cas de ce filtre, c'est meme le conjugué. Donc pas besoin de calculer les coefficients de Hr4, il suffit juste de prendre le conjugué des coefficients de H4.
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    76
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 76
    Points : 56
    Points
    56
    Par défaut
    Impeccable. A présent, j'ai donc une méthode qui fonctionne, donc techniquement je pourrai m'arrêter là.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Signal_filtré = ifft ( Hr4 ( H4 ( fft ( signal_brut ) ) ) )
    Mais comme j'aime bien pousser le vice jusqu'au bout, on va essayer d'optimiser ça à présent. Et comme j'ai besoin de théorie pour continuer, je continue donc ici.
    J'espère que ça ne pose pas de problème?


    Dans le cas de mon filtre, comme je l'utilise dans le sens direct, puis dans le sens retrograde, les phases des filtres s'annulent.
    Donc est-ce que je peux remplacer ( Hr4 * H4 ) par ( Gr4 * G4 ) ?
    G4 étant la fonction de gain du filtre (vachement plus simple en l'occurence)? Cela serait plus rapide à coder et à exécuter (bien que je me demande combien d'opérations il faut pour calculer une racine carré).

    Enfin, si je souhaite revenir sur une opération dans le domaine temporel, il faut que j'utilise la méthode décrite dans la réponse à ce post : http://forums.futura-sciences.com/el...worth-iir.html
    C'est à dire :
    - diviser (Hr4*H4)(f) par j.2.pi.f
    - calculer la transformée en Z du résultat (argh!!)
    - multiplier cela par (1 - 1/z)
    Posons le résultat comme H(z), sous la forme H_num(z)/H_den(z).
    H(z) correspondant à H(z) = y(z)/x(z), on obtient donc
    - H_num(z)/H_den(z) = y(z)/x(z)
    donc
    - x(z).H_num(z) = y(z).H_den(z)
    Et sachant que y(z).z^-1 correspond à y(k-1) dans le domaine temporel, on va donc chercher à exprimer y(z).z en fonction du reste.
    Grossièrement, ça donnerait :
    y(z) = ( n0.x(z).z + n1.x(z).z^-1 + ... + nk.x(z).z^-k ) - ( d0.y(z).z-1 + d1.y(z).z-2 + ... + dm.y(z).z^-m )

    Si c'est bien ça, le plus difficile sera de calculer la transformée en Z de ma grosse équation donnée par (Hr4*H4)(f), sachant que je ne vois même pas comment calculer la transformée en Z d'un fonction "simple" comme
    G=1/sqrt(1+w^8)


    Je pense que j'ai fait le tour de mon problème. Donc je prend tout conseil sur ce dernier point (la transformée en Z), tout comme je prend toute remarque sur la méthode pour passer d'une fonction de transfert (domaine fréquentiel) à une "équation aux différences" (domaine temporel - je ne fait que reprendre le nom utilisé dans le post en lien).

    PS: Merci pour la note sur l'échelle. Je vois bien ce que ça donne. J'arrive à imaginer mon signal, sa fft, une représentation graphique du gain du filtre et son homothétie pour agrandir le filtre et ainsi changer sa fréquence de coupure. Mais j'ai simplement du mal à y associer le terme "changement d'échelle", même si c'est exactement la même chose que changer d'échelle sur une carte routière...

  11. #11
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Points : 16 081
    Points
    16 081
    Par défaut
    Citation Envoyé par Cyborg Voir le message
    Dans le cas de mon filtre, comme je l'utilise dans le sens direct, puis dans le sens retrograde, les phases des filtres s'annulent.
    Donc est-ce que je peux remplacer ( Hr4 * H4 ) par ( Gr4 * G4 ) ?
    G4 étant la fonction de gain du filtre (vachement plus simple en l'occurence)? Cela serait plus rapide à coder et à exécuter (bien que je me demande combien d'opérations il faut pour calculer une racine carré).
    Oui, tu peux. Tu n'as pas besoin de calculer de racine carré car Gr4 =G4 et donc Gr4*G4 = (G4)²

    Donc ton filtrage se resume à : Signal_filtré = ifft ( fft(signal) . G4² )

    Ce qui instinctivement consiste a réduire la contribution des fréquences hautes dans la table FFT (un peu comme avec un equalizer graphique).

    Enfin, si je souhaite revenir sur une opération dans le domaine temporel, il faut que j'utilise la méthode décrite dans la réponse à ce post
    Une autre méthode. Tu calcules la ifft() du filtre fréquentiel. Tu te retrouves donc avec un filtre dans le domaine temporel. Et pour filtrer le signal, tu effectues un produit de convolution.
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  12. #12
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    76
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 76
    Points : 56
    Points
    56
    Par défaut
    Donc on pourrait l'écrire ainsi :
    signal_filtré = signal brut * ifft ( G4² )
    * étant le symbole de la convolution.

    Eh bien merci beaucoup pour ton aide, pseudocode!!

    Je n'ai plus qu'à poser mes équations et c'est parti. Je reviendrai si j'ai un soucis dans mes calculs. Dans le cas contraire, je poserai le résultat des calculs (avec la mention résolu, évidemment ).

    En tout cas, merci pour tout.

  13. #13
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Points : 16 081
    Points
    16 081
    Par défaut
    Citation Envoyé par Cyborg Voir le message
    Donc on pourrait l'écrire ainsi :
    signal_filtré = signal brut * ifft ( G4² )
    * étant le symbole de la convolution.
    Oui.

    Nom : filter.jpg
Affichages : 4175
Taille : 11,8 Ko

    En java, ca donnerait cela:
    Code java : 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
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    // paramètres 
    double Fe = 150.0; // sampling frequency (Nmb samples per second)
    int N=300;         // Number of samples
     
    /* ----------------------------------------------------------------------- */
    /*                           Creation du signal                            */
    /* ----------------------------------------------------------------------- */
     
    // frequence du signal
    double signalFrequency = 3; // in Hz
     
    // generation du signal
    double[] signal = new double[N];
    for(int i=0;i<N;i++) {
    	double t = i/Fe;
    	double w = signalFrequency*(2*Math.PI)*t;
    	double input = 128.0*Math.cos(w);
     
    	// ajout 25% de bruit 
    	double noise = 32.0*(2*Math.random()-1);
    	signal[i] = input+noise;
    }		
     
    /* ----------------------------------------------------------------------- */
    /*                           Creation du Filtre                            */
    /* ----------------------------------------------------------------------- */
     
    // frequence de coupure
    double fc=(15*signalFrequency); // in Hz
     
    if (Fe<(2*fc)) {
    	System.out.println("sampling frequency to low");
    	return;
    }
     
    // generation du filtre dans le domaine frequenciel
    double[] real = new double[N/2];
    double[] imag = new double[N/2];
    for (int f = 0; f < N/2; f++) {
    	double w  = 2*Math.PI*f;
    	double wc = (w*Fe)/(fc*N);
    	double gain_squared = 1.0/(1+Math.pow(wc,8));
    	real[f]=gain_squared;
    	imag[f]=0;
    }
     
    // filtre dans le domaine temporel
    double[] filter = new double[N];
    invDFT(real, imag, filter);
     
    /* ----------------------------------------------------------------------- */
    /*                         Application du Filtre                           */
    /* ----------------------------------------------------------------------- */
     
    // output = filter (x) signal
    double[] output = new double[N];
    for (int i = 0; i < N; i++) {
    	output[i] = 0; 
    	for (int f = 0; f < N; f++)
    		output[i] += signal[(N + i - f) % N] * filter[f];
    }
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  14. #14
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    76
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 76
    Points : 56
    Points
    56
    Par défaut
    Merci pour le code.
    Par contre, je n'avais pas réalisé que la dimension du filtre était directement liée à la dimension de mes données. Hors mes fichiers sont "un peu" long (5min à 2.5kHz, et ça passera à 8h à une fréquence entre 1 et 2.5kHz.

    Il faudrait passer par les machins du genre développement limité pour obtenir une équation qui soit fonction d'un nombre n fini de coefficients ? Ou uniquement par la méthode précédente (tranformée en Z -> équation aux différences) ?

    Edit : Dans un premier temps, je vais l'implémenter comme ça, parce que je dois faire avancer le reste de mes calculs. Mais la question est toujours valable.

  15. #15
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Points : 16 081
    Points
    16 081
    Par défaut
    Citation Envoyé par Cyborg Voir le message
    Merci pour le code.
    Par contre, je n'avais pas réalisé que la dimension du filtre était directement liée à la dimension de mes données. Hors mes fichiers sont "un peu" long (5min à 2.5kHz, et ça passera à 8h à une fréquence entre 1 et 2.5kHz.
    Tu n'es pas obligé de travailler sur tout le signal en une seule fois. Tu peux travailler sur des petits morceaux consécutifs de signal de la taille de ton choix
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  16. #16
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    76
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 76
    Points : 56
    Points
    56
    Par défaut
    * soupire * C'est parfois difficile de travailler avec un cerveau qui fonctionne aussi mal...

    Tu as tout à fait raison.

    Par contre, je me pose une question par rapport à cette partie de l'algorithme :
    signal[(N + i - f) % N]
    Ne travaillant pas simplement sur des signaux "sinusoïdaux" que l'on peut re-boucler sans problème, le fait qu'il y ait une différence importante de ligne de base entre le début du signal et la fin du signal ne risque pas de créer un effet de bord important?
    Car si c'est le cas, il devient absolument nécessaire d'effectuer un passe-haut en amont.

    Edit : Petite erreur, je voulais dire passe-haut, et non passe-bas.

  17. #17
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Points : 16 081
    Points
    16 081
    Par défaut
    Citation Envoyé par Cyborg Voir le message
    Par contre, je me pose une question par rapport à cette partie de l'algorithme :
    signal[(N + i - f) % N]
    Ne travaillant pas simplement sur des signaux "sinusoïdaux" que l'on peut re-boucler sans problème, le fait qu'il y ait une différence importante de ligne de base entre le début du signal et la fin du signal ne risque pas de créer un effet de bord important?
    L'utilisation de l'espace de Fourier repose sur le principe d'avoir un signal d'entrée périodique. D'ou le code en question qui fait boucler le signal. Si le signal n'est pas périodique, cela provoquera effectivement des effets de bord au début/fin du signal.

    Mais bon, y a pas de miracle. C'est dur de filtrer un point du signal sans "supposer" ce qu'il y a de part et d'autre de ce point.
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  18. #18
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    76
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 76
    Points : 56
    Points
    56
    Par défaut
    Eh eh, j'me doute bien.

    Mon signal "intéressant" est périodique (signal cardiaque), mais le signal brut possède une composante basse-fréquence non-négligeable liée à la ventilation, qu'il faut que je filtre.
    Si je suis en fin d'inspiration au début de mon signal, et en fin d'expiration à la fin, il y aura une grosse différence de ligne de base. Recopier ainsi le signal me donne donc un effet de bord important.
    Et le filtre ayant la taille des données, l'effet de bord intervient sur l'intégralité des données (même si je pense que c'est de façon minime une fois éloigné des bords).

    Par contre, si je limite la taille du filtre à l'équivalent de 3s (N=3.Fe), je sais que je n'aurai d'effet de bord que sur les 3 premières et 3 dernières secondes de mon signal.

    Mais c'est possible de voir la différence, d'un point de vue algo, entre une méthode où on limite la taille du filtre, et une méthode où la taille du filtre correspond à la taille des données ? Une manière théorique d'estimer la qualité du filtre en fonction de sa taille ?
    Autrement qu'en faisant une soustraction des 2 résultats, évidemment.

  19. #19
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Points : 16 081
    Points
    16 081
    Par défaut
    Citation Envoyé par Cyborg Voir le message
    Mais c'est possible de voir la différence, d'un point de vue algo, entre une méthode où on limite la taille du filtre, et une méthode où la taille du filtre correspond à la taille des données ? Une manière théorique d'estimer la qualité du filtre en fonction de sa taille ?
    Autrement qu'en faisant une soustraction des 2 résultats, évidemment.
    Je suppose que ca doit être possible. ll faudrait calculer analytiquement le SNR du signal filtré en fonction de N.

    Intuitivement, je dirai que la qualité dépend surtout de la périodicité du signal sur la durée d'echantillonage, quelque soit cette durée. Mais je ne suis pas sur.
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  20. #20
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    76
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 76
    Points : 56
    Points
    56
    Par défaut
    Au fait, voici l'algorithme que j'utilise, c'est à dire :
    signal_filtré = IFFT ( G4^2 ( FFT ( Signal_Brut ) ) )
    Vue la taille de mes données, il vaut forcément mieux travailler dans le domaine fréquentiel pour les raisons évoquées plus haut.

    Et quitte à ce qu'il y ait la solution, autant que l'algo C figure avec.
    Note : il est donc basé sur la librairie FFTW pour la transformée en ondelettes.

    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
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    /******************************************************************************
     ***********************    passe_bande_frequentiel    ************************
     ******************************************************************************
     * But :
     *  - filtre un signal par un filtre passe-bande de Butterworth
     * Entrees :
     *  - p_d_donnees : tableau contenant les donnees a filtrer
     *  - ul_nb_donnees : nombre d'echantillons du tableau
     *  - d_frequence_echantillonnage : frequence d'echantillonnage du signal
     *  - d_frequence_coupure_ph : frequence de coupure du passe-haut
     *  - d_frequence_coupure_pb : frequence de coupure du passe-bas
     *  - ui_ordre : ordre du filtre
     * Sorties :
     *  - p_d_donnees_filtrees : tableau contenant les donnees apres filtrage
     *  - code_erreur : code d'erreur 
     *      0 : pas d'erreur
     *     -1 : mauvais parametres
     *     -2 : erreur allocation mémoire
     ******************************************************************************/
    void FiltragePasseBandeFFTW ( const double * p_d_donnees ,
                                  const unsigned long ul_nb_donnees ,
                                  const double d_frequence_echantillonnage ,
                                  const double d_frequence_coupure_ph ,
                                  const double d_frequence_coupure_pb ,
                                  const unsigned int ui_ordre ,
                                  double * p_d_donnees_filtrees ,
                                  int * code_erreur )
    {
      unsigned long i ;
      unsigned long ul_dim_fft = ( unsigned long ) ( ul_nb_donnees / 2 ) + 1 ;
      double d_gain_ph , d_gain_pb ;
      fftw_complex * fc_sortie_fft ;
      fftw_plan fp_plan_fft ;
     
      if ( code_erreur )
        * code_erreur = 0 ;
     
      if ( ( ! p_d_donnees ) || ( ! p_d_donnees_filtrees ) ||
           ( ! d_frequence_echantillonnage ) || ( ! ul_nb_donnees ) ||
           ( ( d_frequence_coupure_ph <= 0 ) && ( d_frequence_coupure_pb <= 0 ) ) ||
           ( 2 * d_frequence_coupure_ph > d_frequence_echantillonnage ) ||
           ( 2 * d_frequence_coupure_pb > d_frequence_echantillonnage ) )
        { // Controle des frequences de coupures ( il faut que Fc<Fe/2 )
          if ( code_erreur )
            * code_erreur = -1 ;
        }
      else
        {
          fc_sortie_fft = ( fftw_complex * ) fftw_malloc ( ul_nb_donnees * sizeof ( fftw_complex ) ) ;
          if ( ! fc_sortie_fft )
            {
              if ( code_erreur )
                * code_erreur = -2 ;
            }
          else
            {
              // Calculer la fft du signal
              fp_plan_fft = fftw_plan_dft_r2c_1d ( ul_nb_donnees , ( double * ) p_d_donnees , fc_sortie_fft , FFTW_ESTIMATE ) ;
              fftw_execute ( fp_plan_fft ) ;
              fftw_destroy_plan ( fp_plan_fft ) ;
     
              // Convoluer par le filtre Butterworth d'ordre 4, applique dans le sens direct et retrograde pour supprimer la phase ( Hr4 * H4 = Gr4 * G4 = (G4)^2 )
              if ( d_frequence_coupure_ph <= 0 ) // Filtre passe bas uniquement
                {
                  for ( i = 0 ; i < ul_dim_fft ; i++ )
                    {
                      // w=2.pi.f ; wc = (w*Fe)/(fc*N) ; G4^2 = 1 / ( 1 + wc^(2*ordre) )
                      d_gain_pb = 1.0 / ( 1.0 + pow ( ( 2 * PI * i * d_frequence_echantillonnage ) / ( d_frequence_coupure_pb * ul_nb_donnees ) , 2 * ui_ordre ) ) ;
                      fc_sortie_fft [ i ] [ 0 ] = fc_sortie_fft [ i ] [ 0 ] * d_gain_pb ;
                      fc_sortie_fft [ i ] [ 1 ] = fc_sortie_fft [ i ] [ 1 ] * d_gain_pb ;
                    }
                }
              else
                {
                  if ( d_frequence_coupure_pb <= 0 ) // Filtre passe haut uniquement
                    {
                      for ( i = 0 ; i < ul_dim_fft ; i++ )
                        {
                          // w=2.pi.f ; wc = (w*Fe)/(fc*N) ; G4^2 = 1 / ( 1 + wc^(2*ordre) )
                          d_gain_ph = 1 - ( 1.0 / ( 1.0 + pow ( ( 2 * PI * i * d_frequence_echantillonnage ) / ( d_frequence_coupure_ph * ul_nb_donnees ) , 2 * ui_ordre ) ) ) ;
                          fc_sortie_fft [ i ] [ 0 ] = fc_sortie_fft [ i ] [ 0 ] * d_gain_ph ;
                          fc_sortie_fft [ i ] [ 1 ] = fc_sortie_fft [ i ] [ 1 ] * d_gain_ph ;
                        }
                    }
                  else
                    {
                      // Filtre passe bas bande
                      for ( i = 0 ; i < ul_dim_fft ; i++ )
                        {
                          // w=2.pi.f ; wc = (w*Fe)/(fc*N) ; G4^2 = 1 / ( 1 + wc^(2*ordre) )
                          d_gain_ph = 1 - ( 1.0 / ( 1.0 + pow ( ( 2 * PI * i * d_frequence_echantillonnage ) / ( d_frequence_coupure_ph * ul_nb_donnees ) , 2 * ui_ordre ) ) ) ;
                          d_gain_pb = 1.0 / ( 1.0 + pow ( ( 2 * PI * i * d_frequence_echantillonnage ) / ( d_frequence_coupure_pb * ul_nb_donnees ) , 2 * ui_ordre ) ) ;
                          fc_sortie_fft [ i ] [ 0 ] = fc_sortie_fft [ i ] [ 0 ] * d_gain_ph * d_gain_pb ;
                          fc_sortie_fft [ i ] [ 1 ] = fc_sortie_fft [ i ] [ 1 ] * d_gain_ph * d_gain_pb ;
                        }
                    }
                }
     
              // Calculer l'ifft du signal
              fp_plan_fft = fftw_plan_dft_c2r_1d ( ul_nb_donnees , fc_sortie_fft , p_d_donnees_filtrees , FFTW_ESTIMATE ) ;
              fftw_execute ( fp_plan_fft ) ;
              fftw_destroy_plan ( fp_plan_fft ) ;
     
              // Prise en compte du facteur d'echelle
              for ( i = 0 ; i < ul_dim_fft ; i++ )
                p_d_donnees_filtrees [ i ] /= ul_nb_donnees / 2 ;
     
              fftw_free ( fc_sortie_fft ) ;
            }
        }
    }

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Filtre de butterworth
    Par Zaazoun dans le forum R
    Réponses: 3
    Dernier message: 10/05/2011, 13h38
  2. Réponses: 0
    Dernier message: 05/05/2011, 10h44
  3. Filtre passe bas second ordre
    Par JohannB dans le forum C++
    Réponses: 2
    Dernier message: 16/06/2010, 10h18
  4. Réponse temporelle d'un filtre de Butterworth
    Par olivier2 dans le forum Signal
    Réponses: 1
    Dernier message: 08/09/2007, 00h36

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