But

 

Le but de ce TP est de réaliser en C/C++ les fonctions effectuant la décomposition d'un signal à l'aide d'un banc de filtres d'analyse et sa reconstruction par banc de filtres de synthèse, c'est à dire par filtrage passe-haut/passe-bas, décimation et interpolation.
On ne considerera que les filtres de Haar et les filtres biorthogonaux 9/7.

On demande d'implanter les fonctions suivantes :

    void analyse_haar(double* x,int p);
  • Effectue la décomposition de Haar "sur place" du signal x.
  • En entrée, x est un signal temporel de longueur p où p est une puissance de 2.
  • En sortie, x contient les résultats de la décomposition de Haar du signal d'entrée. Dans sa première moitié, x contient les coefficients d'approximation et dans sa seconde moitié, x contient les coefficients de détail.
    void synthese_haar(double* x,int p);
  • Effectue la reconstruction "sur place" d'un signal, à partir de ses coefficients x, obtenus par décomposition de Haar. Cette fonction est la réciproque de analyse_haar() (à la précision machine près).
  • En entrée, x de longueur p, où p est une puissance de 2, contient, dans sa première moitié, les coefficients d'approximation et dans sa seconde moitié, les coefficients de détail, obtenus par décomposition de Haar.
  • En sortie, x est le signal temporel reconstruit.
    void analyse_97(double* x,int p);
  • Effectue la décomposition "sur place" du signal x avec les filtres biorthogonaux 9/7.
  • Les paramètres sont les mêmes que analyse_haar().
    void synthese_97(double* x,int p);
  • Effectue la reconstruction "sur place" d'un signal, à partir de ses coefficients x , obtenus par décomposition avec les filtres biorthogonaux 9/7.
  • Les paramètres sont les mêmes que synthese_haar().

On demande aussi de commenter les résultats obtenus et d'afficher les signaux générés à l'aide d'un outil de tracé de courbe comme gnuplot, scilab ou matlab.
Enfin, on veillera à conserver les fonctions définies ci-dessus, car elle seront réutilisées dans la suite des TPs.

Notes

Les fonctions effectuent les transformations sur place, signifiant qu'elles effectuent la transformation directement sur le signal d'entrée. Certaines opérations, comme le produit de convolution, ne sont pas possibles à réaliser directement sur place, et on pourra avoir recours à des tableaux temporaires.
Tous les signaux seront representés en C/C++ par des tableaux de double.
Un mémento des fonctions C ANSI utiles est disponible ici.

TP

 

Selon le schéma classique d'analyse par banc de filtres, on réalise un filtrage passe-bas et passe-haut du signal d'entrée puis une décimation d'un facteur 2 des signaux résultants. De même, la reconstruction par banc de filtres de synthèse se fait par interpolation d'un facteur 2 des coefficients d'approximation et de détail, puis par filtrage passe-bas et passe-haut des signaux résultants. On se propose dans les 3 questions suivantes (indépendantes) de réaliser ces opérations élementaires :

  • interpolation d'un facteur 2
  • décimation d'un facteur 2
  • filtrage

1 - Interpolation d'un facteur 2

Définition
Si y est le signal obtenu par interpolation d'un facteur 2 de x, alors y est simplement défini par : y[2n]=x[n] et y[2n+1]=0.
Le signal résultant a donc une taille 2 fois supérieure à celle du signal original.
TP
Implantez une fonction réalisant l'interpolation d'un facteur 2 d'un signal.

2 - Décimation d'un facteur 2

Définition
La décimation d'un facteur 2 est l'opération quasi-réciproque de l'interpolation d'un facteur 2. Si y est le signal obtenu par décimation d'un facteur 2 de x, alors y est simplement défini par : y[n]=x[2*n].
Le signal résultant a donc une taille 2 fois inférieure à celle du signal original.
TP
Implantez une fonction réalisant la décimation d'un facteur 2 d'un signal.

3 - Filtrage

