Vous êtes sur la page 1sur 7

TP 1 Matlab et applets Fourier et ondelettes 1D M2 Pro IIA - 01/12/2009 1) Installation

- Vous devez tlcharger 2 toolbox (pour Matlab) ces adresses : http://www.ceremade.dauphine.fr/~peyre/numerical-tour/tours/toolbox_general.zip http://www.ceremade.dauphine.fr/~peyre/numerical-tour/tours/toolbox_signal.zip - Dzippez-les dans C:/Program Files/Matlab/toolbox toolbox_general/ et toolbox_signal/) (vous obtenez deux rpertoires :

- Pour le TP, vous pouvez crer un fichier texte nomm par exemple tp1.m dans lequel vous crirez toutes les commandes Matlab demandes (pour en garder la trace). Vous navez qu lancer tp1; dans Matlab pour excuter vos commandes. - Avant de dmarrer, vous devez excuter cette ligne dans Matlab :
getd = @(p)path(path,p);

- Puis il va falloir ajouter nos 2 toolboxes au PATH, pour cela il faut dire Matlab daller dans le rpertoire C:/Program Files/Matlab/toolbox (avec la commande cd), puis ajouter ces 2 lignes :
getd('toolbox_signal/'); getd('toolbox_general/');

2) Commandes de base de Matlab


% a b c d A B C c

Crer une variable, un tableau :


ceci est un commentaire = 1; a = 2+1i; = [1 2 3 4]; = [1; 2; 3; 4]; = 1:2:7; = eye(4); = ones(4); = rand(4); = b'; % nombre rel et complexe % vecteur ligne % vecteur colonne % on a d=[1 3 5 7] % matrice identit % matrice constante 1 % matrice alatoire % transpose

Modification de vecteurs et matrices


% accder une entre de matrice, de vecteur % accder un ensemble d'indices % accder au derniers indices % renverser un vecteur % classer des valeurs % mettre zro les entres plus petites que 2 % supprimer la 3me entre du vecteur % cr une matrice de taille 2x4 % accde la 2me colonne

A(2,2) = B(1,1) + b(1); b(1:3) = 0; b(end-2:end) = 1; b = b(end:-1:end); b = sort(b); b = b .* (b>2); b(3) = []; B = [b; b]; c = B(:,2);

Commandes avances
% fonction usuelles % afficher l'aide d'une fonction % parties relles et imaginaires % module et phase % affichage % afficher une valeur avec 2 dcimales

a = cos(b); a = sqrt(b); help MakeSignal; a = real(b); a = imag(b); a = abs(b); a = angle(b); disp('bonjour'); disp( sprintf('Valeur de x=%.2f', x) );

Affichage

plot( 1:10, (1:10).^2 ); % affichage d'une fonction 1D title('Mon titre'); % le titre xlabel('variable x'); ylabel('variable y'); % les axes subplot(2, 2, 1); % divise l'cran en 2x2 et slectionne le 1er quadrant

Programmation % boucle rpte pour i=1, i=2, i=3 et i=4 % faire une action

for i=1:4 disp(i); end i = 4; while i<5 disp(i); i = i-1; end

% idem mais avec un while % faire une action

3) Charger et dessiner des signaux


Les signaux sont des vecteurs 1D, habituellement stocks sous forme de tableaux (n,1), o n est le nombre dchantillons. Pour charger un signal (on va faire appel au fichier load_signal.m et la fonction load_signal) :
f = load_signal('Piece-Regular', n);

% signal de taille n=100 par exemple

On peut alors changer lchelle des entres du signal, et passer [0,1] :


f = rescale(f);

Afficher le signal :
clf; % efface la courbe prcdente plot(f); % affiche axis('tight'); % change les bornes des axes pour sadapter la taille des donnes title('My title'); % titre set_label('variable x', 'variable y'); % nom des axes

On peut aussi afficher plusieurs figures en utilisant subplot :


subplot(2, 2, 1); plot(f); axis('tight'); subplot(2, 2, 4); plot(f.^2); axis('tight'); % divise lcran en 2x2 et slectionne le 1er quadrant % slectionne le dernier quadrant

Essayer les signaux suivants (dfinis dans lune des toolboxes) : 'regular', 'step', 'rand'
g = load_signal('regular', 100); plot(1:100, g); h = load_signal('step', 10); plot(1:10, h); % 1:10 chelle de laxe des x % A FAIRE : changer les valeurs de laxe y (grce aux options de la fentre), pour mieux voir le signal i = load_signal('rand', 100); plot(i); % A FAIRE : excuter ces lignes plusieurs fois et vrifier que le signal nest jamais le mme (fonction alatoire) help load_signal % pour voir les autres signaux disponibles

