美文网首页
傅里叶变换

傅里叶变换

作者: dingtom | 来源:发表于2020-04-06 19:32 被阅读0次

    采样定理:所谓采样定理 ,又称香农采样定理,奈奎斯特采样定理,是信息论,特别是通讯与信号处理学科中的一个重要基本结论。采样定理指出,如果信号是带限的,并且采样频率高于信号带宽的两倍,那么,原来的连续信号可以从采样样本中完全重建出来。

    离散傅里叶变换(DFT)

    离散傅里叶变换(discrete Fourier transform) 傅里叶分析方法是信号分析的最基本方法,傅里叶变换是傅里叶分析的核心,通过它把信号从时间域变换到频率域,进而研究信号的频谱结构和变化规律。但是它的致命缺点是:计算量太大,时间复杂度太高,当采样点数太高的时候,计算缓慢,由此出现了DFT的快速实现,即下面的快速傅里叶变换FFT。

    快速傅里叶变换(FFT)

    import numpy as np
    from scipy.fftpack import fft,ifft
    import matplotlib.pyplot as plt
    from matplotlib.pylab import mpl
     
    mpl.rcParams['font.sans-serif'] = ['SimHei']   #显示中文
    mpl.rcParams['axes.unicode_minus']=False       #显示负号
     
     
    #采样点选择1400个,因为设置的信号频率分量最高为600赫兹,根据采样定理知采样频率要大于信号频率2倍,所以这里设置采样频率为1400赫兹(即一秒内有1400个采样点,一样意思的)
    x=np.linspace(0,1,1400)      
     
    #设置需要采样的信号,频率分量有200,400和600
    y=7*np.sin(2*np.pi*200*x) + 5*np.sin(2*np.pi*400*x)+3*np.sin(2*np.pi*600*x)
    
    plt.figure()
    plt.plot(x[0:50],y[0:50])   
    plt.title('原始部分波形(前50组样本)')
    plt.show()
    

    这里原始信号的三个正弦波的频率分别为,200Hz、400Hz、600Hz,最大频率为600赫兹。根据采样定理,fs至少是600赫兹的2倍,这里选择1400赫兹,即在一秒内选择1400个点。

    fft_y=fft(y)                          #快速傅里叶变换
    print(len(fft_y))
    print(fft_y[0:5])
    

    1400
    [-4.18864943e-12+0.j 9.66210986e-05-0.04305756j 3.86508070e-04-0.08611996j
    8.69732036e-04-0.12919206j 1.54641157e-03-0.17227871j]

    换之后的结果数据长度和原始采样信号是一样的

    每一个变换之后的值是一个复数,为a+bj的形式下标为0和 N /2的两个复数的虚数部分为0,下标为i和 N - i 的两个复数共辄,也就是其虚部数值相同、符号相反。再用ifft()从频域转回时域之后,出现了由误差引起的很小的虚部,用np.real()取其实部即可.
     由于一半是另一半的共轭,因此只需要关心一半数据.fft转换后下标为0的实数表示时域信号中的直流成分(不随时间变化)

    N=1400
    x = np.arange(N)           # 频率个数
     
    abs_y=np.abs(fft_y)                # 取复数的绝对值,即复数的模(双边频谱)
    angle_y=np.angle(fft_y)              #取复数的角度
     
    plt.figure()
    plt.plot(x,abs_y)   
    plt.title('双边振幅谱(未归一化)')
     
    plt.figure()
    plt.plot(x,angle_y)   
    plt.title('双边相位谱(未归一化)')
    plt.show()
    

    振幅谱的纵坐标很大,而且具有对称性
    Y=A1+A2cos(2πω2+φ2)+A3cos(2πω3+φ3)+A4*cos(2πω4+φ4)

    经过FFT之后,得到的“振幅图”中,
    第一个峰值(频率位置)的模是A1的N倍,N为采样点,本例中为N=1400,此例中没有,因为信号没有常数项A1
    第二个峰值(频率位置)的模是A2的N/2倍,N为采样点,
    第三个峰值(频率位置)的模是A3的N/2倍,N为采样点,
    第四个峰值(频率位置)的模是A4的N/2倍,N为采样点,

    # 将振幅谱进行归一化和取半处理
    normalization_y=abs_y/N            #归一化处理(双边频谱)
    plt.figure()
    plt.plot(x,normalization_y,'g')
    plt.title('双边频谱(归一化)',fontsize=9,color='green')
    plt.show()
    half_x = x[range(int(N/2))]                                  #取一半区间
    normalization_half_y = normalization_y[range(int(N/2))]      #由于对称性,只取一半区间(单边频谱)
    plt.figure()
    plt.plot(half_x,normalization_half_y,'b')
    plt.title('单边频谱(归一化)',fontsize=9,color='blue')
    plt.show()
    

    STFT(短时傅里叶变换)

    STFT短时傅里叶变换,实际上是对一系列加窗数据做FFT。有的地方也会提到DCT(离散傅里叶变换),而DCT跟FFT的关系就是:FFT是实现DCT的一种快速算法。

    FFT有个参数N,表示对多少个点做FFT,如果一帧里面的点的个数小于N就会zero-padding到N的长度。每个点对应一个频率点,某一点n(n从1开始)表示的频率为:
    F_n=(n−1)∗Fs/N
    第一个点(n=1,Fn等于0)表示直流信号,最后一个点N的下一个点(实际上这个点是不存在的)表示采样频率Fs。

    FFT后我们可以得到N个频点,比如,采样频率为16000,N为1600,那么FFT后就会得到1600个点,FFT得到的1600个值的模可以表示1600个频点对应的振幅。因为FFT具有对称性,当N为偶数时取N/2+1个点,当N为奇数时,取(N+1)/2个点,比如N为512时最后会得到257个值。
    scipy.signal.stft(x,fs = 1.0,window =‘hann’,nperseg = 256,noverlap = None,nfft = None,detrend = False,return_oneside = True,boundary =‘zeros’,padded = True,axis = -1 )

    • x: STFT变换的时域信号
    • fs: 时域信号的采样频率
    • window: 时域信号分割需要的窗函数,可以自定义窗函数,常见的窗函数有boxcar、triang、blackman、hamming等
    • nperseg: 窗函数长度
    • noverlap: 窗函数重叠数,默认为50%。
    • nfft: FFT的长度,默认为nperseg。如大于nperseg会自动进行零填充
    • return_oneside : True返回复数实部,None返回复数。
    f, t, Zxx = scipy.signal.stft(x,fs=1.0,window='hann',
            nperseg=256,noverlap=None,nfft=None,
            detrend=False,return_onesid =True, 
            boundary='zeros',padded=True,axis=-1 )
    
    • f: 频率
    • t: 时间
    • Zxx: STFT时频数据

    相关文章

      网友评论

          本文标题:傅里叶变换

          本文链接:https://www.haomeiwen.com/subject/fycbphtx.html