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

FIR Filter: Zeitachse und Amplitude nicht wie erwartet

 

BlackWolf
Forum-Anfänger

Forum-Anfänger


Beiträge: 17
Anmeldedatum: 09.03.15
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 19.03.2015, 11:28     Titel: FIR Filter: Zeitachse und Amplitude nicht wie erwartet
  Antworten mit Zitat      
Hallo Community,

nachdem ich meine letzten drei Threads alle wieder nach kurzer Zeit löschen konnte, habe ich nun ein Programm stehen und würde gerne wissen, ob ich irgendwo einen Fehler übersehen habe.

Grundsätzlich habe ich eine verrauschte Stufenfunktion und möchte diese so filtern, dass ich am Ende eine definierte Stufe habe. Das alles soll im Zeitbereich geschehen. Dies ist mir auch soweit gelungen. Allerdings hadere ich dabei noch etwas mit der Amplitude und warum das Ergebnis verschoben ist. Bin mir nicht ganz sicher, ob das so stimmen kann.

Es würde mich sehr freuen wenn Ihr mal einen blick drauf werft und mir verratet, ob alles soweit passt oder es noch korrekturen geben muss.

Vielen Dank schonmal Smile

Code:

clc
clear all
close all

% FIR-Filter Implementation Version 1.0

Signal_Data = importdata('short-avg.dat');    % Reading data
Signal = Signal_Data.data;
time_axis = Signal(:,1);                              % Time vector
Signal_Vector = Signal(:,2);                        % Signal vector
N = length(Signal_Vector);                          % Samplepoints

t0 = time_axis(1000);                                 % time period
T = t0/N;                                                   % sampling period
fs = 1/T;                                                    % sampling rate
df = fs/N;                                                   % Frequencyresolution

cut_signal = Signal_Vector(1:351);               % Create Cut-Signal
L=length(cut_signal);
cut_nfft = 2^nextpow2(L);                           % Length of FFT

f_1 = (0:cut_nfft/2-1)*fs/cut_nfft;                  % Frequency vector for Cut-Signal

for j=1:length(cut_signal)                             % Anheben der Nullinie
    cut_signal(j) = cut_signal(j) + 0.3006;
end

Diff_cut_signal = diff(cut_signal)/T;                 % Differentiation from Cut-Signal
K = length(Diff_cut_signal);

Diff_windowed_cut_signal = Diff_cut_signal.*hanning(K);    
FFT_Diff_windowed_cut_signal = fft(Diff_windowed_cut_signal,cut_nfft)/cut_nfft;

deltapuls = zeros(512,1);                               % Deltapuls [1,0,0,0,...]
deltapuls(1) = 1;

Filter_Impulse_Response = fir1(9,0.2);
H = filter(Filter_Impulse_Response,1,deltapuls);
Frequency_Response_Filter = fft(H,cut_nfft)/cut_nfft;  

Correction_Function = Frequency_Response_Filter ./ FFT_Diff_windowed_cut_signal;
Correction_Function_Timedomain = ifft(Correction_Function,cut_nfft)/cut_nfft;

Convolution = conv(Correction_Function_Timedomain,Diff_windowed_cut_signal);
Integration = cumtrapz(Convolution);

figure(8)
subplot(2,1,1)
plot(time_axis(1:351),cut_signal)
subplot(2,1,2)
plot(time_axis(1:861),Integration)
 



Anmerkung: Das Signal wurde gekürzt, da es durch Rückkopplung wie eine Rechteckfunktion aussah, wir aber nur eine Stufe generiert haben Wink

short-avg.zip
 Beschreibung:

Download
 Dateiname:  short-avg.zip
 Dateigröße:  5.15 KB
 Heruntergeladen:  490 mal
Private Nachricht senden Benutzer-Profile anzeigen


BlackWolf
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 17
Anmeldedatum: 09.03.15
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 19.03.2015, 12:05     Titel:
  Antworten mit Zitat      
Die Zeitachse ist mir gerade gelungen, lediglich die Zeitverschiebung ist mir noch nicht ganz klar. Und natürlich das Amplitudenproblem..

