首页 > 解决方案 > STFT 的节能

问题描述

我正在进行的项目需要一个短时间的傅立叶变换。为此,我使用 scipy.signal.stft。从理论上我们得知,时域信号与时频域具有相同的能量;Parseval 定理 ( https://en.wikipedia.org/wiki/Parseval%27s_theorem )。但是,当我使用 scipy.signal.stft 时,如果比较两个能量值的计算,我不会获得相同数量的能量。我很确定,这是因为在使用 scipy.signal.stft 时涉及到一些缩放,所以我通过源代码吐槽。经过一番深入搜索,我找到了 np.sqrt(1/(sum(win)**2)) 的比例因子。但是,使用此比例因子不起作用:

示例代码:

fs = 10e3
N = 1e5
amp = 2 * np.sqrt(2)
noise_power = 0.01 * fs / 2
time = np.arange(N) / float(fs)
mod = 500*np.cos(2*np.pi*0.25*time)
carrier = amp * np.sin(2*np.pi*3e3*time + mod)
noise = np.random.normal(scale=np.sqrt(noise_power),
                         size=time.shape)
noise *= np.exp(-time/5)
x = carrier + noise

frame_size = 1000
window = scipy.signal.windows.hann(frame_size,sym=False)
f, t, Zxx = scipy.signal.stft(x, fs, window=window, nperseg=frame_size)
scale = np.sqrt(1/(sum(window)**2))
Zxx_scaled = Zxx/scale

Et=np.sum(x**2)
Ef=np.sum(abs(Zxx_scaled)**2)/N
print("Et = %.3f" % Et)
print( "Ef = %.3f" % Ef)

结果(取决于噪声,但在规模上):

Et = 1641328.607
Ef = 6158.539

有谁知道如何正确缩放生成的 STFT 矩阵值以获得相等的能级并证明 STFT 的能量守恒?

(我正在寻找一个sum(window)**2恒定的变换(和窗口),并且由于在 STFT 和 I-STFT 中使用了窗口,因此如果我使用 hann 窗口,我假设我有一个“紧框架”变换。但是,证明能量守恒是第一步……)

标签: pythonscipysignal-processingfft

解决方案


推荐阅读