Verfasst am: 18.01.2016, 19:05
Titel: Maximabestimmung über "Threshold"
Hallo zusammen,
Was der unten sichtbare Code machen soll ist eigentlich "einfache" Maximabestimmung. nur, dass ich HAUPTmaxima (keine kleinen, keine Sattelstellen etc) haben will. was der code also machen soll:
- gesamtes Frequenzband ablaufen (for-schleife)
- für jeden punkt um Spannweite "steps" nach links und rechts gucken und falls in BEIDE Richtungen kleinere werte um mindestens schwelle "eps" kleiner ausgegeben werden, handelt es sich um ein Maximum und es soll in "data2" geworfen werden.
Der Code ist angelehnt an den R Code eines Freundes, ab einem gewissen Punkt bin ich blutiger Anfänger leider vor die Wand gefahren....
Nun also das Eigentliche:
Was habe ich (vorab berechnet):
Code:
databsabs % betrag der fft Amplitude
f % frequenzmatrix (für x-achse)
eps = 0.01e-9; % threshold (ergibt sich aus messgenauigkeit, kann "beliebig" angepasst werden)
steps = 10; % x-achsen-wert, der nach links und rechts geguckt wird, kann "beliebig" angepasst werden
data2 = zeros(1025,1); % Leere (z.b.)1025 x 1 Matrix für Ergebniswerte
if databsabs[f-steps]-databsabs[f]>eps && databsabs[f+steps]-databsabs[f]>eps
data2<-rbind(data2,databsabs[f,]); end% data2 sind peaks, hier wird das da rein geworfen (funktion rbind) end
das hat jetzt zwar nichts mit deinem Code zu tun, aber hast du es schon mal mit der Matlab Funktion
findpeaks
versucht? Setzt allerdings die Signal Processing Toolbox voraus. Dort lassen sich aber neben einem Threshold noch weitere Regeln für die Suche von Maxima definieren.
Das hier verstehe ich allerdings nicht wirklich:
Zitat:
- für jeden punkt um Spannweite "steps" nach links und rechts gucken und falls in BEIDE Richtungen kleinere werte um mindestens schwelle "eps" kleiner ausgegeben werden, handelt es sich um ein Maximum und es soll in "data2" geworfen werden.
Kannst du mal ein Bsp. dazu erstellen? Was macht rbind? Bitte nutze doch die Codeumgebung (Code-Button) im Forum, damit dein Code lesbarer wird.
Auf Arrays vom Typ double wird der Index in runde Klamern gesetzt:
Code:
y = rand(1,10); % double array mit 10 zufälligen Werten
y(1)% erste Element
y(end)% letztes Element
y(2:5)% Bereich 2.-5. Element
ich habe jetzt eine Zeit gebastelt und es tatsächlich wieder mit findpeaks versucht.
mein Problem ist nun - so glaube ich -, dass ich eine zu alte matlab version nutze (2012a). Ich möchte nämlich gerne mit 'prominence' arbeiten, das scheint hier aber nicht zu funktionieren. Ich habe den Eindruck, dass 'prominence' so ziemlich das macht, was ich ursprünglich mit meiner for-if-schleife versucht habe.
aber ZUM EIGENTLICHEN.
1) Ist es tatsächlich so, dass r2012a keine 'MinPeakProminence' bietet?
2) Hat jemand sich schon mal die Mühe gemacht, das nachzubauen, sodass man es in seinen Code einfügen kann?
Greez und danke
David
btw., ich antizipiere schonmal die Rückfrage:
Code:
cd C:\Users\Admin\Dropbox\MA_DS_Windows_PC\Excel_Matlab\ACC_Vibro_50kHz
Fs=50000 ; % Samplerate
L=32768; %Signallänge, alternativ 32768
df = Fs/L; % Auflösung
Y = fft(KV,L)/L;
f = Fs/2*linspace(0,1,L/2+1);
KVabs = 2*abs(Y(1:L/2+1));
NY = fft(KS,L)/L;
KSabs = 2*abs(NY(1:L/2+1));
th=8e-2;
ph=8e-2;
sheet = 1;
[peaks,locations] = findpeaks(KVabs,'THRESHOLD',th,'MINPEAKHEIGHT',ph); % weitere Entwicklung, wieder abgespeckt, mit minimaler Höhe. erster Code, der funktioniert. Durch die Mindesthöhe muss er aber jeweils an die Amplitide angepasst werden. (Hier 0,1)
locations = locations - 1; %% sonst hat man um `df` zu hoch ausgegebene Frequenzen
peaksV = peaks;
locationsV = locations;
frequenciesV = locationsV*df;
maximaV = [frequenciesV'; peaksV'];
figure; plot(f,KVabs) title('Amplitudenspektrum und Peaks vom Laservibrometer') xlabel('Frequenz [Hz]') ylabel('|Amplitude|') hold on; stem(frequenciesV,peaksV,'r','LineStyle','none'); hold off;
[peaks,locations] = findpeaks(KSabs,'THRESHOLD',th,'MINPEAKHEIGHT',ph); % weitere Entwicklung, mit minimaler Höhe. erster Code, der einigermaßen funktioniert. Durch die Mindesthöhe muss er aber jeweils an die Amplitide angepasst werden. (Hier 0,1)
locations = locations - 1; %% sonst hat man um `df` zu hoch ausgegebene Frequenzen
peaksS = peaks;
locationsS = locations;
frequenciesS = locationsS*df;
maximaS = [frequenciesS'; peaksS'];
figure; plot(f,KSabs) title('Amplitudenspektrum und Peaks von Beschleunigungssensor') xlabel('Frequenz [Hz]') ylabel('|Amplitude|') hold on; stem(frequenciesS,peaksS,'r','LineStyle','none'); hold off;
xlswrite('SensorPEAKS01.xlsx',maximaS,sheet); % "1" Steht hier für Sheet1 in der Excel xlswrite('VibrometerPEAKS01.xlsx',maximaV,sheet);
FreqS = [f' KSabs]; % Matrix aus Betrag Sensor FFT über Frequenz
FreqV = [f' KVabs]; % Matrix aus Betrag Vibro FFT über Frequenz
xlswrite('SensorFFT01.xlsx',FreqS,sheet); % "1" Steht hier für Sheet1 in der Excel, man darf nur mit dem ersten sheet anfangen, zweiter geht erst, wenn die datei existiert. xlswrite('VibrometerFFT01.xlsx',FreqV,sheet);
EDIT: KV und KS sind meine Eingangsvektoren (Zeitbereich).
Einstellungen und Berechtigungen
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
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.