2015-03-02 10 views
6

Ich implementierte einen einfachen Tiefpassfilter in Matlab mit einem Vorwärts-und Rückwärts-FFT. Es funktioniert im Prinzip, aber die minimalen und maximalen Werte unterscheiden sich vom Original.Matlab Tiefpass Filter mit fft

signal = data; 
%% fourier spectrum 
% number of elements in fft 
NFFT = 1024; 
% fft of data 
Y = fft(signal,NFFT)/L; 
% plot(freq_spectrum) 

%% apply filter 
fullw = zeros(1, numel(Y)); 
fullw(1 : 20) = 1; 
filteredData = Y.*fullw; 

%% invers fft 
iY = ifft(filteredData,NFFT); 
% amplitude is in abs part 
fY = abs(iY); 
% use only the length of the original data 
fY = fY(1:numel(signal)); 
filteredSignal = fY * NFFT; % correct maximum 

clf; hold on; 
plot(signal, 'g-') 
plot(filteredSignal ,'b-') 
hold off; 

das resultierende Bild sieht aus wie dieses

enter image description here

Was mache ich falsch? Wenn ich beide Daten normalisiere, sieht das gefilterte Signal korrekt aus.

+1

Ihr Filter muss symmetrisch sein, wie das Signal ist. Warum erwarten Sie, dass sich min und max nicht ändern? Es gibt keinen Grund dazu. – thang

+2

Beachten Sie, dass der Versuch, einen "Ziegelstein" -Filter wie diesen im Frequenzbereich anzuwenden, unangenehme Artefakte erzeugt - Sie müssen eine glatte Funktion im Frequenzbereich verwenden (normalerweise eine Fensterfunktion). Beachten Sie auch, dass Ihre Filterverstärkung nicht normalisiert ist, und wie Sie wissen, sollte Ihr Filter symmetrisch sein, sonst erhalten Sie komplexe Zeitdomänenausgabedaten. –

Antwort

14

nur uns, wie MATLAB speichert Frequenzinhalt für Y = fft(y,N) zu erinnern:

  • Y(1) ist die Konstante
  • Y(2:N/2 + 1) ist die Menge der positiven Frequenzen
  • Y(N/2 + 2:end) ist die Menge der negativen Frequenzen versetzt .. (normalerweise würden wir dies links der vertikalen Achse zeichnen)

Um einen echten Tiefpassfilter zu machen, müssen wir die niedrigen Frequenzen und die niedrigen negativen Frequenzen beibehalten.

Hier ist ein Beispiel dafür in der Frequenzdomäne mit einem multiplikativen Rechteck-Filter zu tun, wie du getan hast:

% make our noisy function 
t = linspace(1,10,1024); 
x = -(t-5).^2 + 2; 
y = awgn(x,0.5); 
Y = fft(y,1024); 

r = 20; % range of frequencies we want to preserve 

rectangle = zeros(size(Y)); 
rectangle(1:r+1) = 1;    % preserve low +ve frequencies 
y_half = ifft(Y.*rectangle,1024); % +ve low-pass filtered signal 
rectangle(end-r+1:end) = 1;   % preserve low -ve frequencies 
y_rect = ifft(Y.*rectangle,1024); % full low-pass filtered signal 

hold on; 
plot(t,y,'g--'); plot(t,x,'k','LineWidth',2); plot(t,y_half,'b','LineWidth',2); plot(t,y_rect,'r','LineWidth',2); 
legend('noisy signal','true signal','+ve low-pass','full low-pass','Location','southwest') 

enter image description here

Die vollständige Tiefpass fitler eine bessere Arbeit, aber sie Ich werde feststellen, dass die Rekonstruktion ein bisschen "wellig" ist. Dies liegt daran, dass die Multiplikation mit einer Rechteckfunktion in der Frequenzdomäne dieselbe wie eine convolution with a sinc function in the time domain ist. Eine Faltung mit einer Sinc-Funktion ersetzt jeden Punkt mit einem sehr ungleichen gewichteten Durchschnitt seiner Nachbarn, daher der "Wellen" -Effekt.

Ein Gaußfilter hat bessere Tiefpassfiltereigenschaften, weil the fourier transform of a gaussian is a gaussian. Ein Gaussian zerfällt auf Null, so dass keine fernen Nachbarn im gewichteten Durchschnitt während der Faltung enthalten sind. Hier ist ein Beispiel mit einem Gaußschen Filter, um die positiven und negativen Frequenzen zu bewahren:

gauss = zeros(size(Y)); 
sigma = 8;       % just a guess for a range of ~20 
gauss(1:r+1) = exp(-(1:r+1).^ 2/(2 * sigma^2)); % +ve frequencies 
gauss(end-r+1:end) = fliplr(gauss(2:r+1));   % -ve frequencies 
y_gauss = ifft(Y.*gauss,1024); 

hold on; 
plot(t,x,'k','LineWidth',2); plot(t,y_rect,'r','LineWidth',2); plot(t,y_gauss,'c','LineWidth',2); 
legend('true signal','full low-pass','gaussian','Location','southwest') 

enter image description here

Wie Sie sehen können, die Rekonstruktion ist viel besser so.

+1

Sehr schöne Erklärung. Ich gebe zu, dass ich dazu tendiere zu vergessen, dass der Fourier-Raum gefaltet ist und auf beiden Seiten gefiltert werden muss. –