How to find dominant peaks in matlab (fft)

11,988

Solution 1

If your dominant peaks are seperated like in the plot you included, there is a parameter for findpeaks() that can help a whole lot. Try:

findpeaks(x, 'MINPEAKDISTANCE', dist);

with x being your magnitudes and dist being a distance you can assume to be te smallest distance between 2 peaks. This might give you a false peek in between 2 peek that are more than 2*dist from each other, if so consider adding a small threshold with 'MINPEAKHEIGHT'

Another Option is calulating your threshold dynamicly, for exsample by calulating the mean m and the standard deviation sigma and setting a threshold by only counting peaks that are n*sigma above m.

Solution 2

you can still use findpeaks. for example [pks,locs] = findpeaks(data) returns the indices of the local peaks. then you can sort data(locs) and get the top 4 amplitudes.

[a ind]=sort(data(locs,'descend')

or set a threshold, data(locs)>threshold etc...

Solution 3

One way to do this is to compute the difference function for the magnitude array (which is equivalent to derivative for continuous functions). Look for points where the value for the difference function goes from positive to negative. Those are your peak points.

To find the most prominent peaks, compute the second order difference function at the points obtained from the first order difference and select the ones which are of highest magnitude.

If the number of prominent peaks is unknown before-hand you can employ a threshold at this time as a measure of prominence.

Share:
11,988
tgun926
Author by

tgun926

Updated on June 13, 2022

Comments

  • tgun926
    tgun926 almost 2 years

    I'm having trouble trying to find the 4 dominant peaks in this graph

    Graph

    The signal is values are very jittery, in that they go up then down, making it hard to find the maximum value and it's index.

    function [peaks, locations] = findMaxs (mag, threshold)
    len = length(mag);
    
    prev = 1;
    cur = 2;
    next = 3;
    k = 1; %number of peaks
    while next < len
        if mag(cur) - mag(prev) > threshold
            if mag(cur) > mag(next)
                peaks(k) = mag(cur);
                fprintf('peak at %d\n', cur);
                k = k + 1;
            end
        end
        prev = cur;
        cur = next;
        next = next + 1;
    end
    
    end
    

    findpeaks() gave me way too many results, so I'm using this function. However, if I set the threshold too low, I get too many results, and if I set it even very slightly too high, I miss one of the dominant peaks.

    How can I do this?

  • Yuriy Kravets
    Yuriy Kravets almost 8 years
    that's a lot of calculation -_-