Detecting Peaks in a FFT Plot

前端 未结 1 539
心在旅途
心在旅途 2021-01-03 07:03

I was wondering how is it possible to detect new peaks within an FFT plot in Python. let\'s say i have this simple Plot: And i want to automatically measure the \'Similarity

相关标签:
1条回答
  • 2021-01-03 07:39

    There are many ways to find peaks, and even to interpolate their sub-sample location. Once you have the peaks, just check if you find a new one.

    You can use the peakutils package to find the peaks. You can set there the threshold and minimum distance between peaks.

    import numpy as np
    from pylab import *
    import scipy.fftpack
    
    # Number of samplepoints
    N = 600
    # sample spacing
    T = 1.0 / 800.0
    x = np.linspace(0.0, N*T, N)
    y1 = np.sin(50.0 * 2.0*np.pi*x) + 0.5*np.sin(80.0 * 2.0*np.pi*x)+ 0.7*np.sin(30.0 * 2.0*np.pi*x)+ 0.5*np.sin(10.0 * 2.0*np.pi*x)
    y2 = np.sin(50.0 * 2.0*np.pi*x) + 0.5*np.sin(80.0 * 2.0*np.pi*x)+ 0.2*np.sin(60.0 * 2.0*np.pi*x)+ 0.4*np.sin(40.0 * 2.0*np.pi*x)
    yf1 = scipy.fftpack.fft(y1)
    yf2 = scipy.fftpack.fft(y2)
    xf = np.linspace(0.0, 1.0/(2.0*T), N/2)
    
    v1 = 2.0/N * np.abs(yf1[:N/2])
    v2 = 2.0/N * np.abs(yf2[:N/2])
    
    # Find peaks
    import peakutils
    peaks_ind1 = peakutils.indexes(v1, thres=0.2, min_dist=5)
    peaks_ind2 = peakutils.indexes(v2, thres=0.2, min_dist=5)
    
    dist_th_for_new_peaks = 3
    new_peaks = []
    for p in peaks_ind2:
        found_new_peak = np.all(np.abs(p - peaks_ind1) > dist_th_for_new_peaks)
        if found_new_peak:
            new_peaks.append(p)
            print("New Peak!! - %d" % p)
    
    fig, ax = plt.subplots()
    plot(xf, v1, color='blue')
    plot(xf, v2, color='green')
    for p in peaks_ind1:
        ax.scatter(xf[p], v1[p], s=40, marker='s', color='blue', label='v1')
    for p in peaks_ind2:
        ax.scatter(xf[p], v2[p], s=40, marker='s', color='green', label='v2')    
    for p in new_peaks:
        ax.scatter(xf[p], v2[p], s=40, marker='s', color='red', label='new peaks')        
    
    xlabel('Freq (Hz)',fontsize=16,weight='bold')
    ylabel('|Y(freq)|',fontsize=16,weight='bold')
    
    ax = gca()
    fontsize = 14
    for tick in ax.xaxis.get_major_ticks():
        tick.label1.set_fontsize(fontsize)
        tick.label1.set_fontweight('bold')
    for tick in ax.yaxis.get_major_ticks():
        tick.label1.set_fontsize(fontsize)
        tick.label1.set_fontweight('bold')
    ax.set_xlim([0,400])
    ax.set_ylim([0,0.8])
    grid(True)
    show()
    

    The red squares are the new peaks that were found in the green signal:

    0 讨论(0)
提交回复
热议问题