来自近乎完美的正弦曲线的奇怪 FFT 频谱

Posted

技术标签:

【中文标题】来自近乎完美的正弦曲线的奇怪 FFT 频谱【英文标题】:Strange FFT spectrum from a near perfect sinusoid 【发布时间】:2019-03-17 13:01:49 【问题描述】:

我在我的 Abaqus 仿真中检索了一些信号以进行验证。真实信号应该是 300kHz 的完美正弦曲线,我使用 scipy.fftpack.fft 对采样信号执行 fft。

但是我得到了一个奇怪的频谱,如下图所示(对不起,我懒得将频谱的 x 轴缩放到正确的频率)。在同一张图中,我将信号切成小块并在时域中绘制。我还对纯正弦波重复了相同的过程。 这完全让我吃惊。如下代码所示,采样频率是信号频率的 16.66 倍。目前,我认为这是由于采样周期的误差很小。理论上,Abaqus 会以固定的时间间隔对其进行采样。如您所见,存在一些小错误,因此我的信号中的点看起来比完美信号更粗。但是这么小的误差是否会给频谱带来显着的差异呢?不然频谱怎么会这样?


仅供参考:这是我信号的放大 fft 频谱:

FYI2:这是用于生成上述数字的 python 代码

def myfft(x, k, label):
    plt.plot(np.abs(fft(x))[0:k], label = label)
    plt.legend()

plt.subplot(4,1,1)
for i in range(149800//200):
    plt.plot(mysignal[200*i:200*(i+1)], 'bo')
plt.subplot(4,1,2)
myfft(mysignal,150000//2, 'fft of my signal')
plt.subplot(4,1,3)
[Fs,f, sample] =  [5e6,300000, 150000]
x = np.arange(sample)
y = np.sin(2 * np.pi * f * x / Fs)
for i in range(149800//200):
    plt.plot(y[200*i:200*(i+1)], 'bo')
plt.subplot(4,1,4)
myfft(y,150000//2, 'fft of a perfect signal')
plt.subplots_adjust(top = 2, right = 2)

FYI3:Here 是我的.npy.txt 格式的信号。信号很长。它有 150001 个点。 .txt 是来自 Abaqus 的原始文件。 .npy 格式是我用来生成上图的格式 - (1) 时间向量被移除,(2) 数据为半精度并归一化。

【问题讨论】:

您的 FFT 结果在频域中几乎呈正弦曲线。这通常意味着时域中的一些类似脉冲的东西。你的时域图没有显示出那种冲动——但我认为你的时域图跳过了波形的最后。也许那里发生了什么事? 【参考方案1】:

您使用的任何标准 FFT 算法都假设您提供的信号是均匀采样的。在这种情况下,均匀意味着时间间隔相等。您的信号显然不是均匀采样的,因此 FFT 不会“看到”完美的正弦,而是失真的版本。因此,您会看到 FFT 计算的所有这些额外频谱分量,以将失真信号映射到频域。你现在有两个选择。重新采样您的信号,即对其进行均匀采样并使用现成的 FFT 或采用非均匀 FFT 来获得您的频谱。这是一个可以用来计算non-uniform FFT 的库。

【讨论】:

我不认为这是问题的根源。是的,肯定存在某种失真,但视觉上您可以看到输入信号在预期频率上仍然包含大量能量。 FFT 输出在该频率处应该有一个非常明显的峰值。我怀疑一些更基本的问题,并且 FFT 输入和/或输出不是 OP 认为的那样。

以上是关于来自近乎完美的正弦曲线的奇怪 FFT 频谱的主要内容,如果未能解决你的问题,请参考以下文章

matlab 作出信号频谱图

STM32实现FFT,求取幅度频谱

STM32实现FFT,求取幅度频谱

使用 FFT 进行频谱分析

FFT 频谱中的毛刺

如何用 FFT 进行频谱分析? [关闭]