Gelöst habe ich das indem ich in den Faltungsbefehl noch den Zusatz 'same'
reingebracht habe dank der Matlab-Hilfe. Dadurch gibt Matlab nur den Hauptteil der Faltung zurück mit der selben Grösse wie u:

Code:

conv(u,v,'same')
 
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: 21.03.2015, 11:00     Titel:
  Antworten mit Zitat      
Hallo,

wenn ich deinen Code richtig verstehe, wandelst du die Impulsantwort eines Filters in den Frequenzbereich und dividierst ihn mit dem Signalspektrum. Aber was soll das bewirken? Würde hier eine Multiplikation statfinden, entspräche dies einer Faltung (= Filterung des Signal als Äquivalent zu conv im Zeitbereich)

Zur Amplitude...ich würde den Faktor 1/cut_nfft einfach weglassen. Und zwar sowohl bei fft als auch bei ifft.

Die Verschiebung kommt durch das Filter. Jedes Filter hat ein Delay, um den das Ausgangsignal um den Delay nach rechts verschoben ist. Bei einem FIR ist das Delay einfach die Filterlänge, weshalb du bei dem fir1 9. Ordnung einfach um 9 Messwerte wieder nach links verschieben musst. Oder du nutzt statt conv, filtfilt. Das macht den delay rückgängig in dem das Signal bei einer 2. Filterung einfach rückwärts ins Filter geladen wird. Das wäre natürlich auch mit conv möglich. Filtfilt macht es aber automatisch und hat auch nicht den Output der Faltung:

output[m+n-1] = signal[m] * impuls_filter[n]

So lautet nämlich das Faltungstheorem in Bezug auf die Länge des Outputvektors.
Private Nachricht senden Benutzer-Profile anzeigen
 
BlackWolf
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 17
Anmeldedatum: 09.03.15
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 22.03.2015, 12:19     Titel:
  Antworten mit Zitat      
Vielen Dank für deine Antwort DSP.

Das mit dem 1/cut_nfft hab ich auch jetzt weggelassen und mir ist jetzt auch klar das die Verschiebung durch den Filter natürlich kommt. Ich probiere mal filtfilt und schaue was bei rumkommt, oder verschiebe es einfach.

Aber jetzt darf ich das ganze in C/C++ umprogrammieren und leider habe ich kaum Erfahrung darin. Naja, das ist ein anderes Thema Very Happy
Private Nachricht senden Benutzer-Profile anzeigen
 
BlackWolf
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 17
Anmeldedatum: 09.03.15
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 23.03.2015, 13:54     Titel:
  Antworten mit Zitat      
Hey zusammen.

Nachdem ich nun meinen obiges Skript mit dem gesamten Signal testen wollte, also nicht mehr nur Laenge von 351 Stellen, sondern 1000,
zerschiesst sich mein Filter totat bzw macht nicht mehr das was er soll.

Im folgenden nochmal das "neue" Skript:

Code:

clc
clear all
close all

% FIR-Filter Implementation Version 1.2

Signal_Data = importdata('short-avg.dat');    % Reading data
Signal = Signal_Data.data;
Time_axis = Signal(:,1);                      % Time vector
Signal_Vector = Signal(:,2);                  % Signal vector

L=length(Signal_Vector);

t0 = Time_axis(351);                          % time period
T = t0/L;                                     % sampling period
Fs = 1/T;                                     % sampling rate

for i=1:length(Signal_Vector)             % Lifting Zero Axis
    Signal_Vector(i) = Signal_Vector(i) + 0.3006;
end

Diff_cut_signal = diff(Signal_Vector)/T;  % Differentiation from Cut-Signal
K = length(Diff_cut_signal);

Diff_windowed_cut_signal = Diff_cut_signal.*blackmanharris(K);    
FFT_Diff_windowed_cut_signal = fft(Diff_windowed_cut_signal)/K;

Deltapuls = zeros(999,1);                     % Deltapuls [1,0,0,0,...]
Deltapuls(1) = 1;

