Detecting peaks and valleys in signal
    66 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; 

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!


