如何在 Numpy 中恢复傅里叶变换的幅度和相移?

Posted

技术标签:

【中文标题】如何在 Numpy 中恢复傅里叶变换的幅度和相移?【英文标题】:How to recover amplitude, and phase shift from Fourier Transform in Numpy? 【发布时间】:2019-10-20 18:07:08 【问题描述】:

我正在尝试编写一个简单的 python 脚本,从傅立叶变换中恢复正弦波的幅度和相位。

对于给定的频率,我应该能够通过计算由傅里叶变换的实数和虚数定义的向量的大小和方向来做到这一点,即:

Amplitude_at_freq = sqrt(real_component_at_freq^2 + imag_component_at_freq^2)
Phase = arctan(imag_component_at_freq/real_component_at_freq)

参考:1 分 45 秒进入此视频:https://www.youtube.com/watch?time_continue=106&v=IWQfj05i87g

我已经使用 numpy 的 fft 库编写了一个简单的 python 脚本来尝试重现它,但是尽管完全按照上面的方式写出我的推导,但我无法获得幅度和相位,尽管我可以恢复测试的原始频率正弦波正确。上一篇文章Calculating amplitude from np.fft 和这篇文章Why FFT does not retrieve original amplitude when increasing signal length 指出了相同的问题(幅度相差2 倍)。具体来说,解决方案是“乘以 2(去除一半光谱,因此必须保留能量)”,但我需要澄清这意味着什么。其次,没有提到我恢复相位变化的问题,幅度的计算与我在这里的不同。

# Define amplitude, phase, frequency
_A = 4 # Amplitude
_p = 0 # Phase shift
_f = 8 # Frequency

# Construct a simple signal
t = np.linspace(0, 2*np.pi, 1024 + 1)[:-1]
g = _A * np.sin(_f * t + _p) 

# Apply the fourier transform
ff = np.fft.fft(g)

# Get frequency of original signal
ff_ii = np.where(np.abs(ff) > 1.0)[0][0] # Just get one frequency, the other one is just mirrored freq at negative value
print('frequency of:', ff_ii)

# Get the complex vector at that frequency to retrieve amplitude and phase shift
yy = ff[ff_ii] 

# Calculate the amplitude
T = t.shape[0] # domain of x; which we will divide height to get freq amplitude
A = np.sqrt(yy.real**2 + yy.imag**2)/T 
print('amplitude of:', A) 

# Calculate phase shift
phi = np.arctan(yy.imag/yy.real) 
print('phase change:', phi)

但是,我得到的结果是:

>> frequency of: 8
>> amplitude of: 2.0
>> phase change: 1.5707963267948957

所以频率是准确的,但我得到的幅度是 2,应该是 4,相位变化是 pi/2,应该是零。

是我的数学错误,还是我对 numpy 的 fft 实现的理解不正确?

【问题讨论】:

【参考方案1】:

傅立叶将信号分析为exp(i.2.pi.f.t) 项的总和,因此它看到 A.sin(2.pi.f1.t) 为:-i.A/2.exp(i.2.pi.f1.t)+i.A/2.exp(-i.2.pi.f1.t), 这在数学上是相等的。因此,在傅立叶术语中,正频率 f1 和负 -f1 分别具有复值 -A/2.iA/2.i。所以每个“边”只有一半的幅度,但是如果你把它们加在一起(在傅里叶逆变换中)你会得到幅度 A。如果你只看一个,正频率和负频率的这种分裂就是你缺失的因素 2 的地方(正或负)光谱的一面。这通常在实践中完成,因为对于真实信号,另一半很容易推导出给定的信号。

查看精确的数学 Euler's formula 和 Fourier transform。

【讨论】:

感谢 Koen G.,它完美地阐明了这一点。

以上是关于如何在 Numpy 中恢复傅里叶变换的幅度和相移?的主要内容,如果未能解决你的问题,请参考以下文章

仅具有幅度的傅里叶逆变换 - 我也需要相位吗?

在 Python 中绘制快速傅里叶变换

傅里叶级数变换恢复原始信号

OpenCV 完整例程75. Numpy 实现图像傅里叶变换

傅里叶变换2

傅里叶变换 傅里叶逆变换 python