WICHTIG: Der Betrieb von goMatlab.de wird privat finanziert fortgesetzt. - Mehr Infos...

Mein MATLAB Forum - goMatlab.de

Mein MATLAB Forum

 
Gast > Registrieren       Autologin?   

Partner:




Forum
      Option
[Erweitert]
  • Diese Seite per Mail weiterempfehlen
     


Gehe zu:  
Neues Thema eröffnen Neue Antwort erstellen

Filterung und FFT passen nicht immer zusammen

 

Pepsi

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 27.09.2012, 15:01     Titel: Filterung und FFT passen nicht immer zusammen
  Antworten mit Zitat      
hallo an alle wissende

ich bin hier schon ewig am rumprobieren und habe einen neuen rückschlag, bei dem ich alleine nicht weiter komme...

also ich hab ein zeitsignal, welches ich durch eine FFT mit fenster transformiere und anschließend noch ein BP anwenden will. das funktionierete auch bisher. umindest solange ich es nur auf einen kleinen signalausschnitt angewendet habe( L= 6000) bei deutlich längeren signalen (L=250000) haut dann mein bandpass nciht mehr hin, weil die Vektorlängen nicht emhr überein stimmen.

sicher hat es was damit zu tun, dass man ja für die fft mit
N=2^nextpow(L)
arbeitet, so dass sich die vektorlänge des amplitudengangs immer ändert. aber ich hab jetzt keinen ansatz, wie ich das auf meine zeit-signale umwandle. irgendwie muss sich dass ja für den bandpass auch anpassen lassen... will das programm später in einer gui anwenden, sowohl, wenn ich nur einen ausschnitt betrachte, als auch für das gesamte zeitsignal...

hier der code

Code:

% Laden des Files
%-----------------------------------

filename = uigetfile ('*.xls','Auswahl der gewünschten Zeitreihe');
[nums, txt] =xlsread(filename);

%----------------------------------
%Zeitbereich
% ----------------------------------
x =nums(:,1);           % x-Vektor
y =nums(:,2);           % y-vektor

Ta = 6.65e-6;                % Abtastrate
fa = 1/Ta;                   % Abtastfrequenz
fn = fa/2;                   % Nyquistfrequenz
L = length(x);               % Länge des Zeitsignals
N = 2^nextpow2(L);           % gewünschte FFT-Länge (N=2^x, sonst wird der DFT-Algorithmus verwendet!)
df = fa/N;                   % Frequenzauflösung                                          



%---Darstellung Datensatz ---

% max. Amplitude zur Skalierung der graphischen Darstellung feststellen:
max_y = max(abs(y))*1.1;
fig = figure(1);                                                                             %fig 1
plot(x,y);
%axis([0 N -max_y max_y])
title('Zeitreihe')
ylabel('Spannung')
xlabel('Zeit')
grid



%------------------------------------------------------------------------------
% Frequenzbereich
% ----------------------------------------------------------------------------



% Berechnung der FFT
% ------------------
H = fft(y, N);                                                                          
% Berechnung des Amplitudengangs aus dem komplexen Frequenzvektor H:
amplH = abs(H);


% Graphische Darstellung
% ------------------------------------
% Frequenzvektoren (werden bei der graphischen Darstellung benötigt):
x_fn = 0 : df : fn-df;
x_fa = 0 : df : fa-df;

%-----------------------
% Fensterfunktion
% ----------------------

% Anhang an die bereits erfolgte Untersuchung
% -------------------------------------------

win = hann(L)';                                                                          

y_win = y'.*win; % Fensterung ohne Amplitudenkorrektur
%y_win = y'.*win*N/sum(win); % Fensterung mit Amplitudenkorrektur
max_y = max(abs(y_win))*1.1;

% Berechnung der FFT
% ------------------
H = fft(y_win, N);
% Berechnung des Amplitudengangs aus dem komplexen Frequenzvektor H:
amplH = abs(H);


% Darstellung des interessierenden Frequenzbereichs des Amplitudengangs (0...fn) und
% daran angepasste Amplitudenskalierung (Normierung auf N/2):
%-------------------------------------------------------------------------------

