赞
踩
Fourier变换就是将周期信号沿正交基分解,而一组良好的正交基就是正弦/余弦函数,完备的正交基为 e j 2 π n t T 或 e j 2 π n f 0 t \displaystyle e^{j\frac {2 \pi n t}{T}} 或 e^{j2 \pi n f_0t} ejT2πnt或ej2πnf0t , 正交容易证明,完备性证明复杂。
基于此,连续域上的Fourier变换可以写为
F ( ω ) = ∫ − ∞ + ∞ f ( t ) e − j ω t d t \displaystyle F(\omega) = \int_{-\infin}^{+\infin} f(t) e^{-j\omega t} {\rm d}t F(ω)=∫−∞+∞f(t)e−jωtdt
其逆变换为
f ( t ) = 1 2 π ∫ − ∞ + ∞ F ( ω ) e − j ω t d w \displaystyle f(t) = \frac 1 {2\pi} \int_{-\infin}^{+\infin} F(\omega) e^{-j\omega t}{\rm d}w f(t)=2π1∫−∞+∞F(ω)e−jωtdw
在上述工作基础之上发展了离散Fourier变换(DFT),将其变换对写为
F ( k ) = ∑ n = 0 N − 1 f ( n ) e − j 2 π N k n F(k) = \sum_{n=0}^{N-1} f(n) e^{-j \frac{2\pi }{N} k n} F(k)=∑n=0N−1f(n)e−jN2πkn
f ( n ) = 1 N ∑ n = 0 N − 1 F ( k ) e j 2 π N k n \displaystyle f(n) = \frac 1 {N} \sum_{n=0}^{N-1} F(k)e^{j \frac{2\pi }{N} k n} f(n)=N1n=0∑N−1F(k)ejN2πkn
假设 采样频率Fs,信号频率F,信号长度L,采样点数N。那么FFT之后结果就是N个点的复数。每一个点就对应着一个频率点。这个点的模值,就是该频率值下的幅度特性。
采样频率Fs,被N-1个点平均分成N等份,每个点的频率依次增加。为了方便进行FFT运算,通常N取大于信号长度L的2的整数次方。用matlab 的 nextpower2 函数实现。
例如某点n所表示的频率为:Fn=(n-1)*Fs/N。由上面的公式可以看出,Fn所能分辨的最小频率为Fs/N。如果采样频率Fs为1024Hz,采样点数为1024点,则可以分辨到1Hz。 1024Hz的采样率采样1024点,刚好是1秒,也就是说,采样1秒时间的信号并做FFT,则结果可以分析到1Hz。如果采样2秒时间的信号,则N为2048,并做FFT,则结果可以分析到0.5Hz。 如果要提高频率分辨力,则必须增加采样点数,也即采样时间。频率分辨率和采样时间是倒数关系。 引用自cnblogs
假设FFT之后某点n用复数a+bi表示,该复数的模就是
A
n
=
a
2
+
b
2
A_n=\sqrt{a^2+b^2}
An=a2+b2
,相位就是
P
n
=
a
r
c
t
a
n
b
a
P_n=arctan \displaystyle\frac{b}{a}
Pn=arctanab 。根据以上的结果,就可以计算出n点(n≠1,且n<=N/2)对应的信号的表达式为:
A n N / 2 c o s ( 2 π F n t + P n ) \displaystyle \frac{A_n}{N/2}cos(2\pi F_nt+P_n) N/2Ancos(2πFnt+Pn), 即 2 A n N c o s ( 2 π F n t + P n ) \displaystyle \frac{2A_n}{N}cos(2\pi F_nt+P_n) N2Ancos(2πFnt+Pn)
# 基频是 1/(2pi)Hz, 最大是 3/(2pi) Hz, ω分别是1,2,3
t = np.linspace(0,2*np.pi,240)
y = 1+ 1*np.sin(t ) + 2*np.sin(2*t)+3*np.sin(3*t)
plt.figure()
plt.plot(t,y)
plt.title('原始波形')
输出为:
# 采样点数 N = len(t) # 采样频率 fs = N/(2*np.pi) N,fs # FFT得到的复数的模(即绝对值)就是对应的“振幅谱”,复数所对应的角度,就是所对应的“相位谱” fft_y=fft(y) #快速傅里叶变换 ## 构造一个dataFrame df_fft=pd.DataFrame(data=fft_y) df_fft.columns=['变换值'] df_fft['幅值']=df_fft['变换值'].abs() df_fft['幅值归一化']=df_fft['幅值']/N*2 df_fft.loc[0,'幅值归一化']=df_fft['幅值归一化'][0]/2 df_fft['辐角']=angle_y=np.angle(fft_y) # 开始遗漏了这一关键项 df_fft['频率']=np.arange(N)/(2*np.pi) pd.options.display.float_format = '{:.2f}'.format df_fft.head()
输出为
变换值 幅值 幅值归一化 辐角 频率
0 240.00-0.00j 240.00 1.00 -0.00 0.00
1 1.60-122.18j 122.19 1.02 -1.56 0.16
2 6.34-242.28j 242.36 2.02 -1.54 0.32
3 13.99-356.08j 356.35 2.97 -1.53 0.48
4 -0.36+6.82j 6.83 0.06 1.62 0.64
做幅值图、归一化幅值图与相位图
fig,axs = plt.subplots(1,3,figsize=(8,2),dpi=100)
x=np.arange(N)
axs[0].plot(x,df_fft['幅值'])
axs[0].set_title('幅值-双边')
axs[1].plot(x,df_fft['辐角'])
axs[1].set_title('双边相位谱')
axs[2].plot(x,df_fft['幅值归一化'])
axs[2].set_title('双边幅值归一化')
plt.show()
# 取半处理 df_fft_harlf = df_fft.loc[np.arange(int(N/2)),:] # half_x = x[range(int(N/2))] #取一半区间 # normalization_half_y = df_fft['幅值归一化'][np.arange(int(N/2))] #由于对称性,只取一半区间(单边频谱) fig,axs = plt.subplots(1,2,figsize=(8,2),dpi=150) axs[0].stem(df_fft_harlf.index,df_fft_harlf['幅值归一化'],'b') axs[0].set_xlim(0,9) axs[0].set_title('单边频谱(归一化)',fontsize=9,color='blue') plt.gca().set_xlim(0,10) axs[1].stem(df_fft_harlf.index,df_fft_harlf['辐角'],'b') axs[1].set_xlim(0,10) axs[1].set_title('相位',fontsize=9,color='blue') plt.show()
df_fft_harlf[df_fft_harlf['幅值归一化']>0.5]
输出为
变换值 幅值 幅值归一化 辐角 频率
0 240.00-0.00j 240.00 1.00 -0.00 0.00
1 1.60-122.18j 122.19 1.02 -1.56 0.16
2 6.34-242.28j 242.36 2.02 -1.54 0.32
3 13.99-356.08j 356.35 2.97 -1.53 0.48
把辐角换算为角度看一看。
df_fft_harlf[df_fft_harlf['幅值归一化']>0.5]['辐角']/np.pi*180
0 -0.00
1 -89.25
2 -88.50
3 -87.75
Name: 辐角, dtype: float64
重新加和,看是否与原函数相符
yy =1+ 1.018237*np.cos(t-1.557706)+ 2.019664* np.cos(2*t-1.544616)+ 2.969593*np.cos(3*t-1.531526)
plt.plot(t,y,'r',t,yy,'b')
可见基本与原函数相同,同时scipy默认的fft是分解为余弦波。
可见逆变换需要用处理前变换的数据。
plt.plot(t,y,'r',label='原始')
plt.plot(t,np.real(ifft(fft_y)),'b',label='逆变换')
plt.legend();
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。