理解FFT, STFT, 加窗的含义
理解所谓的N点FFT是啥, 理解STFT, 理解加窗的作用
文章目录
补零(zero padding)
带来的效果: 频率分辨率变好
- 补零就是在信号后面加上0
比如我有一个随机信号, 长度为8, 所谓的长度是说被8个点采样了, 如下图:
那么我们知道它输出的X[K] 也应该有8个数, 代表的意思是8个点里有0次周期, 1次周期, 2次周期, …7次周期的基波. 所以当我的采样点加多, 对应的输出的X[k]也就越长, 这里注意的是 在固定的采样频率下, 采样点是不变的, 那么我们就可以把短的信号补长, 补上0
然后再做DFT就可以得到长度为8的, 为16的等不等的数组, 会发现补零使得图变平滑了, 实质就是 频率的分辨率变小了, 之前的时候提到 对应每个X[k], 它的频率是 k ∗ f s / N k*f_s/N k∗fs/N ,所以频率分辨率就是 f s / N f_s/N fs/N .
- 由此可见N越大, 频率分辨率越好.
举例
- 假如我有个信号是由440Hz和441Hz组成的, 假如要想分辨出这两个信号频率分辨率至少是1Hz, 也就是 f s / N f_s/N fs/N <1, 查看下面的补零效果
补零对原信号的影响
- 直观来想, 假如我给一个有限长信号后面补零, 肯定会对原信号造成影响, 这个影响体现在哪呢?
看下面这个图, 假如我的原信号有4410个点, 然后补零到16384个点, 它的频谱图可能是这样的:
假如不补零而是这个信号变长了,就是不在原来的地方断掉而是不断的延续,其频谱图如下:
补零的作用: 增加频率分辨率, 并能任意选择FFT的长度
FFT
FFT 是快速计算DFT的统称
DFT的性质
- 假如N个点的DFT可以分解成 N = n 1 ∗ n 2 N\text=n_1*n_2 N=n1∗n2 的形式, 那么此时的DFT可以分解为两部分DFT, 缩短了计算时间复杂度降低了
- 补零N到2的k次幂, 可以使得任意DFT都分解为2长度的DFT
- 当然X[k]还是中心对称的, 比较容易计算
加窗
N点内非周期振动出现的问题
- 之前的时候都假设信号在采样的N个点里振动了整数个周期
看下面这个图, 第一个是256个点里振动了4个周期, 第二个是把后面的36个点给去掉了
- 现在在第二个后面补零到256个点, 做N=256的DFT, X[4]应该在两个信号中都是最高的那个
按理来说应该只有一个频率, 但是截断补零后第二个信号出现了别的频率, 也就是出现了所谓的频率泄露的情况, 这是为什么呢?
频率泄露的原因
- DFT计算的时候 假定信号会是无限长的, 因为正弦和余弦正交的性质只有在无限长的信号中才成立
DFT计算的时候会把有限长的信号补长, 变为无限长的, 假如不是整数周期的话就会在补的地方出现跳变, 这个跳变的频率其实是无限大的, 所以各个地方都会有频率了
加窗就是为了减少跳变带来的频率泄露
- 看看下面这个汉宁窗的例子, 窗都是从0开始到0结束的, 为了减少跳变, 汉宁窗乘过原信号后就不会存在跳变了, 因为边缘都成了0了
看看加窗后对频谱的影响
- 可以看到加窗去掉了 高频的频率泄露 , 但是在低频的噪声似乎更大了, 但是实际上我们能够知道加上窗后中心频率衰减了多少, 第二高的比例是多少, 相当于从不可控到可控了
STFT
DFT的缺点, 对整个信号进行处理, 没有前后时间信息
比如下面的信号应该是先440Hz, 后660Hz, 但是DFT得到的频谱图完全看不出来
STFT通过帧对信号进行处理
- 假如有一个3s的音频, 我们先取一个10到25ms的时间作为1帧, 如下图:
- 得到的信号 一般不会是恰好有整数个周期, 因此需要加窗
- 加窗前
- 加窗后
- 补零进行傅里叶变换, 得到频谱图
-
可以得到第一帧的X数组, len(X) =N
-
帧移取帧长的25%到75%, 再取一帧
- 等到走完信号后, 竖着构成一个矩阵, k=0在下面
- 对矩阵进行染色, 就得到了实频谱
- 总结: 这里横轴是frame, 纵轴分辨率是 f s / N f_s/N fs/N
帧长短的影响
- 感性来看, 增加frame长度, 每个帧包含的信息多了, 那么测量的频率应该就越准确
- 但是这样导致 时间分辨率降低了, 不能准确知道到底是在什么时候频率发生了改变
可以查看下面的例子, 帧长分别是2048个点, 4096个点, 16384个点, 可以看到frame很小时间分辨率比较好, 能够清楚看到是什么时候跳变的, 但是对音频的频率却不清楚, 假如frame很大, 则频率可以明显的知道, 但是 跳变的界限就不清楚了
hop size的影响(也就是步进值大小的影响)
直观上增加了frame数量
- 可以看下面不同的步进值, 发现区别不大
- 但是重叠还是必要的, 因为边缘可能还是会丢失一部分信息, 所以重叠是要加的, 但是不要加太多
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)