select local maxima in energy signal

I have the following plot which represents the RMS energy of a signal over time. The energy goes up and down with varying maximum amplitude. I want to keep the portions of the signal where the energy is quasi-steady (i.e. the top of each "hill", like the brown line). I cannot use thresholding because the local maxima are varying. How can I do it?

I am using Matlab.

• Looks like a periodic signal; why not average over the respective signal periods(0-90,120-210,etc..) or find local maxima and keep the average value/ max value over that entire period?? – charansai Feb 20 '17 at 17:35

I would suggest to apply a median filter like

y=filter(1,0.05*ones(1,20),x)

And then apply Matlab function "findpeaks"

As an alternative to second step you perform a segmentation based on different from zero areas like in

ne0 = find(A~=0);                                   % Nonzero Elements
ix0 = unique([ne0(1) ne0(diff([0 ne0])>1)]);        % Segment Start Indices
ix1 = ne0([find(diff([0 ne0])>1)-1 length(ne0)]);   % Segment End Indices
for k1 = 1:length(ix0)
section{k1} = A(ix0(k1):ix1(k1));
end
celldisp(section)                                   % Display Results

And then perform calculation on each segment. For example sum all samples and divide by number of samples.

• I like the idea of the filtering but with that segmentation method I'm getting also the slopes, which I don't want. For example, in the fourth hill in my picture I don't want to retrieve the samples from 400 to 500, but the ones corresponding to the brown line (~420 to 480). Maybe I can segment with this method and then, for each section, threshold based on local maxima? – firion Feb 21 '17 at 9:59
• For a simple solution maybe you can only consider for example the samples between 15% and 85% of the vector. As an alternative you can calculate the derivative (x[n]-x[n-1] or diff(x) ) and define a threshold for derivate values. – Filipe Pinto Feb 21 '17 at 11:33
• I came up with a nice solution: without previous filtering, I apply the method provided in your answer. Then, for each section, I keep only the values above the RMS of that section (the mean can be used instead of RMS for wider result). In this way the slopes are discarded. Thanks for your suggestion! – firion Feb 21 '17 at 12:10
• Filtering you add a phase that change peak position. I think that wavelets should work well. Or at least filtfilt function in MATLAB that doesn't change phase – Andrea Apr 17 '18 at 9:47