关于scipy.signal.stft重叠帧数计算及结果维度的疑问
关于scipy.signal.stft输出结果的疑问解答
嘿,我来帮你把这几个问题掰扯清楚~
1. 2049代表什么含义?
这个2049是STFT的频率轴点数,和你处理的实值音频信号直接相关:
- 你设置的窗口大小是4096,scipy默认用和窗口大小相同的FFT点数(除非手动指定
nfft参数)。 - 对于实值信号,FFT的结果是共轭对称的——负频率部分的信息和正频率部分完全重复。为了节省计算和存储,scipy默认只返回**正频率区间(包括直流分量)**的结果,点数计算公式是
nperseg // 2 + 1,也就是4096//2 +1 =2049。 - 这个数值刚好对应你得到的
f数组的长度,f里的每个元素就是从0Hz到采样率一半(44100/2=22050Hz)的频率点。
2. 重叠帧数是否为2049?当然不是!
首先得纠正一个概念:我们说的“重叠”指的是相邻两个分析窗口之间重叠的样本数量,而不是“帧数”。
你提到scipy默认重叠是window_size//2,这里就是4096//2=2048个样本重叠——也就是说,上一个窗口和下一个窗口有2048个样本是重复的。
3. 如何计算STFT的时间帧数量?
你得到的Zxx形状是(2049,84),其中84就是时间帧的总数,计算逻辑是基于总采样数、窗口大小和步长(步长=窗口大小-重叠样本数):
- 先算出步长:
hop_length = nperseg - noverlap =4096-2048=2048,也就是每移动2048个样本就计算一帧STFT。 - 时间帧数量的核心计算公式可以参考:
不过scipy内部可能会根据是否自动补零微调(比如最后一帧样本不够时会补零凑满窗口大小),所以最终得到的帧数量是84,和你实际运行的结果一致。import numpy as np n_samples = 169600 nperseg = 4096 hop_length = 2048 n_frames = int(np.ceil((n_samples - nperseg)/hop_length)) + 1
总结一下:Zxx的第一个维度是频率点数(2049),第二个维度是时间帧数量(84),重叠的是2048个样本,不是帧数哦~
内容的提问来源于stack exchange,提问作者Ashan Priyadarshana
相关产品推荐
相关产品推荐

