[英]Plotting and extracting fft phase
這是一個將 fft 相位繪圖與 2 種不同方法進行比較的代碼:
import numpy as np
import matplotlib.pyplot as plt
import scipy.fftpack
phase = np.pi / 4
f = 1
fs = f*20
dur=10
t = np.linspace(0, dur, num=fs*dur, endpoint=False)
y = np.cos(2 * np.pi * t + phase)
Y = scipy.fftpack.fftshift(scipy.fftpack.fft(y))
f = scipy.fftpack.fftshift(scipy.fftpack.fftfreq(len(t)))
p = np.angle(Y)
p[np.abs(Y) < 1] = 0
fig, ax = plt.subplots(2, 1)
ax[0].plot(t, y)
ax[1].plot(f*fs, p, label='from fft')
ax[1].phase_spectrum(y, fs, window=None, label='from phase_spectrum')
plt.legend()
plt.show()
結果如下:
這是當周期的信號數不是整數時的結果:
我有幾個問題:
在回答之前,只是一個小說明:
刪除p[np.abs(Y) < 1] = 0
行。 您的大部分頻譜的幅度都低於 1,這就是為什么使用這條線,您的頻譜看起來最像一條位於 0 處的平線。
現在回答:
phase_spectrum
做了三件與你不同的事情:
np.unwrap(np.angle(Y))
。angle_spectrum
。sides='twosided'
版本, phase_spectrum
sides='twosided'
phase_spectrum
sides='twosided'
傳遞給phase_spectrum
調用。 現在,關於以頻率f
獲取相位:
為此,您必須使用相位而不展開.
如果您沒有整數個周期,您就不能直接提取單音信號的相位,這是對的。 那是因為信號的頻率並不完全落在 FFT 中任何頻率倉的頂部。 不過,您可以獲得最近 bin 相位的近似值。 您還可以對頻譜進行正弦插值,以在您想要的頻率下獲得其值。
如果您只關心單個頻率f
的相位,那么您根本不應該使用 FFT。 FFT 計算所有頻率的相位和幅度。 如果您只關心單個頻率,只需執行Y_at_f = y @ np.exp(2j * np.pi * f * t)
並通過np.angle(Y_at_f)
獲得該相位。
您可以通過在 FFT 之前執行 fftshift(圓形旋轉 N/2)來提取參考數據窗口中心的相位。 這是因為,在 fftshift 之后,atan2() 始終與圍繞其中心的數據的奇數與偶數之比有關(分解為奇函數加偶函數)。
因此,在生成過程中計算窗口中間信號的相位,並使用它而不是開始時的相位。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.