[ideas wanted]: How to find "peaks" of sloping signal?
24 views (last 30 days)
Show older comments
Sven Larsen
about 19 hours ago
Commented: Star Strider
about 12 hours ago
Shoutout to you all math wizards! I need to detect peaks of (possibly) sloping signals. i.e sometimes first "peak" is real peak (findpeaks), but other times "peak" is in upward sloping portion of signal. See example figure below: the blue triangle is what findpeaks finds as first peak. But I need to detect that "peak" before it (see red arrow).
All ideas are much appreciated!
data is in attachment (data.mat)
0 Comments
Accepted Answer
Star Strider
about 17 hours ago
The online ability to run scripts seems to be broken.
I used MATLAB Online to devise this —
% LD = load('data.mat')
file = websave('data.mat','https://www.mathworks.com/matlabcentral/answers/uploaded_files/1809778/data.mat');
LD = load(file);
data = LD.data;
x = linspace(0, 5.5, numel(data)); % Supply Missing Coordinate
Fs = 1/x(2)
[FTs1,Fv] = FFT1(data,x);
figure
plot(Fv, abs(FTs1)*2)
xlim([0 3])
title('Fourier Transform (Informs Filter Design)')
data_filt = highpass(data, 0.0425, Fs, ImpulseResponse='iir');
[pksf,locsf] = findpeaks(data_filt);
[pks,locs] = findpeaks(data);
locs = [locsf(1) locs]
pks = data(locs)
figure
plot(x, data)
hold on
plot(x(locs), data(locs), 'rv' )
hold off
figure
plot(x, data_filt)
title('Filtered ‘data’')
function [FTs1,Fv] = FFT1(s,t)
% Arguments:
% s: Signal Vector Or Matrix
% t: Associated Time Vector
t = t(:);
L = numel(t);
if size(s,2) == L
s = s.';
end
Fs = 1/mean(diff(t));
Fn = Fs/2;
NFFT = 2^nextpow2(L);
FTs = fft((s - mean(s)) .* hann(L).*ones(1,size(s,2)), NFFT)/sum(hann(L));
Fv = Fs*(0:(NFFT/2))/NFFT;
% Fv = linspace(0, 1, NFFT/2+1)*Fn;
Iv = 1:numel(Fv);
Fv = Fv(:);
FTs1 = FTs(Iv,:);
end
.
4 Comments
Star Strider
about 10 hours ago
That is the frequency that works best. (Signal processinig is frequently experimental.) I used the Fourier transform result to provide the first approximation, then went from there until I got a result that works.
Note that it is based on the ‘x’ vector. Basing it on the index vector is an optiion, and in that instance the sampling frequency is 1, and the cutoff frequency would have to be calculated differently, and likely experimentally, although scaling it as a function of the calculated sampling frequency here (0.0425/Fs) would likely work.
.
More Answers (0)
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!