scipy.signal.

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,則值取決於 Zxxinput_onesided 的形狀。如果 input_onesidedTruenperseg=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=Truenumpy.fft.rfft。如果 False,將輸入解釋為雙邊 FFT。預設值為 True

boundarybool, optional

指定輸入訊號是否在其邊界處通過向 stft 提供非 None boundary 參數來擴展。預設值為 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()
../../_images/scipy-signal-istft-1_00_00.png

將小於載波幅度 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()
../../_images/scipy-signal-istft-1_01_00.png

請注意,清理後的訊號不像原始訊號那樣突然開始,因為瞬態的一些係數也被移除

>>> 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()
../../_images/scipy-signal-istft-1_02_00.png