views:

2338

answers:

5

I can write something myself by finding zero-crossings of the first derivative or something, but it seems like a common-enough function to be included in standard libraries. Anyone know of one?

My particular application is a 2D array, but usually it would be used for finding peaks in FFTs, etc.

Specifically, in these kinds of problems, there are multiple strong peaks, and then lots of smaller "peaks" that are just caused by noise that should be ignored. These are just examples; not my actual data:

1-dimensional peaks:

FFT output with peaks

2-dimensional peaks:

Hough transform output with labeled peaks

The peak-finding algorithm would find the location of these peaks (not just their values), and ideally would find the true inter-sample peak, not just the index with maximum value, probably using quadratic interpolation or something.

Typically you only care about a few strong peaks, so they'd either be chosen because they're above a certain threshold, or because they're the first n peaks of an ordered list, ranked by amplitude.

As I said, I know how to write something like this myself. I'm just asking if there's a pre-existing function or package that's known to work well.

Update:

I translated a MATLAB script and it works decently, but could be better.

A: 

http://code.activestate.com/recipes/475188/ ?

Ned Batchelder
that's the max/min value (for blocks), not the location
andrew cooke
+1  A: 

I do not think that what you are looking for is provided by SciPy. I would write the code myself, in this situation.

The spline interpolation and smoothing from scipy.interpolate are quite nice and might be quite helpful in fitting peaks and then finding the location of their maximum.

EOL
+1  A: 

There are standard statistical functions and methods for finding outliers to data, which is probably what you need in the first case. Using derivatives would solve your second. I'm not sure for a method which solves both continuous functions and sampled data, however.

nullpointer
+2  A: 

Detecting peaks in a spectrum in a reliable way has been studied quite a bit, for example all the work on sinusoidal modelling for music/audio signals in the 80ies. Look for "Sinusoidal Modeling" in the literature.

If your signals are as clean as the example, a simple "give me something with an amplitude higher than N neighbours" should work reasonably well. If you have noisy signals, a simple but effective way is to look at your peaks in time, to track them: you then detect spectral lines instead of spectral peaks. IOW, you compute the FFT on a sliding window of your signal, to get a set of spectrum in time (also called spectrogram). You then look at the evolution of the spectral peak in time (i.e. in consecutive windows).

David Cournapeau
Look at peaks in time? Detect spectral lines? I'm not sure what this means. Would it work for square waves?
endolith
I tried to add some explanation, let me know if this is still unclear.
David Cournapeau
Oh, you're talking about using STFT instead of FFT. This question isn't about FFTs specifically; that's just an example. It's about finding the peaks in any general 1D or 2D array.
endolith
+1  A: 

I'm looking at a similar problem, and I've found some of the best references come from chemistry (from peaks finding in mass-spec data). For a good thorough review of peaking finding algorithms read this. This is one of the best clearest reviews of peak finding techniques that I've run across. (Wavelets are the best for finding peaks of this sort in noisy data.).

It looks like your peaks are clearly defined and aren't hidden in the noise. That being the case I'd recommend using smooth savtizky-golay derivatives to find the peaks (If you just differentiate the data above you'll have a mess of false positives.). This is a very effective technique and is pretty easy to implemented (you do need a matrix class w/ basic operations). If you simply find the zero crossing of the first S-G derivative I think you'll be happy.

Paul

Paul
I was looking for a general purpose solution, not one that only works on those particular images. I adapted a MATLAB script to Python and it works decently.
endolith
Right on. Matlab is a good source for algorithms. What technique does the script use? (BTW, SG is a very general purpose technique).
Paul
I linked it above. It basically just searches for local maxima that are larger than a certain threshold above their neighbors. There are certainly better methods.
endolith