Filter_Impulse_Response = fir1(9,0.25);
H = filter(Filter_Impulse_Response,1,Deltapuls);
Frequency_Response_Filter = fft(H)/K;  

Correction_Function = Frequency_Response_Filter ./ FFT_Diff_windowed_cut_signal;
Correction_Function_Timedomain = ifft(Correction_Function)/K;

Convolution = conv(Correction_Function_Timedomain,Diff_windowed_cut_signal,'same');
Integration = cumtrapz(Convolution);

figure(1)
subplot(2,1,1)
plot(Time_axis,Signal_Vector)
subplot(2,1,2)
plot(Time_axis(1:999),Integration)
 



Ich wäre sehr sehr froh, wenn mir jemand sagen kann, warum das passiert.. ich sitze schon den ganzen morgen dran und habe leider gerade keine Ahnung. Normalerweise sollte doch mindestens Ansatzweise das Rechtecksignal rauskommen..

Vielen Dank,
Black Wolf
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: 23.03.2015, 14:34     Titel:
  Antworten mit Zitat      
Ich stelle nochmal die gleiche Frage. Was bezweckst du mit dieser Division?

Zitat:
Correction_Function = Frequency_Response_Filter ./ FFT_Diff_windowed_cut_signal;


Wie schon gesagt ist eine Multiplikation mit der Impulsantwort des Filters im Frequenzbereich = eine Faltung im Zeitbereich.

Eine Division ist dann eigentlich die Umkehrfunktion (Deconvolution). Teile ich z.B. die Sprungantwort eines Filters durch dessen Impulsantwort, erhält man das Eingangssprungsignal. Somit wurde die Faltung rückgängig gemacht. Wenn das gewünscht ist, warum wird dann anschließend nochmal eine Faltung im Zeitbereich durchgeführt?

Allerdings muss man bei Conv/Deconv unbedingt die Längen des Faltungstheorems berücksichtigen, ansonsten führt man eine zyklische statt einer linearen Faltung durch und das Ergebnis ist damit falsch.

Warum teilst du nun wieder bei FFT/IFFT?

Schau dir mal hier das angehängte Skript FFT_Faltung.m an:
http://www.gomatlab.de/window-sinc-filter-t19156.html

output[m+n-1] = signal[m] * impuls_filter[n]

Um eine zyklische Faltung zu vermeiden, müssen die Eingangsvektoren schon vor der FFT auf die Länge m+n-1 gebracht werden.
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: 24.03.2015, 07:46     Titel:
  Antworten mit Zitat      
Die falsche Amplitude wird vermutlich auch durch die Fensterung verursacht werden.

Code:

% statt
Diff_windowed_cut_signal = Diff_cut_signal.*blackmanharris(K);    
% Fensterung mit Amplitudenkorrektur
win = blackmanharris(K);
Diff_windowed_cut_signal = Diff_cut_signal.*win*k/sum(win);  
 


Den Faktor 1/k würde ich definitiv bei FFT/IFFT weglassen.

Ansonsten kann ich dir nicht weiterhelfen, ohne genauere Erklärung deines Codes. Ausführen kann ich ihn leider nicht, da mit die Daten fehlen.
Wobei mir schon klar ist, was du bis zu der Division im Freq.-bereich machst.
Private Nachricht senden Benutzer-Profile anzeigen
 
BlackWolf
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 17
Anmeldedatum: 09.03.15
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 24.03.2015, 08:44     Titel:
  Antworten mit Zitat      
Hey DSP,

vielen dank für deine Hilfe!

Ich bin gerade nochmal was Theorie durchgegangen und
ich denke meine Entfaltung ist zu naiv.

