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

Posted

技术标签:

【中文标题】如何从傅里叶输出中生成详细的频谱图?【英文标题】:How to produce a detailed spectrogram from Fourier output? 【发布时间】:2020-01-30 20:40:49 【问题描述】:

我正在用 C# 在 Visual Studio 2010 中开发一个小应用程序来绘制频谱图(频率“热图”)。

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

从输入信号数组中切出一个矩形窗口数组 将该数组输入 FFT,返回复数值 将幅度值存储在数组中(该窗口的频谱) 步进窗口,并将新值存储在其他数组中,从而生成一个锯齿状数组,其中包含窗口的每一步及其光谱 将它们绘制到图形对象中,颜色使用热图的全局最小值/最大值作为相对冷和热

屏幕截图的左侧显示了我的应用程序,在右侧有一个频谱图,用于相同的输入(512 个样本长)和来自名为“过去 - 时间序列分析”的程序的大小为 32 的相同矩形窗口(@ 987654321@)。我的 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 输出上使用什么校正来获得这些值?

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

提前致谢!

【问题讨论】:

如果您想在 STFT(短时傅立叶变换)中获得更高的频率分辨率,则需要更多的时间步长,这意味着这会降低您的时间分辨率。但是,您可以重叠您的时间间隔(实际上是插值)。您可以通过从数据中减去所有数据的平均值来移除 DC。是否要保留它是编程之外的问题,这是您需要考虑的数据的物理含义。同上关于颜色条,也许你还没有删除 DC。 注意:我会首先在更高级别的环境(如 Matlab、Python Numpy、Mathematica)中开发类似的东西来计算参数。这也将使您更容易获得对您的问题的支持(可以发布短代码,图像代码可以制作,因此您不会陷入 C# 实现问题)。 感谢您的所有回答! :) 我最大的问题是(因为我的 Y 值都很大)我应该在任何处理之前从整个信号数组中减去平均值。现在我已经做到了。我现在还使用了最大重叠量,并添加了零填充,这对强调细节很有帮助。对数着色也非常有效,并且显示接近最大幅度的信息更易于识别。如果我使用 32、64(或任何偶数)长窗口,窗口函数必须像“matlab 对称”:en.wikipedia.org/wiki/Window_function#Symmetry 【参考方案1】:

要在垂直轴上获得更高的平滑度,请将 FFT 补零,以便输出中有更多(内插)频率区间。例如,零填充您的 32 个数据点,以便您可以使用 256 点或更大的 FFT。

要使水平轴更平滑,请重叠 FFT 输入窗口(重叠 75% 或更多)。

对于这两者,使用平滑窗口函数(Hamming 或 Von Hann 等人),并尝试更宽的窗口,超过 32 个(因此重叠更多)。

要获得更好的着色,请尝试使用颜色映射表,输入是(非零)幅度的 log()。

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

【讨论】:

【参考方案2】:

你好 LimeAndConconut,

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

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

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

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

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

【讨论】:

以上是关于如何从傅里叶输出中生成详细的频谱图?的主要内容,如果未能解决你的问题,请参考以下文章

MATLAB傅里叶变换后寻找频谱次大值对应的位置

傅里叶分析

信号分析——从傅里叶变化到FFT

用matlab进行傅里叶变换。傅里叶变换得到的相位谱、幅值谱有啥用?怎么分析?

图片处理-opencv-12.图像傅里叶变换

傅里叶变换 小波变换