Python 基于FIR實現(xiàn)Hilbert濾波器求信號包絡(luò)詳解
在通信領(lǐng)域,可以通過希爾伯特變換求解解析信號,進而求解窄帶信號的包絡(luò)。
實現(xiàn)希爾伯特變換有兩種方法,一種是對信號做FFT,單后只保留單邊頻譜,在做IFFT,我們稱之為頻域方法;另一種是基于FIR根據(jù)傳遞函數(shù)設(shè)計一個希爾伯特濾波器,我們稱之為時域方法。
# -*- coding:utf8 -*-
# @TIME : 2019/4/11 18:30
# @Author : SuHao
# @File : hilberfilter.py
import scipy.signal as signal
import numpy as np
import librosa as lib
import matplotlib.pyplot as plt
import time
# from preprocess_filter import *
# 讀取音頻文件
ex = '..\\..\\數(shù)據(jù)集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) )
def hilbert_filter(x, fs, order=201, pic=None):
'''
:param x: 輸入信號
:param fs: 信號采樣頻率
:param order: 希爾伯特濾波器階數(shù)
:param pic: 是否繪圖,bool
:return: 包絡(luò)信號
'''
co = [2*np.sin(np.pi*n/2)**2/np.pi/n for n in range(1, order+1)]
co1 = [2*np.sin(np.pi*n/2)**2/np.pi/n for n in range(-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)
if pic is not None:
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('hilbert filter frequency response')
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()
return envolope
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('envolope of music by FIR \n time:%.3f'%a)
plt.tight_layout()
start = time.time()
# 使用scipy庫函數(shù)實現(xiàn)希爾伯特變換
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('envolope of music by scipy \n time:%.3f'%a)
plt.tight_layout()
plt.show()
使用chirp信號對兩種方法進行比較
FIR濾波器的頻率響應(yīng)

使用音頻信號對兩種方法進行比較
由于音頻信號時間較長,采樣率較高,因此離散信號序列很長。使用頻域方法做FFT和IFFT要耗費比較長的時間;然而使用時域方法只是和濾波器沖擊響應(yīng)做卷積,因此運算速度比較快。結(jié)果對比如下:
頻域方法結(jié)果

時域方法結(jié)果

由此看出,時域方法耗費時間要遠小于頻域方法。
以上這篇Python 基于FIR實現(xiàn)Hilbert濾波器求信號包絡(luò)詳解就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
使用Python和大模型進行數(shù)據(jù)分析和文本生成
Python語言以其簡潔和強大的特性,成為了數(shù)據(jù)科學、機器學習和人工智能開發(fā)的首選語言之一,在這篇文章中,我將介紹如何用Python連接和使用大模型,并通過示例展示如何在實際項目中應(yīng)用這些技術(shù),需要的朋友可以參考下2024-05-05
Python實現(xiàn)葵花8號衛(wèi)星數(shù)據(jù)自動下載實例
這篇文章主要為大家介紹了Python實現(xiàn)葵花8號衛(wèi)星數(shù)據(jù)自動下載實例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-10-10
Pycharm打開已有項目配置python環(huán)境的方法
這篇文章主要介紹了Pycharm打開已有項目配置python環(huán)境的方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-07-07

