FFT实部/虚部/绝对值的含义解释

22

我目前正在学习离散傅里叶变换,并使用numpy进行实验以更好地理解它。

我尝试绘制了一个“sin x sin x sin”信号,并获得了一个只有4个非零点的干净FFT。我天真地告诉自己:“好吧,如果我用这些振幅和频率绘制一个“sin + sin + sin + sin”的信号,我应该得到相同的“sin x sin x sin”信号,对吧?”

好吧...不完全是这样

(第一个是“x”信号,第二个是“+”信号)

enter image description here

两者具有相同的振幅/频率,但不是相同的信号,即使我可以看到它们有一些相似之处。

好的,既然我只绘制了FFT的绝对值,我想我失去了一些信息。

然后我为两个信号绘制了实部、虚部和绝对值:

enter image description here

现在,我很困惑。我该怎么办?我从数学角度阅读了关于DFT的文章。我理解复数值来自于单位圆。我甚至不得不学习希尔伯特空间来理解它的工作原理(而且这很痛苦!...我只是浅尝辄止)。我只希望了解这些实部/虚部图是否在数学世界之外具有任何具体意义:

  • abs(fft):频率+振幅
  • real(fft):?
  • imaginary(fft):?

代码:

import numpy as np
import matplotlib.pyplot as plt
N = 512 # Sample count
fs = 128 # Sampling rate
st = 1.0 / fs # Sample time
t = np.arange(N) * st # Time vector

signal1 = \
1   *np.cos(2*np.pi * t) *\
2   *np.cos(2*np.pi * 4*t) *\
0.5 *np.cos(2*np.pi * 0.5*t)

signal2 = \
0.25*np.sin(2*np.pi * 2.5*t) +\
0.25*np.sin(2*np.pi * 3.5*t) +\
0.25*np.sin(2*np.pi * 4.5*t) +\
0.25*np.sin(2*np.pi * 5.5*t)



_, axes = plt.subplots(4, 2)

# Plot signal
axes[0][0].set_title("Signal 1 (multiply)")
axes[0][0].grid()
axes[0][0].plot(t, signal1, 'b-')

axes[0][1].set_title("Signal 2 (add)")
axes[0][1].grid()
axes[0][1].plot(t, signal2, 'r-')

# FFT + bins + normalization
bins = np.fft.fftfreq(N, st)    
fft  = [i / (N/2) for i in np.fft.fft(signal1)]
fft2 = [i / (N/2) for i in np.fft.fft(signal2)]

# Plot real
axes[1][0].set_title("FFT 1 (real)")
axes[1][0].grid()
axes[1][0].plot(bins[:N/2], np.real(fft[:N/2]), 'b-')

axes[1][1].set_title("FFT 2 (real)")
axes[1][1].grid()
axes[1][1].plot(bins[:N/2], np.real(fft2[:N/2]), 'r-')

# Plot imaginary
axes[2][0].set_title("FFT 1 (imaginary)")
axes[2][0].grid()
axes[2][0].plot(bins[:N/2], np.imag(fft[:N/2]), 'b-')

axes[2][1].set_title("FFT 2 (imaginary)")
axes[2][1].grid()
axes[2][1].plot(bins[:N/2], np.imag(fft2[:N/2]), 'r-')

# Plot abs
axes[3][0].set_title("FFT 1 (abs)")
axes[3][0].grid()
axes[3][0].plot(bins[:N/2], np.abs(fft[:N/2]), 'b-')

axes[3][1].set_title("FFT 2 (abs)")
axes[3][1].grid()
axes[3][1].plot(bins[:N/2], np.abs(fft2[:N/2]), 'r-')

plt.show()
4个回答

46

对于每个频率区间,幅度 sqrt(re^2 + im^2) 表示相应频率的分量的振幅。而相位 atan2(im, re) 则表示该分量的相对相位。单独看实部和虚部并不特别有用,除非你关心数据窗口中心的对称性质(偶对奇)。


1
感谢你和 hotpaw2。我现在觉得我理解得更好了。我甚至不知道 atan2 的存在! - Cyrille
问题?: 1)我假设复数的实部平方是正的,对吗? 2)当复数被平方时,虚部的符号是什么?它是否为负,因为sqrt(-1)**2为-1? - ox.
3
不,将复数看作“实部+虚部j”的形式。因此,实部和虚部都是实数,而且实部的平方和虚部的平方都是正数。 - Paul R

17

关于某个参考点,比如一个固定时间窗口的中心,相同频率的正弦波和余弦波会看起来不同(相对于任何固定时间参考点有不同的起始相位)。它们在任何整数周期宽度上也是数学上正交的,因此可以表示出一种独立的基向量变换。

FFT结果的实部是每个频率分量与余弦波的相似程度,虚部是每个分量与正弦波的相似程度。通过各种正弦和余弦分量的比率,可以构造任意或所需相位的正弦波,从而使FFT结果完整。

仅靠幅度无法区分正弦波和余弦波。IFFT(imag(FFT))会破坏信号重建,如果信号具有与纯余弦波不同的相位。因为IFFT(re(FFT))也会破坏信号重建,如果信号具有与FFT光圈窗口不同的纯正弦波。


2
您可以将由三个cos函数乘积组成的信号1转换为由四个cos函数之和组成的信号。这与由四个正弦函数之和组成的函数2有所不同。
cos函数是一个偶函数,cos(-x)== cos(x)。偶函数的傅里叶变换是纯实数。这就是为什么函数1的fft的虚部图仅包含接近零的值(1e-15)的原因。
sine函数是一个奇函数sin(-x)== -sin(x)。奇函数的傅里叶变换是纯虚数。这就是为什么函数2的fft的实部图仅包含接近零的值(1e-15)的原因。
如果您想更详细地了解FFT和DFT,请阅读电气工程信号分析教科书。

1
你说得对,我没有提交好的例子(sin/cos)。嗯,我确实阅读了各种教科书、网站、观看了视频和一个DSP mooc,但它们大多包含一些令人望而生畏(至少对我来说)的数学概念和公式,并需要进行额外的调查,就像这个问题一样。我开始理解它们,但我还有很长的路要走。感谢之前的回答,现在我可以通过添加具有相应幅度和相位的余弦子信号(因为原始信号是实数)来手动重构任何信号。相位公式是我缺失的关键。这就是为什么我接受了Paul R的答案。 - Cyrille

0

虽然...现在你一定是一个很好的专家了 :) 对于其他人:请注意 使用这组正确的数学方程式 因此将总和更正为:

    signal1 = \
1   *np.cos(2*np.pi * t) *\
2   *np.cos(2*np.pi * 4*t) *\
0.5 *np.cos(2*np.pi * 0.5*t)

signal2 = \
0.25*np.cos(-2*np.pi * 2.5*t) +\
0.25*np.cos(2*np.pi * 3.5*t) +\
0.25*np.cos(-2*np.pi * 4.5*t) +\
0.25*np.cos(2*np.pi * 5.5*t)

现在的结果如下:

(现在的结果是)

因此,关键是实部也应该相同。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接