On peut afficher plusieurs signaux dans une mme fentre (pour plus facilement les comparer) :
clf; plot(1:100, [g i]'); legend('signal regular', 'signal rand');

Dessiner une sinusode :


x = 1:0.01:10; y = sin(x); plot(x, y); % vecteur dchantillonnage du signal et chelle de laxe des x

Exercice 1 : A partir de la sinusode prcdente, changez son chantillonnage et sa frquence. Regardez le rsultat laffichage. En utilisant des sommes de sinusodes, essayez de retrouver la courbe du cours (transparent 15).

4) Sries de Fourier en 1D : applet


On va revenir sur une applet pour bien comprendre la dcomposition en sries de Fourier. Applet : http://www.falstad.com/fourier/ On commence par afficher les fonctions sinus et cosinus (boutons Sine et Cosine ) : la fonction saffiche dans la partie haute. Les 2 autres parties graphiques du dessous montrent la dcomposition en sinus et cosinus de la fonction affiche (dcomposition en sries de Fourier). Chaque composante en sinus et cosinus est caractrise par sa frquence et son amplitude (on les visualise en passant la souris dessus). Q1 : Essayer avec dautres fonctions que sinus et cosinus (la souris vous permet de modifier chaque fonction prdfinie, votre guise) et regardez les composantes frquentielles. Le transparent 16 du cours vous montre 2 diffrentes faons de dcomposer une fonction en sries de Fourier :

Ici on peut afficher soit les amplitudes des composantes en cosinus et sinus, soit lamplitude du cosinus et sa phase associe. Regardez la diffrence. Q2 : Repartez de la fonction sinus et regardez leffet du dphasage sur les composantes frquentielles (bouton Phase Shift ). Q3 : La case cocher Log View vous permet de visualiser le logarithme de lamplitude, on peut alors visualiser lensemble des dB de chaque composante. Regardez cela sur le signal Noise .

5) Transforme de Fourier en 1D

Calcul de la transforme de Fourier et affichage :

ff = fft(f); % transforme de Fourier 1D du signal f (dans le plan complexe) ff = fft(f,1024); % transforme de Fourier 1D du signal f, sur 1024 points rgulirement distribus dans [0,1] plot(fftshift(abs(ff))); % fftshift : pour afficher les basses frquences au centre f1 = real(ifft(ff)); % transforme inverse 1D

Exercice 2 : Tapez ceci dans la fentre de commande :


lookfor fourier

% affiche toutes les fonctions relies Fourier

Ensuite, utilisez "help" suivi du nom de la fonction qui vous intresse pour avoir plus d'informations sur chacune delles. Exercice 3 : Pour trouver des chantillons de la transforme de Fourier d'un signal, il faut utiliser la fonction "fft". Tapez dans la fentre de commande les lignes suivantes :
figure(1) T = 0.01; Fs = 1/T; % priode d'chantillonnage % frquence d'chantillonnage de 100 Hz

t = 0:T:1; x = sin(2*pi*10*t); plot(t,x) title('Signal') xlabel('temps (ms)')

% vecteur dchantillonnage du signal et chelle de laxe des x % signal ayant une frquence de 10 Hz

Q1 : Regardez le rsultat avec dautres frquences dchantillonnage (en diminuant T avec par exemple 0.001). Que remarquez-vous ? Changez aussi la frquence de la sinusode (5, 2, au lieu de 10). Maintenant tapez ceci :
figure(2) FFT_size = 2048; X = fft(x,FFT_size); f = (0:FFT_size/2)/(FFT_size/2)*Fs/2; plot(f, abs(X(1:FFT_size/2+1))); title('Signal en frquence'); xlabel('Frquence(Hz)'); ylabel('Amplitude');

% on voit bien que le signal est 10 Hz

Remarquez la composante 10 Hz. Remarquez aussi qu'en utilisant "figure(1)" et "figure(2)" il a t possible d'afficher des courbes dans des fentres diffrentes. Q2 : Quelle est la taille de f, de X ? A quoi sert f ? A quoi sert linstruction : X(1:FFT_size/2+1) ? Q3 : Regardez la phase, la partie relle et imaginaire de X. Q4 : Pourquoi nobserve-t-on pas une simple composante frquentielle 10 Hz ? Comparer avec le rsultat de lapplet situe cette adresse : http://www.dsptutor.freeuk.com/analyser/SpectrumAnalyser.html en choisissant la fonction sinus, de frquence 1000 Hz. Regardez le signal et son spectre, puis baisser la frquence 100 puis 10 Hz en faisant varier le nombre dchantillons ( Number of samples ). Que constatez-vous ? Exercice 4 : Transforme de Fourier inverse (ifft). Essayez ceci avec le signal dfini auparavant :
inv = ifft(fft(x)); plot(t, inv)

