摘要:一直以來都是用MATLAB做信號處理,得到預處理的特徵後再用Python進一步應用神經網絡之類的方法。這裏將MATLAB中的FFT、STFT、加窗以及帶通濾波通過Python接口實現,防止以後MATLAB用不了了,一定程度上也提高了效率,不用兩個軟件換來換去。
系列目錄
- Python信號處理:快速傅里葉變換(FFT),短時傅里葉變換(STFT),窗函數,以及濾波
- Python信號處理:自相關函數(對標MATLAB中的autocorr)
- Python信號處理:波束形成及目標方位估計,CBF、MVDR
- Python信號處理:cvxpy工具包求解稀疏約束優化問題
目錄
- 快速傅里葉變換(FFT)
- 窗函數對傅里葉變換的影響
- 兩種信號濾波方式
- 短時傅里葉變換(STFT)
1. 快速傅里葉變換
FFT的實現主要有兩種方法,分別通過np.fft
或scipy.fftpack
中的fft實現,實現方法基本是一樣的,以scipy.fftpack.fft
爲例。
首先生成一個帶噪聲的信號,頻率爲10、15、20 Hz,採樣率=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,採樣率=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.stft
和scipy.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點數、消除趨勢,兩者基本都是一樣的。