Python信號處理:快速傅里葉變換(FFT),短時傅里葉變換(STFT),窗函數,以及濾波

摘要:一直以來都是用MATLAB做信號處理,得到預處理的特徵後再用Python進一步應用神經網絡之類的方法。這裏將MATLAB中的FFT、STFT、加窗以及帶通濾波通過Python接口實現,防止以後MATLAB用不了了,一定程度上也提高了效率,不用兩個軟件換來換去。

系列目錄

  1. Python信號處理:快速傅里葉變換(FFT),短時傅里葉變換(STFT),窗函數,以及濾波
  2. Python信號處理:自相關函數(對標MATLAB中的autocorr)
  3. Python信號處理:波束形成及目標方位估計,CBF、MVDR
  4. Python信號處理:cvxpy工具包求解稀疏約束優化問題

目錄

  1. 快速傅里葉變換(FFT)
  2. 窗函數對傅里葉變換的影響
  3. 兩種信號濾波方式
  4. 短時傅里葉變換(STFT)

1. 快速傅里葉變換

FFT的實現主要有兩種方法,分別通過np.fftscipy.fftpack中的fft實現,實現方法基本是一樣的,以scipy.fftpack.fft爲例。

首先生成一個帶噪聲的信號,頻率爲10、15、20 Hz,採樣率fsf_s=100 Hz,時長2 s。時域波形如下左圖所示。使用scipy.fftpack.fft獲取頻域信號,同時使用scipy.fftpack.fftfreq獲取,信號頻譜如下右圖所示。

X = fftpack.fft(x)           # x爲時域信號
freqs = fftpack.fftfreq(N) * fs  # N爲信號點數,fs爲採樣率

在這裏插入圖片描述

2. 窗函數對傅里葉變換的影響

以凱撒窗np.kaiser(點數,係數)爲例,凱撒窗能抑制旁瓣,但會加寬主瓣。使用時,在fft中對信號加窗即可。下圖給出不同係數的凱撒窗對主瓣和旁瓣的影響。可以看到,加窗後旁瓣受到抑制,但主瓣變寬。通過調整係數,可以改變凱撒窗的窗口。

X = fftpack.fft(np.kaiser(N, 6) * x)

在這裏插入圖片描述

3. 兩種信號濾波方式

A. 通過FFT和IFFT進行濾波

先對信號進行FFT,然後保留想要的頻率,將不要的頻率都設爲0,再將頻譜進行IFFT得到濾波後的時域波形。

def filter1(signal, freq, freqs):
    """利用FFT進行濾波。
    # Arguments
    #   signal: 帶噪聲的時域信號
    #   freq: 想要的頻率
    #   freqs: 信號頻率
    # Return
    #   y: 濾波後的時域信號
    """
    X = fftpack.fft(signal)
    index_freq = [np.where(i == freqs)[0][0] for i in freq]
    index_zeros = np.setdiff1d(np.arange(0, len(freqs)), index_freq)
    X[index_zeros] = 0
    y = fftpack.ifft(X)
    return y

y = filter1(x, [10, 15, 20], freqs)

濾波後的時域信號及其頻譜如下圖所示。
在這裏插入圖片描述

B. 通過butter和filtfilt進行濾波

使用scipy.signal.butter通過截至頻率獲取濾波器係數,利用scipy.signal.filtfilt進行濾波。假設頻率爲10、15、20 Hz,採樣率fsf_s=100 Hz,時長2 s的時域信號,截止頻率爲10和20 Hz。

wl = 2 * (10 - 1) / fs
wh = 2 * (20 + 1) / fs
b, a = signal.butter(8, [wl ,wh], 'bandpass')  #8表示濾波器的階數
filtedData = signal.filtfilt(b, a, x)

濾波後的時域信號及其頻譜如下圖所示。
在這裏插入圖片描述

4. 短時傅里葉變換

scipy.signal.stftscipy.signal.spectrogram兩個類似的方法,區別在於後者返回的是能量,前者返回的是頻譜,差一個絕對值的平方。

兩者接口參數如下:

  • scipy.signal.stft(x,fs=1.0,window='hann',nperseg=256,noverlap=None,nfft=None,detrend=False,return_onesided=True,boundary ='zeros',padded=True,axis=-1 )

  • scipy.signal.spectrogram(x, fs=1.0, window=('tukey', 0.25), nperseg=None, noverlap=None, nfft=None, detrend=’constant’, return_onesided=True, scaling=’density’, axis=-1, mode=’psd’)

常用參數從左往右依次爲:信號、採樣率、窗、每段長度、重疊長度、FFT點數、消除趨勢,兩者基本都是一樣的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章