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 ,该值取决于 Zxxinput_onesided 。如果 input_onesidedTruenperseg=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] - 1nfft 也具有这个价值。这种情况允许使用以下命令正确地反转奇数长度的无填充STFT nfft=None 。默认为 None

input_onesided布尔值,可选

如果 True 将输入数组解释为单边FFT,例如由返回的 stft 使用 return_onesided=Truenumpy.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()
../../_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