如何从傅立叶输出中生成详细的频谱图?

How to produce a detailed spectrogram from Fourier output?

我正在 Visual Studio 2010 年用 C# 开发一个小应用程序来绘制频谱图(频率 "heat map")。

我已经完成了基本的事情:

屏幕截图的左侧显示了我的应用程序,右侧是相同输入(512 个样本长)和相同矩形 window 的频谱图,来自名为 "PAST - time series analysis" (https://folk.uio.no/ohammer/past/index.html)。我的 512 长样本数组仅包含 100 到 1400 左右的整数元素。 (注意:PAST 频谱图最右边的浅蓝色条只是因为我不小心在那个输入数组的末尾留下了一个不必要的“0”元素。否则它们是相同的。)

Link截图:https://drive.google.com/open?id=1UbJ4GyqmS6zaHoYZCLN9c0JhWONlrbe3

但是我在这里遇到了一些问题:

  1. 谱图好像很不详,和我在"PAST time series analysis"做的另一张参考一下,那一张看起来很详细。这是为什么? 我知道例如32 long time window, FFT returns 32个元素,这里不需要0.elem,接下来的32/2个元素有我需要的量级值。但这意味着 32 长 window 输出的频率 "resolution" 是 16。这正是我的程序使用的。但是 "PAST" 程序显示了更多细节。如果您查看蓝色背景中的细线,您会发现它们在频率轴上显示出漂亮的图案,但在我的频谱图中,这些信息仍然看不到。为什么?
  2. 在开始(windowSize/2)宽window步带和结束(windowSize/2)步带中,FFT输入的值较少,因此较少输出,或者精度较低。但在 "PAST" 程序中,这些部分看起来也相对详细,而不是像我的那样只是拉伸条。我该如何改进?
  3. FFTreturn数组的第0个元素(即所谓的"DC"元素)是一个巨大的数,比样本平均值大很多,甚至比它的总和还要大。这是为什么?
  4. 为什么我的值(例如,您在颜色条附近看到的最大值)如此之大?这只是 FFT 输出的幅度值。为什么 PAST 程序中有不同的值?我应该在 FFT 输出上使用什么校正来获得这些值?

如果您对此主题了解更多,请分享您的想法。我对此很陌生。我一个多星期前才第一次读到傅里叶变换。

提前致谢!

你好 LimeAndConconut,

虽然我不了解PAST,但我可以为您提供一些有关FFT 的一般信息。这是您的每一个点的答案

1- 你是对的,对 32 个元素 returns 32 个频率(零频率、正分量和负分量)执行 FFT。这意味着您已经拥有数据中的所有信息,并且 PAST 无法使用相同的 32 大小 window 获取更多信息。这就是为什么我怀疑要对数据进行插值以进行绘图,但这只是视觉上的。再一次,PAST 无法创建比您的数据更多的信息。

2- 我再次同意你的看法。在边界上,您可以访问频率较低的组件。您可以决定不同的策略:不在边界处显示数据,或者使用零填充或循环填充扩展此数据

3- FFT 的零元素应该是 32 windowed 数组的总和。您需要检查 FFT 归一化,查看您的 FFT 函数的文档。

4- 再次检查 FFT 归一化。由于 PAST 颜色条显示负值,因此它似乎是以对数标度绘制的。这是使用对数绘制高动态数据以增强细节的常见用法。

为了在垂直轴上获得更多的平滑度,对 FFT 进行零填充,以便在输出中有更多(插值)频率仓。例如,零填充 32 个数据点,以便您可以使用 256 点或更大的 FFT。

要在水平轴上获得更多平滑度,请重叠 FFT 输入 windows(重叠 75% 或更多)。

对于两者,使用平滑的 window 函数(Hamming 或 Von Hann,et.al),并尝试更宽 windows,超过 32(因此重叠更多)。

为了获得更好的着色效果,请尝试使用颜色映射 table,输入是(非零)量级的 log()。

您还可以对每个图形 XY 点使用多个不同的 FFT,并根据局部属性决定用哪个着色。