为什么 ShortTimeFFT.upper_border_begin 会受窗口值影响?
数据小许
结论
upper_border_begin(n) 会检查窗口中哪些位置的权重非零。它从信号右端检查窗口切片:如果窗口超出信号范围的部分权重全为零,该切片就不会被视为受到右侧补零的影响。因此,即使窗口长度相同,端点是否为零也可能改变返回的 (k_ub, p_ub)。
这里的 n=50 指输入信号的样本数。返回值分别是受影响的最低信号索引 k_ub 和最低切片索引 p_ub。SciPy 文档将该方法描述为窗口开始伸出信号右边界的位置;源码则通过检查窗口权重是否为零来判断边界。方法文档 · SciPy 源码
为什么这三个例子结果不同
源码会将窗口值转换为平方幅值:
w2 = self.win.real**2 + self.win.imag**2
检查切片超出信号末尾的部分时,如果对应的 w2 全为零,该切片就可以视为没有有效权重越过边界。判断逻辑相当于:
if k_ <= n or all(w2[n-k_:] == 0):
return_value = (q_ + 1) * self.hop - self.m_num_mid, q_ + 1
对于长度为 6、hop=2 的窗口,Hann 窗口末端为零。检查到合适的切片时,超出信号末尾的窗口位置只覆盖这个零权重点,因此该切片不会被视为有有效权重越界。返回值会向后移动一个 hop,得到 (47, 25)。
全 1 窗口的末端非零;替换了 Hann 窗口两端零值的窗口,末端也非零。这些窗口越过边界的部分仍有权重,因此必须更早标记受影响的位置,结果为 (45, 24)。这与题目给出的三组输出一致。
使用时的注意点
- 边界判断取决于窗口端点是否严格为零。源码检查的是
w2 == 0,不会比较窗口值的大小或判断它是否“接近零”。 upper_border_begin返回边界索引,不是窗口幅值或 STFT 结果。- 如果你实际想问的是
lower_border_end,它处理信号左侧边界,判断规则对应窗口左端的非零位置。题目中的代码示例调用的是upper_border_begin。
备注:内容仅供参考。