Aber zuerst versuche ich mal zu erklären, was ich damit bewirken will bzw. was ich mit meinem Programm anstellen will:
Ich benötige lediglich einen simplen Tiefpassfilter, wie im Programm zu sehen ist, um das Rauschen aus meinem Signal zu bekommen.
Das ganze soll später im Zeitbereich passieren. Da es hier um Messrauschen geht, also Rauschen welches dem Messinstrument inne ist, will ich eine Correction-Funktion erstellen, womit ich später jedes Signal, welches durch die Messeinrichtung kommt, vom Rauschen befreien kann (Alles im Zeitbereich, deshalb ist die Faltung im Programm, nur damit ich sehe obs klappt oder nicht. Später soll nur noch die Faltung im Zeitbereich mit der Correction_Funktion im Programm sein).
Dafür ist die Entfaltung gedacht.

Correction_F = Frequency_Response / Gemessenes_Signal

Jedoch verstärke ich hiermit nur mein Rauschen und bekomme dadurch wahrscheinlich ein falsches Ergebniss, wenn ich mein Signal mit der Correction_Funktion im Zeitbereich falte.

Ich hoffe ich konnte mein Vorhaben einigermassen rüberbringen.

Besten Dank nochmal!

PS: Das Signal habe ich nochmal angehängt.

short-avg.zip
 Beschreibung:
Hier nochmal die Daten

Download
 Dateiname:  short-avg.zip
 Dateigröße:  5.15 KB
 Heruntergeladen:  436 mal
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: 24.03.2015, 09:29     Titel:
  Antworten mit Zitat      
Zitat:

Da es hier um Messrauschen geht, also Rauschen welches dem Messinstrument inne ist, will ich eine Correction-Funktion erstellen, womit ich später jedes Signal, welches durch die Messeinrichtung kommt, vom Rauschen befreien kann


Sorry, aber das verstehe ich immer noch nicht. Wozu die Correction-Funktion wenn es das Filter zum Entrauschen gibt?

Mal ein kleines Bsp. für die Faltung und Inverse Faltung

Sprungfunktion[m + n-1] * Filter_Impulsantwort[n + m-1] = Filter_Sprungantwort[m + n-1]

m = 1000 Werte
n = 100

Du musst also VOR der FFT schon das Eingangsignal und die Filter_Impulsantwort auf die Länge m+n-1 durch Anhängen von Nullen bringen. Nur dann entspricht die Multiplikation im Freq.-bereich der linearen Faltung im Zeitbereich.

Inverse Faltung: Auch hier muss die Länge der Vektoren beachtet werden. Das Eingangsignal (der Sprung) hat 1000 Messwerte. Damit bei der inv. Faltung ebenso diese 1000 Messwerte herauskommen, muss also das Ausgangsignal und die Impulsantwort schon die Länge m+n-1 haben. Wieder durch Anhängen von Nullen.

Sprungfunktion[m] = Filter_Sprungantwort[m+n-1] / Filter_Impulsantwort[m+n-1]

!!NICHT!!

Sprungfunktion[m] = Filter_Impulsantwort[m+n-1] / Filter_Sprungantwort[m+n-1]

Außerdem muss die Filterimpulsantwort lang genug sein, so dass das Filter eingeschwungen ist. Idealerweise sollte

Code:
sum(Filter_Impulsantwort) = 1


sein damit keine Verstärkung auftritt. Ist die Filterimpulsantwort nicht eingeschwungen, kommt es bei der Inversen Faltung zu Artefakten.
Private Nachricht senden Benutzer-Profile anzeigen
 
BlackWolf
Themenstarter

Forum-Anfänger

Forum-Anfänger


Beiträge: 17
Anmeldedatum: 09.03.15
Wohnort: ---
Version: ---
     Beitrag Verfasst am: 24.03.2015, 09:47     Titel:
  Antworten mit Zitat      
Vielen Dank nochmal für deine Umfassende Hilfe.

Leider hab ich gerade selber die Idee hinter meiner "Correction_Funktion" verloren und muss da nochmal genauer drüber nachdenken.

Jedenfalls werde ich jetzt erstmal versuchen die genannten Hinweise umzusetzen und nachzuvollziehen.

Mal sehen ob ich es so hinbekomme wie ich es gern haben würde Wink
Private Nachricht senden Benutzer-Profile anzeigen
 
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.