amplitudengang = [amplH(1)/N amplH(2:N/2)/(N/2)]; % DC-Bin auf N normieren!  
 
fig = figure(fig+1);                                                                        %fig
plot(x_fn, amplitudengang);

title('Amplitudengang nach Fensterung')
ylabel('Amplitude')
xlabel(['Auflösung: ',num2str(df),' Hz Frequenz in Hz'])
grid

%-----------------------------
% Bandpass
%-----------------------------
%Ordnung n:
n = 10000; % Anzahl der Nullstellen in der kompl. Ebene

pass1 = 1000; % -6 dB – Grenzfrequenz in Hz
pass2 = 28000; % -6 dB – Grenzfrequenz in Hz
Wn = [pass1/fn pass2/fn];
FIRkoeff = fir1(n, Wn, 'bandpass'); % BP-Filter

% Zunächst den Nennerkoeffizientenvektor erstellen:
% (nötig zur korrekten Rechnung mit freqz, grpdelay, zplane)
a = zeros(size(FIRkoeff)); % oder:
%a = zeros(1, n+1);
a(1) = 1;
% freqz über Aufruf mit Koeffizientenvektoren
cntW = 4096;
% Standardmäßig (ohne zusätzliche Parameterangabe cntW) werden nur 512 Frequenzpunkte
% berechnet!
[Hfir, Wfir] = freqz(FIRkoeff, a, cntW); % mit 0 <= Wfir <= pi
%df = Wfir(2)/pi*fn; % oder: df = fn/length(Wfir);
% df (delta_f) ist der Abstand zwischen den Frequenzpunkten in Hz
% d.h. df entspricht der Frequenzauflösung in Hz
amplFIR = abs(Hfir);
phaseFIR = angle(Hfir);


% Darstellung des Amplitudengangs (linear):
fig = figure(fig+1);                                                                            %fig
plot(x_fn, amplFIR, 'b');
%plot(Wfir/pi*fn, amplFIR, 'b');
axis([0 fn -0.1 1.1]);
title('Amplitudengang des FIR-Filters')
ylabel('Verstärkung')
xlabel(['Auflösung: ',num2str(df),' Hz Frequenz in Hz'])
hold on;
plot(Wn*fn,1,'rx')
hold off;

%multiplikation mit frequenzgang
y_BP = amplitudengang'.*amplFIR;

fig = figure(fig+1);                                                           %fig                                                                    %fig
plot(x_fn, y_BP);
xlim([pass1 pass2]) ;

 


DSP
Forum-Meister

Forum-Meister



Beiträge: 2.117
Anmeldedatum: 28.02.11
Wohnort: ---
Version: R2014b
     Beitrag Verfasst am: 27.09.2012, 20:14     Titel:
  Antworten mit Zitat      
Das Problem liegt vermutlich in der Faltung des Signals mit der Impulsantwort des Filters. Es ist richtig, dass diese im Freq.-bereich in eine Multiplikation übergeht. Allerdings muss man dabei eine zyklische Faltung vermeiden, da sonst Fehler entstehen. Dazu müssen die Längen von Signal und Impulsantw. gleich sein. Schau mal hier bei der Funktion Faltung...

http://www.gomatlab.de/window-sinc-filter-t19156.html
Private Nachricht senden Benutzer-Profile anzeigen
 
Pepsi

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 01.10.2012, 12:46     Titel:
  Antworten mit Zitat      
Hab überlegt, das Problem mit zero padding zu umgehen. Also meinen Bandpass einfach mit Nullen am Ende aufzufüleln, damit die Signale gleich lang sind.

Code:

amplFIR = [amplFIR, zeros(length(x_fn) - length (amplFIR))];
 


Jetzt kommt folgender Fehler:

??? Error using ==> zeros
Maximum variable size allowed by the program is exceeded.

Error in ==> fft_fenster at 194
amplFIR = [amplFIR, zeros(length(x_fn) - length (amplFIR))];

Habe ich jetzt wirklich die Den Speicher gesprengt? amplFIR soll doch nicht größer sein als x_fn... Hier hakt das Verständnis mal wieder... =/
 
