istft#
- scipy.signal.istft(Zxx, fs=1.0, window='hann', nperseg=None, noverlap=None, nfft=None, input_onesided=True, boundary=True, time_axis=-1, freq_axis=-2, scaling='spectrum')[原始碼]#
執行反向短時傅立葉轉換 (舊版函式)。
舊版
此函式被視為舊版,將不再接收更新。雖然我們目前沒有移除它的計畫,但我們建議新程式碼改用更現代的替代方案。
ShortTimeFFT
是一個更新的 STFT / ISTFT 實作,具有更多功能。比較 可以在 短時傅立葉轉換 章節的 SciPy 使用者指南 中找到。- 參數:
- Zxxarray_like
要重建的訊號之 STFT。如果傳遞純實數陣列,它將被轉換為複數資料類型。
- fsfloat, optional
時間序列的取樣頻率。預設值為 1.0。
- windowstr 或 tuple 或 array_like, optional
想要使用的視窗。如果 window 是字串或 tuple,它會傳遞給
get_window
以產生視窗值,預設情況下這些值是 DFT 偶數。請參閱get_window
以取得視窗和必要參數的清單。如果 window 是 array_like,它將直接用作視窗,且其長度必須為 nperseg。預設值為 Hann 視窗。必須與用於產生 STFT 的視窗相符,才能進行忠實的反轉。- npersegint, optional
對應於每個 STFT 段的資料點數量。如果每個段的資料點數量為奇數,或者如果 STFT 通過
nfft > nperseg
進行填充,則必須指定此參數。如果 None,則值取決於 Zxx 和 input_onesided 的形狀。如果 input_onesided 為 True,nperseg=2*(Zxx.shape[freq_axis] - 1)
。否則,nperseg=Zxx.shape[freq_axis]
。預設值為 None。- noverlapint, optional
段之間重疊的點數。如果 None,則為段長度的一半。預設值為 None。當指定時,必須滿足 COLA 約束 (請參閱下面的註釋),並且應與用於產生 STFT 的參數相符。預設值為 None。
- nfftint, optional
對應於每個 STFT 段的 FFT 點數。如果 STFT 通過
nfft > nperseg
進行填充,則必須指定此參數。如果 None,則預設值與 nperseg 相同,如上詳述,但有一個例外:如果 input_onesided 為 True 且nperseg==2*Zxx.shape[freq_axis] - 1
,則 nfft 也採用該值。這種情況允許使用nfft=None
正確反轉奇數長度未填充的 STFT。預設值為 None。- input_onesidedbool, optional
如果 True,將輸入陣列解釋為單邊 FFT,例如由
stft
傳回的return_onesided=True
和numpy.fft.rfft
。如果 False,將輸入解釋為雙邊 FFT。預設值為 True。- boundarybool, optional
指定輸入訊號是否在其邊界處通過向
stft
提供非 Noneboundary
參數來擴展。預設值為 True。- time_axisint, optional
STFT 的時間段位於何處;預設值為最後一個軸 (即
axis=-1
)。- freq_axisint, optional
STFT 的頻率軸位於何處;預設值為倒數第二個軸 (即
axis=-2
)。- scaling: {‘spectrum’, ‘psd’}
預設的 ‘spectrum’ 縮放允許將 Zxx 的每個頻率線解釋為幅度譜。 ‘psd’ 選項將每條線縮放為功率譜密度 - 它允許通過數值積分
abs(Zxx)**2
來計算訊號的能量。
- 返回:
- tndarray
輸出資料時間陣列。
- xndarray
Zxx 的 iSTFT。
另請參閱
stft
短時傅立葉轉換
ShortTimeFFT
提供更多功能的較新 STFT/ISTFT 實作。
check_COLA
檢查是否滿足恆定重疊相加 (COLA) 約束
check_NOLA
檢查是否滿足非零重疊相加 (NOLA) 約束
註釋
為了能夠通過使用
istft
的反向 STFT 來反轉 STFT,訊號視窗化必須遵守「非零重疊相加」(NOLA) 的約束\[\sum_{t}w^{2}[n-tH] \ne 0\]這確保了出現在重疊相加重建方程式分母中的歸一化因子
\[x[n]=\frac{\sum_{t}x_{t}[n]w[n-tH]}{\sum_{t}w^{2}[n-tH]}\]不為零。可以使用
check_NOLA
函式檢查 NOLA 約束。已修改 (通過遮罩或其他方式) 的 STFT 不保證對應於精確可實現的訊號。此函式通過 [2] 中詳述的最小平方估計演算法來實作 iSTFT,該演算法產生一個訊號,該訊號使返回訊號的 STFT 與修改後的 STFT 之間的均方誤差最小化。
在版本 0.19.0 中新增。
參考文獻
[1]Oppenheim, Alan V., Ronald W. Schafer, John R. Buck “離散時間訊號處理”,Prentice Hall,1999 年。
[2]Daniel W. Griffin, Jae S. Lim “從修改後的短時傅立葉轉換進行訊號估計”,IEEE 1984, 10.1109/TASSP.1984.1164317
範例
>>> import numpy as np >>> from scipy import signal >>> import matplotlib.pyplot as plt >>> rng = np.random.default_rng()
產生測試訊號,一個在 50Hz 的 2 Vrms 正弦波,受到在 1024 Hz 取樣的 0.001 V**2/Hz 白雜訊干擾。
>>> fs = 1024 >>> N = 10*fs >>> nperseg = 512 >>> amp = 2 * np.sqrt(2) >>> noise_power = 0.001 * fs / 2 >>> time = np.arange(N) / float(fs) >>> carrier = amp * np.sin(2*np.pi*50*time) >>> noise = rng.normal(scale=np.sqrt(noise_power), ... size=time.shape) >>> x = carrier + noise
計算 STFT,並繪製其幅度
>>> f, t, Zxx = signal.stft(x, fs=fs, nperseg=nperseg) >>> plt.figure() >>> plt.pcolormesh(t, f, np.abs(Zxx), vmin=0, vmax=amp, shading='gouraud') >>> plt.ylim([f[1], f[-1]]) >>> plt.title('STFT Magnitude') >>> plt.ylabel('Frequency [Hz]') >>> plt.xlabel('Time [sec]') >>> plt.yscale('log') >>> plt.show()
將小於載波幅度 10% 或以下的成分歸零,然後通過反向 STFT 轉換回時間序列
>>> Zxx = np.where(np.abs(Zxx) >= amp/10, Zxx, 0) >>> _, xrec = signal.istft(Zxx, fs)
將清理後的訊號與原始訊號和真實載波訊號進行比較。
>>> plt.figure() >>> plt.plot(time, x, time, xrec, time, carrier) >>> plt.xlim([2, 2.1]) >>> plt.xlabel('Time [sec]') >>> plt.ylabel('Signal') >>> plt.legend(['Carrier + Noise', 'Filtered via STFT', 'True Carrier']) >>> plt.show()
請注意,清理後的訊號不像原始訊號那樣突然開始,因為瞬態的一些係數也被移除
>>> plt.figure() >>> plt.plot(time, x, time, xrec, time, carrier) >>> plt.xlim([0, 0.1]) >>> plt.xlabel('Time [sec]') >>> plt.ylabel('Signal') >>> plt.legend(['Carrier + Noise', 'Filtered via STFT', 'True Carrier']) >>> plt.show()