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备份文件以及mysql数据库的脚本代码
Jun 10 Python
教大家玩转Python字符串处理的七种技巧
Mar 31 Python
python itchat实现微信自动回复的示例代码
Aug 14 Python
Python中列表与元组的乘法操作示例
Feb 10 Python
Python Xml文件添加字节属性的方法
Mar 31 Python
Python实现获取nginx服务器ip及流量统计信息功能示例
May 18 Python
python的pstuil模块使用方法总结
Jul 26 Python
Django框架视图层URL映射与反向解析实例分析
Jul 29 Python
Python socket实现的文件下载器功能示例
Nov 15 Python
解决python gdal投影坐标系转换的问题
Jan 17 Python
python中openpyxl和xlsxwriter对Excel的操作方法
Mar 01 Python
详细介绍python类及类的用法
May 31 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之PHP语法学习笔记1
2006/12/17 PHP
一些php技巧与注意事项分析
2011/02/03 PHP
解析php dirname()与__FILE__常量的应用
2013/06/24 PHP
PHP中$_SERVER使用说明
2015/07/05 PHP
PHP实现二叉树的深度优先与广度优先遍历方法
2015/09/28 PHP
Laravel 验证码认证学习记录小结
2019/12/20 PHP
CSS中一些@规则的用法小结
2021/03/09 HTML / CSS
Javascript模板技术
2007/04/27 Javascript
javascript 原型模式实现OOP的再研究
2009/04/09 Javascript
Web前端设计模式  制作漂亮的弹出层
2010/10/29 Javascript
获取div编辑框,textarea,input text的光标位置 兼容IE,FF和Chrome的方法介绍
2012/11/08 Javascript
js面向对象编程之如何实现方法重载
2014/07/02 Javascript
jQuery读取XML文件内容的方法
2015/03/09 Javascript
jquery使用each方法遍历json格式数据实例
2015/05/18 Javascript
微信小程序 toast 详解及实例代码
2016/11/09 Javascript
Bootstrap CSS组件之导航(nav)
2016/12/17 Javascript
使用json-server简单完成CRUD模拟后台数据的方法
2018/07/12 Javascript
Bootstrap Table实现定时刷新数据的方法
2018/08/13 Javascript
vue如何进行动画的封装
2018/09/26 Javascript
使用vue-router切换页面时,获取上一页url以及当前页面url的方法
2019/05/06 Javascript
nodejs读取图片返回给浏览器显示
2019/07/25 NodeJs
微信浏览器左上角返回按钮监听的实现
2020/03/04 Javascript
Python的Django框架中的select_related函数对QuerySet 查询的优化
2015/04/01 Python
浅谈用Python实现一个大数据搜索引擎
2017/11/28 Python
python实现ID3决策树算法
2017/12/20 Python
让Django支持Sql Server作后端数据库的方法
2018/05/29 Python
Flask框架Flask-Principal基本用法实例分析
2018/07/23 Python
python 杀死自身进程的实现方法
2019/07/01 Python
NumPy中的维度Axis详解
2019/11/26 Python
Python jieba结巴分词原理及用法解析
2020/11/05 Python
Kendra Scott官网:美国领先的时尚配饰品牌
2020/10/22 全球购物
乡镇八一建军节活动方案
2014/08/24 职场文书
医生党的群众路线教育实践活动个人对照检查材料
2014/09/23 职场文书
大学迎新生欢迎词
2015/09/29 职场文书
纯html+css实现Element loading效果
2021/08/02 HTML / CSS
vue router 动态路由清除方式
2022/05/25 Vue.js