Python 基于FIR实现Hilbert滤波器求信号包络详解


Posted in Python onFebruary 26, 2020

在通信领域,可以通过希尔伯特变换求解解析信号,进而求解窄带信号的包络。

实现希尔伯特变换有两种方法,一种是对信号做FFT,单后只保留单边频谱,在做IFFT,我们称之为频域方法;另一种是基于FIR根据传递函数设计一个希尔伯特滤波器,我们称之为时域方法。

# -*- 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 = '..\\..\\数据集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: 希尔伯特滤波器阶数
  :param pic: 是否绘图,bool
  :return: 包络信号
  '''
  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库函数实现希尔伯特变换
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滤波器的频率响应

Python 基于FIR实现Hilbert滤波器求信号包络详解

使用音频信号对两种方法进行比较

由于音频信号时间较长,采样率较高,因此离散信号序列很长。使用频域方法做FFT和IFFT要耗费比较长的时间;然而使用时域方法只是和滤波器冲击响应做卷积,因此运算速度比较快。结果对比如下:

频域方法结果

Python 基于FIR实现Hilbert滤波器求信号包络详解

时域方法结果

Python 基于FIR实现Hilbert滤波器求信号包络详解

由此看出,时域方法耗费时间要远小于频域方法。

以上这篇Python 基于FIR实现Hilbert滤波器求信号包络详解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python序列操作之进阶篇
Dec 08 Python
Django实现的自定义访问日志模块示例
Jun 23 Python
关于Tensorflow中的tf.train.batch函数的使用
Apr 24 Python
使用pandas将numpy中的数组数据保存到csv文件的方法
Jun 14 Python
Python 实现「食行生鲜」签到领积分功能
Sep 26 Python
Python从数据库读取大量数据批量写入文件的方法
Dec 10 Python
Python 利用高德地图api实现经纬度与地址的批量转换
Aug 14 Python
如何理解python中数字列表
May 29 Python
Scrapy模拟登录赶集网的实现代码
Jul 07 Python
如何使用 Flask 做一个评论系统
Nov 27 Python
Python基础进阶之海量表情包多线程爬虫功能的实现
Dec 17 Python
关于Python中*args和**kwargs的深入理解
Aug 07 Python
python实现逆滤波与维纳滤波示例
Feb 26 #Python
Python全面分析系统的时域特性和频率域特性
Feb 26 #Python
解决pycharm每次打开项目都需要配置解释器和安装库问题
Feb 26 #Python
Python中os模块功能与用法详解
Feb 26 #Python
Python中sys模块功能与用法实例详解
Feb 26 #Python
Python线程threading模块用法详解
Feb 26 #Python
Python图像处理库PIL中图像格式转换的实现
Feb 26 #Python
You might like
PHP中的日期及时间
2006/11/23 PHP
php 移除数组重复元素的一点说明
2008/11/27 PHP
libmysql.dll与php.ini是否真的要拷贝到c:\windows目录下呢
2010/03/15 PHP
PHP随机数生成代码与使用实例分析
2011/04/08 PHP
php中inlcude()性能对比详解
2012/09/16 PHP
浅析PHP程序设计中的MVC编程思想
2014/07/28 PHP
php编程中echo用逗号和用点号连接的区别
2016/03/26 PHP
详解php curl带有csrf-token验证模拟提交方法
2018/04/18 PHP
浅谈laravel aliases别名的原理
2019/10/24 PHP
Laravel等框架模型关联的可用性浅析
2019/12/15 PHP
JQuery魔力之$("tagName")与selector
2012/03/05 Javascript
JavaScript中的类数组对象介绍
2014/12/30 Javascript
javascript中replace( )方法的使用
2015/04/24 Javascript
理解JS事件循环
2016/01/07 Javascript
JavaScript中循环遍历Array与Map的方法小结
2016/03/12 Javascript
javascript中href和replace的比较(详解)
2016/11/25 Javascript
javascript 中的继承实例详解
2017/05/05 Javascript
详解如何使用Node.js编写命令工具——以vue-cli为例
2017/06/29 Javascript
JavaScript实现的搜索及高亮显示功能示例
2017/08/14 Javascript
使用json-server简单完成CRUD模拟后台数据的方法
2018/07/12 Javascript
Vue中的情侣属性$dispatch和$broadcast详解
2019/03/07 Javascript
localstorage实现带过期时间的缓存功能
2019/06/28 Javascript
Python中实现结构相似的函数调用方法
2015/03/10 Python
python简单实现旋转图片的方法
2015/05/30 Python
python检查序列seq是否含有aset中项的方法
2015/06/30 Python
python 爬虫出现403禁止访问错误详解
2017/03/11 Python
50行Python代码获取高考志愿信息的实现方法
2019/07/23 Python
Python hashlib和hmac模块使用方法解析
2020/12/08 Python
HTML5 3D衣服摇摆动画特效
2016/03/17 HTML / CSS
S’well Bottle保温杯官网:绝缘不锈钢水瓶
2018/05/09 全球购物
澳大利亚家庭花园和DIY工具网店:VidaXL
2019/05/03 全球购物
施惠特软件测试面试题以及笔试题
2015/05/13 面试题
你经历的项目中的SCM配置项主要有哪些?什么是配置项?
2013/11/04 面试题
搞笑获奖感言
2014/01/30 职场文书
学校党的群众路线教育实践活动整改措施
2014/10/25 职场文书
JS轻量级函数式编程实现XDM三
2022/06/16 Javascript