I have a series of data (single array). If I take this data and plot it, I can see that there are multiple peaks. However If I zoom in to a section of data, I see that there is substantial noise.

I like to detect how many peaks in the data using little CPU time and energy. I thought of detecting the slopes of these peaks (could be sharp or smooth rising or falling) and look at the number of slopes to determine the number of peaks. (2 slopes positive and negative for every peak)

Any pointers how I can calculate the slopes in the presence of noise?

The code will go into an embedded system, memory is limited so preferably I like to implement something that doesn't require any significant data copy.

  • 1
    $\begingroup$ You sound like in a store asking for something you need $\endgroup$ – Alfredo Castañeda García Jan 21 '12 at 8:58
  • 2
    $\begingroup$ If the noise is relatively high in frequency then you could low pass filter the data $\endgroup$ – Paul R Jan 21 '12 at 9:00
  • 4
    $\begingroup$ Can you post one or more example plots of your data? That will help us see what it looks like. Peak detection is not usually done via derivative estimation, as calculating the derivative of a signal is very sensitive to noise (it is a highpass operation). There may be characteristics to the signal of interest that you can exploit. Also, there is always a tradeoff between the probability of correctly detecting a peak and the probability of falsely declaring a peak that really isn't of interest. Which is more important to your application? $\endgroup$ – Jason R Jan 21 '12 at 14:09
  • 2
    $\begingroup$ If you can produce a plot, it would be helpful. $\endgroup$ – Jason R Jan 22 '12 at 16:00
  • 1
    $\begingroup$ You want to detect peaks, you may want to search for peak detection (look at dsp.stackexchange.com/questions/1302/peak-detection-approach). $\endgroup$ – Geerten Feb 21 '12 at 15:56

It depends on the type of noise and type of signal. Show an example if you want a good answer. But, that said, in general you probably want to low-pass filter the signal. If I were you, I'd take a Fourier power spectrum to see if most of the noise is high frequency, and the signal I care about mostly in a lower range. If they overlap, oh well that's life. I would have to think more about things.

One low-pass filter that's good for noisy signal in many cases is the Savitzky-Golay filter. It is described in Numerical Recipes, and for Python there's a function in the Python Numpy Cookbook. It is merely a convolution with a small kernel. You pick the window size based on the width of the peaks or other features, wide enough to mush out the noise, but not wider than the features. It can be small, say five points, or bigger like dozens, a hundred maybe.

You also pick a polynomial order - usually I use 2 or 4. Order 2 is fine for when the window is small, < 10 points or it spans less than half a cycle or so (if your signal resembles a sine) while order 4 is better at matching distorted peak shapes, but likes to have around 9 or more points. But a lot depends on the shape and frequency of the noise.

As other say in the comments, finding derivatives probably isn't the best strategy, but if you want find derivatives anyway, the Savitzky-Golay filter can do that - simultaneously smoothing and reporting the derivative instead of the signal.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.