Python 基于FIR实现Hilbert滤波器求信号包络详解
在通信领域,可以通过希尔伯特变换求解解析信号,进而求解窄带信号的包络。
实现希尔伯特变换有两种方法,一种是对信号做FFT,单后只保留单边频谱,在做IFFT,我们称之为频域方法;另一种是基于FIR根据传递函数设计一个希尔伯特滤波器,我们称之为时域方法。
#-*-coding:utf8-*- #@TIME:2019/4/1118:30 #@Author:SuHao #@File:hilberfilter.py importscipy.signalassignal importnumpyasnp importlibrosaaslib importmatplotlib.pyplotasplt importtime #frompreprocess_filterimport* #读取音频文件 ex='..\\..\\数据集2\\pre2012\\bflute\\BassFlute.ff.C5B5.aiff' time_series,fs=lib.load(ex,sr=None,mono=True,res_type='kaiser_best') #生成一个chirp信号 #duration=2.0 #fs=400.0 #samples=int(fs*duration) #t=np.arange(samples)/fs #time_series=signal.chirp(t,20.0,t[-1],100.0) #time_series*=(1.0+0.5*np.sin(2.0*np.pi*3.0*t)) defhilbert_filter(x,fs,order=201,pic=None): ''' :paramx:输入信号 :paramfs:信号采样频率 :paramorder:希尔伯特滤波器阶数 :parampic:是否绘图,bool :return:包络信号 ''' co=[2*np.sin(np.pi*n/2)**2/np.pi/nforninrange(1,order+1)] co1=[2*np.sin(np.pi*n/2)**2/np.pi/nforninrange(-order,0)] co=co1+[0]+co #out=signal.filtfilt(b=co,a=1,x=x,padlen=int((order-1)/2)) out=signal.convolve(x,co,mode='same',method='direct') envolope=np.sqrt(out**2+x**2) ifpicisnotNone: w,h=signal.freqz(b=co,a=1,worN=2048,whole=False,plot=None,fs=2*np.pi) fig,ax1=plt.subplots() ax1.set_title('hilbertfilterfrequencyresponse') ax1.plot(w,20*np.log10(abs(h)),'b') ax1.set_ylabel('Amplitude[dB]',color='b') ax1.set_xlabel('Frequency[rad/sample]') ax2=ax1.twinx() angles=np.unwrap(np.angle(h)) ax2.plot(w,angles,'g') ax2.set_ylabel('Angle(radians)',color='g') ax2.grid() ax2.axis('tight') #plt.savefig(pic+'hilbert_filter.jpg') plt.show() #plt.clf() #plt.close() returnenvolope start=time.time() env0=hilbert_filter(time_series,fs,81,pic=True) end=time.time() a=end-start print(a) plt.figure() ax1=plt.subplot(211) plt.plot(time_series) ax2=plt.subplot(212) plt.plot(env0) plt.xlabel('time') plt.ylabel('mag') plt.title('envolopeofmusicbyFIR\ntime:%.3f'%a) plt.tight_layout() start=time.time() #使用scipy库函数实现希尔伯特变换 env=np.abs(signal.hilbert(time_series)) end=time.time() a=end-start print(a) plt.figure() ax1=plt.subplot(211) plt.plot(time_series) ax2=plt.subplot(212) plt.plot(env) plt.xlabel('time') plt.ylabel('mag') plt.title('envolopeofmusicbyscipy\ntime:%.3f'%a) plt.tight_layout() plt.show()
使用chirp信号对两种方法进行比较
FIR滤波器的频率响应
使用音频信号对两种方法进行比较
由于音频信号时间较长,采样率较高,因此离散信号序列很长。使用频域方法做FFT和IFFT要耗费比较长的时间;然而使用时域方法只是和滤波器冲击响应做卷积,因此运算速度比较快。结果对比如下:
频域方法结果
时域方法结果
由此看出,时域方法耗费时间要远小于频域方法。
以上这篇Python基于FIR实现Hilbert滤波器求信号包络详解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。