Python中FIR滤波和小波包滤波对比(MNE脑电数据处理)

2023-10-30

小波变换有信号显微镜之称,在EEG分析中也有广泛的应用,印象中小波算法是来源于地球物理解释的。之前有介绍过小波的一些资料和实现:https://blog.csdn.net/zhoudapeng01/article/details/107025901可以参考下,这里主要分析小波和FIR滤波效果的对比。

博客对应的代码和数据

https://download.csdn.net/download/zhoudapeng01/12793085

# 短时傅里叶变换和FIR滤波效果对比

import mne
import matplotlib.pyplot as plt
from scipy import signal, fft
import numpy as np
import pywt
# 设置MNE库打印Log的级别
mne.set_log_level(False)
# 需要分析的频带及其范围
bandFreqs = [
    {'name': 'Delta', 'fmin': 1, 'fmax': 3},
    {'name': 'Theta', 'fmin': 4, 'fmax': 7},
    {'name': 'Alpha', 'fmin': 8, 'fmax': 13},
    {'name': 'Beta', 'fmin': 14, 'fmax': 31},
    {'name': 'Gamma', 'fmin': 31, 'fmax': 40}
]




def __CalcWP(data, sfreq, wavelet, maxlevel, band):
    # 如果maxlevel太小部分波段分析不到
    wp = pywt.WaveletPacket(data=data, wavelet=wavelet, mode='symmetric', maxlevel=maxlevel)
    # 频谱由低到高的对应关系,这里需要注意小波变换的频带排列默认并不是顺序排列,所以这里需要使用’freq‘排序。
    freqTree = [node.path for node in wp.get_level(maxlevel, 'freq')]
    # 计算maxlevel最小频段的带宽,采样频率的一半
    freqBand = (sfreq/2) / (2 ** maxlevel)
    bandResult = []
    #######################根据实际情况计算频谱对应关系,这里要注意系数的顺序
    for iter_freq in band:
        # 构造空的小波包
        new_wp = pywt.WaveletPacket(data=None, wavelet=wavelet, mode='symmetric', maxlevel=maxlevel)
        for i in range(len(freqTree)):
            # 第i个频段的最小频率
            bandMin = i * freqBand
            # 第i个频段的最大频率
            bandMax = bandMin + freqBand
            # 判断第i个频段是否在要分析的范围内
            if (iter_freq['fmin'] <= bandMin and iter_freq['fmax'] >= bandMax):
                # 给新构造的小波包参数赋值
                # print('freq',bandMin, bandMax,'fmin',iter_freq['fmin'],'fmax',iter_freq['fmax'])
                new_wp[freqTree[i]] = wp[freqTree[i]].data
        # 计算对应频率的数据
        bandResult.append(new_wp.reconstruct(update=True))
    return bandResult

########################################小波包变换-重构造分析不同频段的特征(注意maxlevel,如果太小可能会导致部分频段分析不到)#########################
# 定义WP函数
# epochsData:epochs的数据(mumpy格式)
# sfreq:采样频率
# wavelet:小波类型
# maxlevel:小波层数
# band:频带类型

def WP(epochsData, sfreq, wavelet='db4', maxlevel=8, band=bandFreqs):
    # 输出的维度顺序为 频率->epoch->channel->timeData
    result = []
    for epochData in epochsData:
        channel = []
        for channelData in epochData:
            # print('channel:')
            channel.append(__CalcWP(channelData, sfreq, wavelet=wavelet, maxlevel=maxlevel, band=band))
        result.append(channel)
    return np.array(result).transpose((2, 0, 1, 3))