Jan S
Moderator

Moderator


Beiträge: 11.057
Anmeldedatum: 08.07.10
Wohnort: Heidelberg
Version: 2009a, 2016b
     Beitrag Verfasst am: 01.10.2012, 15:32     Titel:
  Antworten mit Zitat      
Hallo Pepsi,

Du kannst Deinen Befehl ja zunächst mal in Einzelteile zerlegen und schauen, was genau passiert:
Code:
tmp1 = length(x_fn) - length(amplFIR);
tmp2 = zeros(tmp1);
amplFIR = [amplFIR, tmp3];


Wenn tmp1 z.B. 1000 ist, erzeugt "zeros(tmp1)" eine [1000x1000] Matrix. Das wird mit etwa 8MB Speicherplatz noch nichgt den Speicher sprengen, aber ich vermute, Dein tmp1 ist deutlich größer, und Du wolltest eigentlich einen Vektor erstellen, also:
Code:
tmp2 = zeros(1, tmp1)

Gruß, Jan
Private Nachricht senden Benutzer-Profile anzeigen
 
DSP
Forum-Meister

Forum-Meister



Beiträge: 2.117
Anmeldedatum: 28.02.11
Wohnort: ---
Version: R2014b
     Beitrag Verfasst am: 01.10.2012, 15:53     Titel:
  Antworten mit Zitat      
Mal abgesehen von diesem Fehler ist das zeropadding so immer noch nicht korrekt, bzw. die Faltung liefert dir wieder ein falsches Ergebnis.

Du musst den Faltungssatz beachten...

Aus dem Signal x[n] der Länge n und der Imulsantwort h[m] der Länge m wird ein Ausgangssignal y der Länge n + m - 1!

Daher müssen vor der Transformation die beiden Signal x und h auf die Länge n+m-1 durch zeropadding gebracht werden. Siehe die Funktion FFT_Faltung.m aus dem Link. Nur so wird eine zyklische Faltung vermieden. Der Nachteil dieser Methode ist, dass dadurch eben viele Nullen angefügt werden müssen, vor allem wenn n>>m ist. Hierzu gibt es dann gesonderte Verfahren (Overlap Add/Save) wodurch das Zeropadding reduziert werden kann, da das Signal x in Segmente geteilt wird. Aber hier sind dann Korrekturen an den Enden der Segmente notwendig um das richtige Ergebnis zu erhalten.
Private Nachricht senden Benutzer-Profile anzeigen
 
Pepsi

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 01.10.2012, 16:08     Titel:
  Antworten mit Zitat      
ah, ok danke! ich werd mich die tage mal ransetzen und schauen, dass ich das hinbekomme! vielen dank schonmal
 
Pepsi

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 02.10.2012, 15:02     Titel:
  Antworten mit Zitat      
also die variante mit dem zero-padding hat sich in diesem fall wohl erledigt...

durch die deutlich größere länge des signals verringert sich die frequenzauflösung. da sich amplFIR jedoch nicht ändert (was ich nicht ganz verstehe, weil ich sich fn ja anpassen müsste...?), kommt es zur verschiebung der grenzfrequenzen im amplitudengang meines bp-filters (zumindest, so wie es oben programmiert ist)...

da kommt man wohl um die faltung nciht drum rum...
 
DSP
Forum-Meister

Forum-Meister



Beiträge: 2.117
Anmeldedatum: 28.02.11
Wohnort: ---
Version: R2014b
     Beitrag Verfasst am: 02.10.2012, 15:11     Titel:
  Antworten mit Zitat      
Das kann nicht sein...da bist du auf dem Holzweg. Du darfst das fn eben nicht ändern...das ändert sich nämlich auch gar nicht. Die Abtastfrequenz fs bleibt ja immer noch gleich.

Die Freq.-auflösung df = fs/N (N= Anzahl Messwerte)

nur diese ändert sich durch Zeropadding.