Définition
Le filtrage d'un signal temporel x par un filtre de réponse impulsionelle finie (RIF) h se fait par calcul du produit de convolution de x avec h, donnant ainsi le signal de sortie y .
Le produit de convolution y = x @ h est défini par :
y[n]=sum(h[k]*x[n-k]) k évolue sur la longueur du filtre h.
Notes
Un filtre h peut être non-causal (existence de valeurs négatives k pour lesquellesh[k]!=0) or il n'est pas possible en C/C++ d'utiliser des index négatifs. Pour résoudre ce problème, on utilisera des tableaux C/C++ _h de taille impaire q répresentant des filtres h par translation d'indice q/2. Ainsi :
  • _h[0] = h[0-q/2]
  • _h[1] = h[1-q/2]
  • ...
  • _h[q/2] = h[0]
  • _h[q/2+1] = h[1]
  • ...
  • _h[q-1] = h[q/2]
TP
Implantez une fonction calculant le produit de convolution d'un signal x de longueur p par un filtre _h de longueur q. On utilisera la symétrie miroir pour gérer les effets de bords.

4 - Banc de filtres d'analyse de Haar

Définition
La décomposition d'un signal x par banc de filtres d'analyse se fait par :
  • filtrage de x par le filtre passe-bas _h0, donnant le signal xb
  • filtrage de x par le filtre passe-haut _h1, donnant le signal xh
  • décimation d'un facteur 2 de xb donnant les coefficients d'approximation xbd
  • décimation d'un facteur 2 de xh donnant les coefficients de détail xhd

Dans le schéma de Haar, les filtres prototypes d'analyse sont :
  • h0[0,1] = [1/sqrt(2) ; 1/sqrt(2)]
  • h1[0,1] = [1/sqrt(2) ; -1/sqrt(2)]

Mais dans l'implantation, on utilisera _h0 et _h1, de taille 3, définis par :
  • _h0 = [1/sqrt(2) ; 1/sqrt(2) ; 0]
  • _h1 = [1/sqrt(2) ; -1/sqrt(2) ; 0]

Enfin, pour des raisons pratiques, on concaténera les coefficients xbd et xhd.
TP
Implantez la fonction void analyse_haar(double* x,int p) définie plus haut.
Calculez les coefficients d'approximation et de détail sur les signaux suivants :
  • signal "rampe" de longueur 256, défini par x[t]=t t=[0:255]
  • signal "leleccum" de longueur 4096, disponible ici.
Affichez et commentez les coefficients obtenus.
Notes
Le fichier "leleccum.txt" est un fichier ASCII de 4096 valeurs de type float. Une conversion float vers double est indispensable car fscanf lit des float.

5 - Reconstruction

Définition
La reconstruction d'un signal à partir de ses coefficients d'approximation xbd et de détail xhd par banc de filtres de synthèse se fait par :
  • interpolation d'un facteur 2 de xbd donnant le signal xbi
  • interpolation d'un facteur 2 de xhd donnant le signal xhi
  • filtrage de xbi par le filtre passe-bas _g0, donnant le signal yb
  • filtrage de xhi par le filtre passe-haut _g1, donnant le signal yh
  • sommation de yb et yh donnant le signal reconstruit y

Dans le schéma de Haar, les filtres prototypes de synthèse sont :
g0[-1,0] = [1/sqrt(2) ; 1/sqrt(2)]
g1[-1,0] = [-1/sqrt(2) ; 1/sqrt(2)]

Mais dans l'implantation, on utilisera _g0 et _g1, de taille 3, définis par :
_g0 = [0 ; 1/sqrt(2) ; 1/sqrt(2)]
_g1 = [0 ; -1/sqrt(2) ; 1/sqrt(2)]
TP
Implantez la fonction void synthese_haar(double* x,int p) définie plus haut.
Reconstruire les signaux "rampe" et "leleccum" à partir de leur coefficients obtenus précédemment.
Affichez, comparez et commentez les signaux reconstruits par rapport aux signaux originaux.

6 - Banc de filtres biorthogonaux 9/7

Définition
Les valeurs des filtres biorthogonaux 9/7 _h0, _h1, _g0 et _g1 sont diponibles ici.
On reprendra les bancs de filtres d'analyse et de synthèse définis plus haut mais en utilisant ces nouveaux filtres.
TP
Commentez les ressemblances entre les filtres _h0, _h1, _g0 et _g1.
Implantez la fonctions void synthese_97(double* x,int p) définie plus haut.
Implantez la fonctions void analyse_97(double* x,int p) définie plus haut.
Décomposez, reconstruisez et analysez les signaux "rampe" et "leleccum".
Comparez les signaux reconstruits par rapports au signaux originaux.
Comparez et commentez les coefficients obtenus par rapport au schéma de Haar.