if __name__ == '__main__':
    # 加载fif格式的数据
    epochs = mne.read_epochs(r'F:\BaiduNetdiskDownload\BCICompetition\BCICIV_2a_gdf\Train\Fif\A02T_epo.fif')
    # 绘图验证结果
    plt.figure(figsize=(15, 10))
    # 获取采样频率
    sfreq = epochs.info['sfreq']
    # 想要分析的目标频带
    bandIndex = 0
    # 想要分析的channel
    channelIndex = 0
    # 想要分析的epoch
    epochIndex = 0
    # 绘制原始数据
    plt.plot(epochs.get_data()[epochIndex][channelIndex], label='Raw')
    # 计算FIR滤波后的数据并绘图(注意这里要使用copy方法,否则会改变原始数据)
    firFilter = epochs.copy().filter(bandFreqs[bandIndex]['fmin'], bandFreqs[bandIndex]['fmax'])
    plt.plot(firFilter.get_data()[epochIndex][channelIndex], c=(1, 0, 0), label='FIR_Filter')
    # 计算小波包滤波后的数据并绘图
    wpFilter = WP(epochs.get_data(), sfreq)
    plt.plot(wpFilter[bandIndex][epochIndex][channelIndex], c=(0, 1, 0), label='WP_Filter')
    # 绘制图例和图名
    plt.legend()
    plt.title(bandFreqs[bandIndex]['name'])


    ####################################FFT对比两种方法的频谱分布
    plt.figure(figsize=(15, 10))
    # 对FIR滤波后的数据进行FFT变换
    mneFIRFreq = np.abs(fft.fft(firFilter.get_data()[epochIndex][channelIndex]))
    # 对小波包滤波后的数据进行FFT变换,需要注意小波包变换后数据的点数可能会发生变化,这里截取数据保持一致性
    pointNum = epochs.get_data()[epochIndex][channelIndex].shape[0]
    wpFreq = np.abs(fft.fft(wpFilter[bandIndex][epochIndex][channelIndex][:pointNum]))
    # 想要绘制的点数
    pointPlot = 300
    # FIR滤波后x轴对应的频率幅值范围
    FIR_X = np.linspace(0, sfreq/2, int(mneFIRFreq.shape[0]/2))
    # 小波包滤波后x轴对应的频率幅值范围
    WP_X = np.linspace(0, sfreq/2, int(wpFreq.shape[0]/2))
    # 绘制FIR滤波后的频谱分布
    plt.plot(FIR_X[:pointPlot], mneFIRFreq[:pointPlot], c=(1, 0, 0), label='FIR_Filter')
    # 绘制小波包滤波后的频谱分布
    plt.plot(WP_X[:pointPlot], wpFreq[:pointPlot], c=(0, 1, 0), label='WP_FIlter')
    # 绘制图例和图名
    plt.legend()
    plt.title(bandFreqs[bandIndex]['name'])
    plt.show()

注:小波包滤波后数据长度会发生改变,这主要和小波层数以及计算方式有关,超出原始长度的数据可以不用关心,上面的代码中在进行频谱分析前,也就是计算FFT前对数据的长度进行了处理,这样可以保证分析出频谱数据的一致性。

 

WP和FIR在不同频段滤波效果对比:

从滤波的结果来看,小波包的滤波效果在低频段还不错,可是到了高频段其效果一般。

https://blog.csdn.net/zhoudapeng01/article/details/108214064(FIR和STFT对比)

对比FIR、STFT以及WP这三种方法,STFT相对效果更好些。

 

Delta频段(1Hz-3Hz)对应的结果

Theta频段(4Hz-7Hz)对应的结果

Alpha频段(8Hz-13Hz)对应的结果

Beta频段(14Hz-31Hz)对应的结果

Gamma频段(31Hz-40Hz)对应的结果

对应的资源包下载:https://download.csdn.net/download/zhoudapeng01/12793085

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python中FIR滤波和小波包滤波对比(MNE脑电数据处理) 的相关文章