Nutze die Funktion FFT_Faltung.m aus dem oben angegebenen Link bzw. siehe Code unten. Du kannst das Ergebnis sowohl mit den Matlab Funktionen conv wie auch filter vergleichen und wirst sehen, dass sie identsich sind (mal abgesehen von der Länge des Ergebnisvektors). Die Funktion filter schneidet den Ausschwingvorgang einfach ab...tatsächlich hat das Ergebnis aber die Länge n+m-1.

Außerdem darfst du doch nicht nur die Beträge für die Multiplikation nehmen. Du musst den Ergebnisvektor mit Real- und Imaginärteil aus der FFT für die Faltung nehmen.

Code:

function output = FFT_Faltung(sig1, sig2)
% Die Funktion führt eine schnelle Faltung mittels FFT aus
% Input:
% sig1 = Messsignal
% sig2 = Filter-Impulsantwort
% Output:
% output = gefiltertes Messignal
%--------------------------------------------------------------------------

% kopieren der Eingangsvektoren
sig1 = double(sig1(:));
sig2 = double(sig2(:));

% Faltungssatz sig(m) * h(n) = output(m+n-1):
outlength = length(sig1)+length(sig2)-1;
% nächste Zweierpotenz für FFT
fftsize = 2^nextpow2(outlength);

% Messsignal
% mit Nullen auf fftsize auffüllen
sig1 = [sig1; zeros(fftsize-length(sig1),1)];
%Berechnung des Frequenzspektrums
sig1 = fft(sig1,fftsize);

% Filter - Impulsantwort
% mit Nullen auf fftsize auffüllen
sig2 = [sig2; zeros(fftsize-length(sig2),1)];
% Berechnung des Frequenzspektrums
sig2 = fft(sig2,fftsize);
 
% Faltung durch Multiplikation der Spektren
% Rücktransformation in den Zeitbereich
conv_raw = ifft(sig1.*sig2);

% Rückgabe Ergebnis
output = transpose(conv_raw(1:outlength));
 
Private Nachricht senden Benutzer-Profile anzeigen
 
Pepsi

Gast


Beiträge: ---
Anmeldedatum: ---
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 08.10.2012, 16:28     Titel:
  Antworten mit Zitat      
hey...

hatte die letzten tage viel anderes zu tun, aber hab mcih jetzt nochmal in ruhe rangesetzt... das mit der faltung funktioniert wunderbar, wer hätte es gedacht Embarassed

für alle, die auch dran hängen hier mein code an den oben beschriebenen auszug angepasst mit den plots zur veranschaulichung:

Code:

clear all;

% Laden des Files
%-----------------------------------

filename = uigetfile ('*.xls','Auswahl der gewünschten Zeitreihe');
[nums, txt] =xlsread(filename);

%----------------------------------
%Zeitbereich
% ----------------------------------                                                      
x =nums(:,1);           % x-Vektor                                                        %Zeitsignal
y =nums(:,2);           % y-vektor

Ta = 6.65e-6;                % Abtastrate
fa = 1/Ta;                   % Abtastfrequenz
fn = fa/2;                   % Nyquistfrequenz
L = length(x);               % Länge des Zeitsignals
N = 2^nextpow2(L);           % gewünschte FFT-Länge (N=2^x, sonst wird der DFT-Algorithmus verwendet!)
df = fa/N;                   % Frequenzauflösung                                          



%---Darstellung Datensatz ---

% max. Amplitude zur Skalierung der graphischen Darstellung feststellen:
%max_y = max(abs(y))*1.1;
fig = figure(1);                                                                             %fig 1
plot(x,y);
%axis([0 N -max_y max_y])
title('Zeitreihe')
ylabel('Spannung')
xlabel('Zeit')
grid



%------------------------------------------------------------------------------
% Frequenzbereich
% ----------------------------------------------------------------------------


% Fensterfunktion - Hanning
% ----------------------

% Anhang an die bereits erfolgte Untersuchung
% -------------------------------------------

win = hann(L)';                                                                          

y_win = y'.*win; % Fensterung ohne Amplitudenkorrektur                                       %gefenstertes Singal
%y_win = y'.*win*N/sum(win); % Fensterung mit Amplitudenkorrektur


