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)[源代码]¶
执行短时傅立叶逆变换(ISTFT)。
- 参数
- Zxxarray_like
待重构信号的STFT。如果传递的是纯实数组,则会将其强制转换为复杂数据类型。
- fs浮动,可选
时间序列的采样频率。默认为1.0。
- window字符串或元组或array_like,可选
要使用的所需窗口。如果 window 是字符串或元组,则将其传递给
get_window
以生成窗口值,该窗口值是DFT-即使在默认情况下也是如此。看见get_window
有关窗口和所需参数的列表,请执行以下操作。如果 window is array_like它将直接用作窗口,其长度必须为nperseg。默认为Hann窗口。必须与用于生成STFT的窗口匹配以实现忠实反转。- nperseg整型,可选
每个STFT段对应的数据点数量。如果每个数据段的数据点数量为奇数,或者如果STFT是通过填充的,则必须指定此参数
nfft > nperseg
。如果 None ,该值取决于 Zxx 和 input_onesided 。如果 input_onesided 是 True ,nperseg=2*(Zxx.shape[freq_axis] - 1)
。否则,nperseg=Zxx.shape[freq_axis]
。默认为 None 。- noverlap整型,可选
线段之间要重叠的点数。如果 None ,线束段长度的一半。默认为 None 。指定时,必须满足可乐约束(请参阅下面的注释),并且应与用于生成STFT的参数相匹配。默认为 None 。
- nfft整型,可选
每个STFT段对应的FFT点数。如果STFT是通过以下方式填充的,则必须指定此参数
nfft > nperseg
。如果 None ,默认值与的相同 nperseg ,但有一个例外:如果 input_onesided 是真的,并且nperseg==2*Zxx.shape[freq_axis] - 1
, nfft 也具有这个价值。这种情况允许使用以下命令正确地反转奇数长度的无填充STFTnfft=None
。默认为 None 。- input_onesided布尔值,可选
如果 True 将输入数组解释为单边FFT,例如由返回的
stft
使用return_onesided=True
和numpy.fft.rfft
。如果 False ,将输入解释为双面FFT。默认为 True 。- boundary布尔值,可选
指定输入信号是否通过提供非“None”在其边界处扩展
boundary
参数为stft
。默认为 True 。- time_axis整型,可选
STFT的时间段所在的位置;默认值为最后一个轴(即
axis=-1
)。- freq_axis整型,可选
STFT的频率轴所在的位置;默认值为倒数第二个轴(即
axis=-2
)。
- 退货
- tndarray
输出数据时间数组。
- xndarray
的ISTFT Zxx 。
参见
stft
短时傅里叶变换
check_COLA
检查是否满足常量重叠添加(Cola)约束
check_NOLA
检查是否满足非零重叠添加(NOLA)约束
注意事项
为了使得能够通过具有以下项的逆STFT来反转STFT
istft
信号加窗必须遵守“非零重叠相加”(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] }\]不是零。NOLA约束可以用
check_NOLA
功能。不保证已被修改(通过掩蔽或其他方式)的STFT对应于精确可实现的信号。此函数通过中详细介绍的最小二乘估计算法实现iSTFT [2], 其产生最小化返回信号的STFT和修改后的STFT之间的均方误差的信号。
0.19.0 新版功能.
参考文献
- 1
奥本海姆,艾伦·V,罗纳德·W·谢弗,约翰·R·巴克,“离散时间信号处理”,普伦蒂斯·霍尔,1999。
- 2
丹尼尔·W·格里芬,Jae S.Lim“基于修正短时傅立叶变换的信号估计”,IEEE1984,10.1109/TASSP.1984.1164317
示例
>>> from scipy import signal >>> import matplotlib.pyplot as plt >>> rng = np.random.default_rng()
产生一个测试信号,一个50 Hz的2 Vrms正弦波,被0.001 V**2/Hz的白噪声破坏,采样频率为1024 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
计算短时傅立叶变换,并绘制其大小
>>> 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()