Detecting peaks and valleys in signal
123 views (last 30 days)
Show older comments
hello, I'm detecting peaks and valleys in signal. My detector detects more valleys than I need. Is it possible to select only thouse valleys which are next to peak (shown in the picture)?
This is my code:
%find peaks
[pks,plocs,pwidths] = findpeaks(signal(:,1), 'MinPeakHeight',1.8e6);
%find valleys
[vks,vlocs,vwidths] = findpeaks(-signal);
vks = -vks;
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/1312435/image.png)
Thank you for your comments and answers
0 Comments
Accepted Answer
Star Strider
on 2 Mar 2023
I do not have your data.
See if the 'MinPeakDistance' name-value pair will help to isolate them. Experiment with it to ignore the valley between the ones you want, perhaps:
[vks,vlocs,vwidths] = findpeaks(-signal, 'MinPeakDistance',2E3);
Otherwise, detecting the minimum values between the peaks and logically eliminating those values from the returned valleys.
There are likely several ways to solve this.
2 Comments
Star Strider
on 2 Mar 2023
Edited: Star Strider
on 3 Mar 2023
My pleasure!
If I had your signal, I could probably write more definitive code.
EDIT — (3 Mar 2023 at 19:27)
Using 'MinPeakDistance' will likely fail, however this approach works with my test data —
Fs = 250;
L = 60;
t = linspace(0, L*Fs, L*Fs+1)/Fs;
s = (1.75+sum(sin([1;3;5]*2*pi*t*0.1)./[0.6;3;5]))*1.6E+6;
[vys,vlocs] = findpeaks(-s, 'MinPeakHeight',-7.5E+5);
figure
plot(t,s)
hold on
plot(t(vlocs), -vys, 'vr')
hold off
title('Original ‘findpeaks’ Call')
L = numel(t);
tidx = find(diff(sign(s - 2E+6))); % Threshold Signal To Separate Pulses
% tv = t(tidx);
for k = 1:numel(tidx)-1
idxrng = max(1,tidx(k)) : min(L,tidx(k+1)); % Index Range For This Pulse
[minp,idx] = max(-s(idxrng)); % Minimum & Index
idxp(k) = tidx(k) + idx - 1; % Index With Offset
end
% xline(tv,'-r')
% idxp
ixs = ~ismember(vlocs,idxp); % Return 'vlocs' Logical Vector, Eliminating Lowest Peaks
vysv = vlocs(ixs); % Associated 'vlocs' Indices
figure
plot(t,s)
hold on
plot(t(vysv), s(vysv), 'vr')
hold off
title({'Original ''findpeaks'' Call With ','''ismember'' Call To Eliminate Lowest Peak'})
It should be possible to apply this to your data, essentially as presented here, without many changes.
.
More Answers (0)
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!