Que constatez-vous ? Exercice 5 : Le but est de retrouver les composantes frquentielles dun signal quon aura bruit. Pour cela, on considre des donnes chantillonnes 1000 Hz. A partir dun signal contenant 2 sinusodes : - une premire de frquence 50 Hz et damplitude 0.7 - et une seconde de frquence 120 Hz et damplitude 1 On va y ajouter un bruit alatoire de moyenne nulle (modle de bruit Gaussien additif) :
Fs = 1000; % T = 1/Fs; % L = 1000; % t = (0:L-1)*T; % % Sum of a 50 Hz sinusoid and a 120 Hz sinusoid x = 0.7*sin(2*pi*50*t) + sin(2*pi*120*t); y = x + 2*randn(size(t)); % plot(Fs*t(1:50), y(1:50)) title('Signal Corrupted with Zero-Mean Random Noise') xlabel('time (milliseconds)') Sampling frequency : 1000 Hz Sample time Length of signal Time vector

Sinusoids plus noise

Questions sur ce programme : Q1 : Comment pourriez-vous crire autrement ceci : t = (0:L-1)*T; ? Testez-le. Q2 : Quelle est la taille de t, de x ? Q3 : Que reprsente t(1:50) ? Quelle est sa taille ? Que reprsente Fs*t(1:50) ? Q4 : Visualisez le signal sans le bruit ou en faisant varier lamplitude du bruit (essayez avec 0.1).

Il est difficile didentifier les composantes frquentielles en regardant le signal original. En le convertissant dans le domaine des frquences, la Transforme de Fourier discrte du signal bruit y est obtenue grce la FFT (Fast Fourier Transform) :
NFFT = 2^nextpow2(L); % Next power of 2 from length of y Y = fft(y, NFFT)/L; f = Fs/2*linspace(0,1,NFFT/2+1); plot(f, 2*abs(Y(1:NFFT/2+1))) % Plot single-sided amplitude spectrum title('Single-Sided Amplitude Spectrum of y(t)') xlabel('Frequency (Hz)') ylabel('|Y(f)|')

Q5 : Que fait la fonction nextpow2 ? Que vaut NFFT ? Q6 : Que fait la fonction linspace ? Que vaut linspace(0,1,NFFT/2+1)? Affichez-le. A cause du bruit, les amplitudes ne sont pas exactement gales 0.7 et 1. Si on lanait plusieurs fois ce code (en recalculant chaque fois y), cela produirait diffrentes approximations des amplitudes 0.7 et 1. Lautre raison est le fait davoir un signal de taille finie. Si on augmentait L de 1000 10000, on aurait de meilleures approximations en moyenne. Q7 : Essayez cela. Q8 : En vous servant de lapplet prcdente, essayez de retrouver ces observations. (http://www.dsptutor.freeuk.com/analyser/SpectrumAnalyser.html) Exercice 6 : Pour bien se rendre compte des frquences contenues dans un son, allez regarder les applets cette adresse : http://ptolemy.eecs.berkeley.edu/eecs20/berkeley/body.html. Dans le menu de gauche, slectionner litem Sound , puis regarder les applets correspondant aux items Sound displayer , Live sound , Sound spectrum et Quantization .

6) Analyse de Fourier locale sur un son


Un son est un signal 1D qui peut tre localement oscillant ou stationnaire. Une analyse de Fourier est alors utile pour tudier les proprits du son, comme son amplitude et sa frquence. On commence par charger un son (fichier .wav), en ne considrant quune partie des chantillons :
n = 1024*16; % on slectionne par exemple 1024 chantillons (les chantillons sont cods sur 16 bits) options.n = n; [x,fs] = load_sound('bird', n); % charge un son partir dun fichier et stocke dans un vecteur 2 lignes :

le signal x (1re ligne) et sa frquence dchantillonnage fs (2me ligne).


fs;

% doit renvoyer 44100 : cest la frquence dchantillonnage dun son wav : 44,1 kHz

Essayer avec drum, female, male, glockenspiel. Pour jouer un son :


