基于python的快速傅里叶变换FFT(一)
2018-03-31 16:20
267 查看
基于python的快速傅里叶变换FFT(一)
FFT可以将一个信号变换到频域。有些信号在时域上是很难看出什么特征的,但是如果变换到频域之后,就很容易看出特征了。这就是很多信号分析采用FFT变换的原因。另外,FFT可以将一个信号的频谱提取出来,这在频谱分析方面也是经常用的。知识点
1、FFT——离散傅里叶变换(DFT)的快速算法。它是根据离散傅氏变换的奇、偶、虚、实等特性,对离散傅立叶变换的算法进行改进获得的。2、假设采样频率为Fs,信号频率F,采样点数为N。那么FFT之后结果就是一个为N点的复数。每一个点就对应着一个频率点。这个点的模值,就是该频率值下的幅度特性。
3、假设采样频率为Fs,采样点数为N,做FFT之后,某一点n(n从1开始)表示的频率为:Fn=(n-1)*Fs/N;该点的模值除以N/2就是对应该频率下的信号的幅度(对于直流信号是除以N);该点的相位即是对应该频率下的信号的相位。相位的计算可用函数atan2(b,a)计算。atan2(b,a)是求坐标为(a,b)点的角度值,范围从-pi到pi。要精确到xHz,则需要采样长度为1/x秒的信号,并做FFT。要提高频率分辨率,就需要增加采样点数,这在一些实际的应用中是不现实的,需要在较短的时间内完成分析。解决这个问题的方法有频率细分法,比较简单的方法是采样比较短时间的信号,然后在后面补充一定数量的0,使其长度达到需要的点数,再做FFT,这在一定程度上能够提高频率分辨力。
4、由于FFT结果的对称性,通常我们只使用前半部分的结果,即小于采样频率一半的结果。
代码实现
准备工作:安装matplotlib包,打开命令窗口,进入安装python下的scripts路径,输入pip install matplotlib。安装成功后会显示如下图:其他包的安装步骤类似。
import numpy as np from scipy.fftpack import fft,ifft import matplotlib.pyplot as plt import seaborn #采样点选择1400个,因为设置的信号频率分量最高为600Hz,根据采样定理知采样频率要大于信号频率2倍,所以这里设置采样频率为1400Hz(即一秒内有1400个采样点) x=np.linspace(0,1,1400) #设置需要采样的信号,频率分量有180,390和600 y=7*np.sin(2*np.pi*180*x) + 1.5*np.sin(2*np.pi*390*x)+5.1*np.sin(2*np.pi*600*x) yy=fft(y) #快速傅里叶变换 yreal = yy.real # 获取实数部分 yimag = yy.imag # 获取虚数部分 yf=abs(fft(y)) # 取模 yf1=abs(fft(y))/((len(x)/2)) #归一化处理 yf2 = yf1[range(int(len(x)/2))] #由于对称性,只取一半区间 xf = np.arange(len(y)) # 频率 xf1 = xf xf2 = xf[range(int(len(x)/2))] #取一半区间 #原始波形 plt.subplot(221) plt.plot(x[0:50],y[0:50]) plt.title('Original wave') #混合波的FFT(双边频率范围) plt.subplot(222) plt.plot(xf,yf,'r') #显示原始信号的FFT模值 plt.title('FFT of Mixed wave(two sides frequency range)',fontsize=7,color='#7A378B') #注意这里的颜色可以查询颜色代码表 #混合波的FFT(归一化) plt.subplot(223) plt.plot(xf1,yf1,'g') plt.title('FFT of Mixed wave(normalization)',fontsize=9,color='r') plt.subplot(224) plt.plot(xf2,yf2,'b') plt.title('FFT of Mixed wave)',fontsize=10,color='#F08080') plt.show()
实现结果
结果验证
假设我们有一个信号,它含有一个频率为180Hz,幅度为7V的交流信号;一个频率为390Hz,幅度为1.5V的交流信号;一个频率为600Hz,幅度为5.1V的交流信号。用数学表达式就是如下:y=7*np.sin(2*np.pi*180*x) + 1.5*np.sin(2*np.pi*390*x)+5.1*np.sin(2*np.pi*600*x)
从图中我们可以看到,在第181点、第391点、和第601点附近有比较大的值。分别计算这三个点的模值,结果如下:
181点: 4900
391点:1030
601点:2600
按照公式,可以计算出180Hz信号的幅度为:4900/(N/2)=384/(1400/2)=7;390Hz信号的幅度为:1030/(N/2)=1030/(1400/2)=1.5。可见,从频谱分析出来的幅度是正确的。
注:600Hz信号的幅度异常,具体原因为检查出来,后期更新。
相关文章推荐
- 基于python的快速傅里叶变换FFT(二)
- Python图像处理库PIL中快速傅里叶变换FFT的实现(一)
- Python图像处理库PIL中快速傅里叶变换FFT的实现(一)
- Python实现快速傅里叶变换(FFT)
- Python中二维快速傅里叶变换----基于numpy库
- 基于SU的快速傅里叶变换(FFT)
- Python + OpenCV实现基于傅里叶变换(FFT)的旋转文本校正(文字方向检测)
- Python实现快速傅里叶变换的方法(FFT)
- 基于Python的接口自动化测试框架
- 运维自动化之基于python语言的文字界面的运维管理软件
- 超实用python小项目--基于python的手机通讯录二维码生成网站--1、项目介绍和开发环境
- 基于Python的TCP阻塞式echo服务器
- 基于ORB特征提取算法图像匹配 python实现
- 基于Python使用Redis的一些想法和建议
- HDU_1402_A * B Problem Plus(FFT快速傅里叶变换)
- 基于七牛Python SDK写的一个同步脚本
- 快速傅里叶变换(FFT)的C#实现及详细注释
- 基于python3实现socket文件传输和校验
- Python基于Tkinter的HelloWorld入门实例
- HDU 1402及51 nod1028 大数乘法 V2(FFT 快速傅里叶变换)