% Bandpass
%-----------------------------
%Ordnung n:
n = 10000; % Anzahl der Nullstellen in der kompl. Ebene
%fa = ...       % siehe oben
%fn = fa/2;     % Nyquistfrequenz

pass1 = 1000; % -6 dB – Grenzfrequenz in Hz
pass2 = 28000; % -6 dB – Grenzfrequenz in Hz
Wn = [pass1/fn pass2/fn];
FIRkoeff = fir1(n, Wn, 'bandpass'); % BP-Filter                                             %Filter-Impulsantwort          

%Faltung
%----------------------------------------------

% Faltungssatz sig(m) * h(n) = output(m+n-1):
outlength = length(y_win)+length(FIRkoeff)-1;
% nächste Zweierpotenz für FFT
fftsize = 2^nextpow2(outlength);
df_falt = fa/fftsize;

% Messsignal
% mit Nullen auf fftsize auffüllen
tmp1=fftsize-length (y_win);
tmp2= zeros (1,tmp1);
y_win1 = [y_win, tmp2];  
%Berechnung des Frequenzspektrums
y_win_fft = fft(y_win1,fftsize);

ampl_y = abs(y_win_fft);                                                                     %FFT Messsignal
%amplitudengang1 = fftshift(ampl_y/fftsize);

% Frequenzvektoren (werden bei der graphischen Darstellung benötigt):
x_fa1 = 0 : df_falt : fa-df_falt;
x_fn1 = 0 : df_falt : fn-df_falt;

amplitudengang1 = [ampl_y(1)/fftsize ampl_y(2:fftsize/2)/(fftsize/2)];

fig = figure(fig+1);                                                                            %fig
plot (x_fn1, amplitudengang1);


% Filter - Impulsantwort
% mit Nullen auf fftsize auffüllen
tmp3=fftsize-length (FIRkoeff);
tmp4= zeros (1,tmp3);
FIRkoeff1 = [FIRkoeff, tmp4];  
% Berechnung des Frequenzspektrums
FIRkoeff_fft = fft(FIRkoeff1,fftsize);                                                          %FFT Filter

ampl_FIR = abs(FIRkoeff_fft);

%amplitudengang2 = fftshift(ampl_FIR/fftsize);
amplitudengang2 = [ampl_FIR(1)/fftsize ampl_FIR(2:fftsize/2)/(fftsize/2)];
fig = figure(fig+1);                                                                             %fig
plot (x_fn1, amplitudengang2);

%Faltung durch Multiplikation der Spektren

y_FALT = y_win_fft.*FIRkoeff_fft;

ampl_FALT = abs (y_FALT);                                                                        %gefiltertes Spektrum
%amplitudengang3 = fftshift(ampl_FALT/fftsize);
amplitudengang3 = [ampl_FALT(1)/fftsize ampl_FALT(2:fftsize/2)/(fftsize/2)];
fig = figure(fig+1);                                                                             %fig
plot (x_fn1, amplitudengang3);

 
 
Neues Thema eröffnen Neue Antwort erstellen



Einstellungen und Berechtigungen
Beiträge der letzten Zeit anzeigen:

Du kannst Beiträge in dieses Forum schreiben.
Du kannst auf Beiträge in diesem Forum antworten.
Du kannst deine Beiträge in diesem Forum nicht bearbeiten.
Du kannst deine Beiträge in diesem Forum nicht löschen.
Du kannst an Umfragen in diesem Forum nicht mitmachen.
Du kannst Dateien in diesem Forum posten
Du kannst Dateien in diesem Forum herunterladen
.





 Impressum  | Nutzungsbedingungen  | Datenschutz | FAQ | goMatlab RSS Button RSS

Hosted by:


Copyright © 2007 - 2024 goMatlab.de | Dies ist keine offizielle Website der Firma The Mathworks

MATLAB, Simulink, Stateflow, Handle Graphics, Real-Time Workshop, SimBiology, SimHydraulics, SimEvents, and xPC TargetBox are registered trademarks and The MathWorks, the L-shaped membrane logo, and Embedded MATLAB are trademarks of The MathWorks, Inc.