sound(x(:)',fs); % joue le vecteur x(:) (avec la frquence dchantillonnage fs)

On peut afficher le son :


clf; plot(1:n,x); axis('tight'); set_graphic_sizes([], 20); title('Signal');

% largit la taille de la police

Des zooms locaux sur le son montrent ses oscillations :


p = 512; t = 1:n; clf; sel = n/4 + (0:p-1); %slectionner une partie des chantillons : partir du n/4me et en ne prenant que 512 chantillons

subplot(2,1,1); plot(t(sel),x(sel)); axis tight;

%dessine les sel chantillons

sel = n/2 + (0:p-1); %slectionner une partie des chantillons : partir du n/2me et en ne prenant que 512 ch subplot(2,1,2); plot(t(sel),x(sel)); axis tight;

Short Time Fourier transform (STFT) : un spectrogramme est lensemble des transformes de Fourier locales calcules sur des points espacs uniformment (fonction fft du signal fentr). Exercice 7 : Pour obtenir la STFT on calcule la fft sur le signal x fentr (x.*h), o h est une fonction fentre lisse (par exemple une gaussienne), situe autour dun point t0. En faisant varier t0 et la frquence (modulation), on obtient lensemble des atomes ncessaire la production du spectrogramme. Si les atomes (fentres) se recouvrent, on a une transforme redondante. Q1 : Tapez help perform_stft pour voir ce que fait cette fonction. Q2 : Les seuls paramtres lui passer sont la taille de la fentre et le recouvrement :
w = 64*2; q = w/2; % size of the window % overlap of the window

On peut alors calculer un spectrogramme du son, pour voir ses frquences locales dans le domaine de Fourier. Le nombre de fentres utilise est (n-q)/(w-q).
S = perform_stft(x,w,q, options);

Pour voir plus clairement lvolution des harmoniques, on peut afficher le spectrogramme en prenant le log des coordonnes. Le haut du spectrogramme correspond aux basses frquences.
clf; imageplot(abs(S)); axis('on'); plot_spectrogram(S,x); % display the spectrogram % display log spectrogram

7) Dbruiter un son
On cr dabord un signal bruit (simple additive Gaussian noise) :
sigma = .2; xn = x + randn(size(x))*sigma; % on pourra essayer aussi avec sigma = 0.07

Ecoutez le son bruit :


sound(xn,fs);

Dessinez le son :
clf; subplot(2,1,1); plot(x); axis([1 n -1.2 1.2]); set_graphic_sizes([], 20); title('Original signal'); subplot(2,1,2); plot(xn); axis([1 n -1.2 1.2]); set_graphic_sizes([], 20); title('Noisy signal');

On peut raliser le dbruitage par seuillage non-linaire sur le domaine frquentiel. Seuillage faible ou fort Un seuillage est une function non-linaire 1D appliqu chaque coefficient de Fourier ou dondelettes. Les seuillages principaux sont appels hard thresholding et soft thresholding.

Exercice 8 : Seuillage sur la STFT laide de la fonction perform_thresholding. Q1 : Tapez help perform_thresholding pour voir ce que fait cette function. On peut seuiller le spectrogramme dfini prcdemment ( hard thresholding) par les commandes suivantes :
% perform thresholding Sn = perform_stft(xn,w,q, options); SnT = perform_thresholding(Sn, 2*sigma, 'hard'); % display the results subplot(2,1,1); plot_spectrogram(Sn); subplot(2,1,2); plot_spectrogram(SnT);

Q2 : Rcrivez le seuillage avec le soft thresholding et comparez avec le premier. Faire varier sigma en prenant des valeurs dans lintervalle [0.05, 0.5]. Quelles sont les diffrences ? Q3 : Reconstruisez le signal partir des seuillages utiliss prcdemment (fonction perform_stft). Vrifiez le rsultat en coutant le son dbruit. Que concluez-vous propos de la qualit du signal dbruit ? On peut aussi mesurer la qualit du signal dbruit grce la fonction snr (calcul de lerreur quadratique moyenne entre les 2 signaux) Exercice 9 : Faire de mme avec la transforme en ondelettes, laide de la fonction (gnralement, elle respecte mieux les singularits du signal).

perform_wavelet_transf

Q1 : Tapez help perform_wavelet_transf pour voir ce que fait cette function et quelles ondelettes elle utilise. Voici comment on calcule les coefficients dondelettes du signal bruit :
options.ti = 0; Jmin = 4; xW = perform_wavelet_transf(x,Jmin,+1,options);

% chelle minimum de transformation % calcule la transforme jusqu' l'chelle Jmin

Q2 : Calculez plusieurs seuillage hard et soft et affichez-les. On utilisera : plot_wavelet(xW,Jmin); axis([1 n -1 1]); pour afficher les coefficients dondelettes Q3 : Reconstruisez le signal partir des seuillages utiliss prcdemment. Vrifiez le rsultat en coutant le son dbruit et comparez avec la STFT.