随机推荐

  • 系统架构主题之五:软件系统建模方法及其应用

    前面我们梳理了需求分析的相关内容 完成需求分析后 会输出指导软件开发的需求规格说明书 有了该文档的支持 下一步就是系统设计阶段 用于将软件需求的内容转换为可指导软件开发的概要设计和详细设计文档 下面我们从理论和实践上看看如果做系统设计 1
  • Centos7.6 安装最新k8s v1.24+containerd+calico

    安装最新k8s v1 24 containerd calico 开始之前 部署文件位置 端口开放 k8s中需要开放的端口 calico网络插件需要开放的端口 所有服务器都要做的操作 1 升级系统内核 CentOS 7 CentOS 8 2
  • 04_Nginx_从url中获取参数

    04 Nginx 从url中获取参数 1 导读 2 代码示例 3 实验截图 1 导读 需要从url中获取到想要的参数 特此记录方式 2 代码示例 使用的是ngx http request t结构体中的args参数 printf n char
  • 2022年「博客之星」 无知的人_的程序人生

    这是 2022 博客之星 的竞选帖子 请你在这里增加其他内容 包括但不限于 你这一年的收获 感悟 对CSDN 产品的反馈和 2023 年的希望 参考 https blog csdn net SoftwareTeacher article d
  • MYSQL查询当前表存在哪些索引

    查看表存在的索引 show index from table name 表名 结果列表中各字段的含义 Non unique 如果索引不能包括重复词 则为0 如果可以 则为1 Key name 索引名称 Seq in index 索引中的列序
  • TIKTOK视频:视频内容打造需要注意的几点 抓住流量密码

    TIKTOK视频 视频内容打造需要注意的几点 抓住流量密码 大家好 我是项柚 一个专注于讨论TikTok玩法的跨境电商自媒体人 每天不断输出干货给需要的朋友 大家都知道 欧美跨境市场已经被认为是 红海 很多人已经凭着一股冲劲凭着一边做一边学
  • mybatis plus 常用方法

    学习链接 简介 MyBatis Plus 一 分页 创建分页实体 Page
  • 文盘Rust -- 给程序加个日志

    日志是应用程序的重要组成部分 无论是服务端程序还是客户端程序都需要日志做为错误输出或者业务记录 在这篇文章中 我们结合log4rs聊聊rust 程序中如何使用日志 log4rs类似java生态中的log4j 使用方式也很相似 log4rs中
  • 基于SoC FPAG实现手写体识别(HLS编译的全连接算子)

    基于SoC FPAG实现手写体识别 HLS编译的全连接算子 点击操作手册下载 完整代码 1 HLS的代码 2 SoC EDS 中 eclipse 测试代码 由于流程过多 这里采用pdf文件下载的方式 点击操作手册下载 链接 https pa
  • 北京大学肖臻老师《区块链技术与应用》公开课笔记-BTC

    本笔记为学习期间对主要知识和逻辑的记录 根据课程内容分为BTC和ETH两篇 本篇为BTC部分 北京大学肖臻老师 区块链技术与应用 公开课笔记 ETH 文章目录 01 课程简介 02 BTC 密码学原理 03 BTC 数据结构 04 BTC
  • javascript ES5中 foreach()遍历方法

    forcach array forEach function currentValue index arr currentValue 数组当前项的值 index 数组当前项的索引 可选 arr 数组对象本身 filter 方法创建一个新的数
  • Unable to launch the IIS Express Web server 问题之解决 - [Visual Studio 2015]

    背景 Visual Studio 2015 在 Debug 模式下调试失败 报错如下图所示 解决办法 删除解决方案下 vs config 文件夹内的这个配置文件 再关闭并重新运行解决方案即可进行调试
  • 清除SVN版本信息

    echo on color 2f mode con cols 80 lines 25 REM echo Deleting all svn please wait rem Delete svn in current and sub direc
  • LeetCode之Count Binary Substrings(Kotlin)

    问题 Give a string s count the number of non empty contiguous substrings that have the same number of 0 s and 1 s and all
  • 如何搭建C语言环境

    以下文章来源于 公 众 号开源电子网 读取更多技术文章 请扫码关注 如何搭建C语言环境 前言 C语言作为嵌入式开发的必备掌握技能 嵌入式能力的提升速度很大程度在于C语言的掌握能力 正所谓 工欲善其事 必先利其器 学习C语言 第一件动手的事情
  • 【餐厅点餐平台|一】项目描述+需求分析

    餐厅点餐平台导航 餐厅点餐平台 一 项目描述 需求分析 https blog csdn net weixin 46291251 article details 126414430 餐厅点餐平台 二 总体设计 https blog csdn
  • 大数据系列——Redis部署及应用

    Redis有四种部署方式 分别为单机模式 主备模式 哨兵模式 集群模式 其中单机模式比较简单 容量 处理能力有限 没有高可用 主备模式和哨兵模式本质和单机模式一样 只是主备模式保证数据高可用 哨兵模式保证数据和服务的高可用 集群模式是将数据
  • 为什么宏定义和函数定义运行结果不一样?

    函数定义 include
  • JUC-16. CAS

    想了解更多JUC的知识 JUC并发编程合集 1 CAS的概述 CAS的全称为Compare And Swap 比较并交换 它是一条CPU并发原语 比较工作内存值 预期值 和主物理内存的共享值是否相同 相同则执行规定操作 否则继续比较直到主内
  • Python中FIR滤波和小波包滤波对比(MNE脑电数据处理)

    小波变换有信号显微镜之称 在EEG分析中也有广泛的应用 印象中小波算法是来源于地球物理解释的 之前有介绍过小波的一些资料和实现 https blog csdn net zhoudapeng01 article details 1070259