c# - 如何从傅里叶输出中生成详细的频谱图?
问题描述
我正在用 C# 在 Visual Studio 2010 中开发一个小应用程序来绘制频谱图(频率“热图”)。
我已经完成了基本的事情:
- 从输入信号阵列中切出一个矩形窗口阵列
- 将该数组输入 FFT,返回复数值
- 将幅度值存储在数组中(该窗口的频谱)
- 步进窗口,并将新值存储在其他数组中,从而生成一个锯齿状数组,其中包含窗口的每一步及其光谱
- 将它们绘制到图形对象中,颜色使用热图的全局最小值/最大值作为相对冷和热
屏幕截图的左侧显示了我的应用程序,在右侧有一个频谱图,用于相同的输入(512 个样本长)和相同的矩形窗口,大小为 32,来自名为“过去 - 时间序列分析”的程序(https:// folk.uio.no/ohammer/past/index.html)。我的 512 长样本数组仅包含 100 到 1400 范围内的整数元素。(注意:PAST 频谱图最右侧的浅蓝色条只是因为我不小心在末尾留下了一个不必要的“0”元素输入数组。否则它们是相同的。)
截图链接:https ://drive.google.com/open?id=1UbJ4GyqmS6zaHoYZCLN9c0JhWONlrbe3
但是我在这里遇到了一些问题:
- 频谱图看起来很不详细,与我在“过去时间序列分析”中制作的另一张相关,以供参考,并且看起来非常详细。这是为什么?我知道对于例如 32 个长时间窗口,FFT 返回 32 个元素,这里不需要 0. elem,接下来的 32/2 个元素具有我需要的幅度值。但这意味着 32 长窗口的输出频率“分辨率”为 16。这正是我的程序使用的。但是“PAST”程序显示了更多细节。如果您查看蓝色背景中的细线,您会发现它们在频率轴上显示出很好的图案,但在我的频谱图中,这些信息仍然看不到。为什么?
- 在开始 (windowSize/2) 宽窗口步进带和结束 (windowSize/2) 步进带中,FFT 输入的值较少,因此输出较少,或者精度较低。但在“PAST”程序中,这些部分似乎也比较详细,而不是像我的那样只是拉伸条。我该如何改进呢?
- FFT 返回数组的 0. 元素(所谓的“DC”元素)是一个巨大的数字,它比样本平均值甚至它的总和大很多。这是为什么?
- 为什么我的值(例如,您在彩条附近看到的最大值)如此之大?这只是 FFT 输出的幅度值。为什么 PAST 程序中有不同的值?我应该在 FFT 输出上使用什么校正来获得这些值?
如果您对此主题有更多了解,请分享您的想法。我对此很陌生。一个多星期前,我才第一次读到傅立叶变换。
提前致谢!
解决方案
要在垂直轴上获得更多的平滑度,请对您的 FFT 进行零填充,以便输出中有更多(内插)频率区间。例如,零填充您的 32 个数据点,以便您可以使用 256 点或更大的 FFT。
要在水平轴上获得更高的平滑度,请重叠 FFT 输入窗口(75% 或更多重叠)。
对于两者,使用平滑窗口函数(Hamming 或 Von Hann 等),并尝试更宽的窗口,超过 32 个(因此重叠更多)。
要获得更好的着色,请尝试使用颜色映射表,输入是(非零)幅度的 log()。
您还可以为每个图形 XY 点使用多个不同的 FFT,并根据局部属性决定使用哪个着色。
推荐阅读
- yii2 - 从 yii2 中的动态表单按钮调用 Javascript
- ios - 获取 Swift 子目录中资源的所有 URL
- html - 隐藏溢出不适用于图像
- java - 从本地存储库获取最新版本的 jar
- amazon-web-services - AWS CloudWatch Events 在 STS 角色上触发 SNS 为跨账户代入
- python - 将此 curl 命令转换为 python 请求库
- c# - 用c#从串口读取多个数据值
- vue.js - 在点击指令上切换类?
- android - Qt-Creator 无法编译 - 没有这样的文件或目录“c++config.h”
- css - 使用 ruby 将 sass 编译为 css