zoukankan      html  css  js  c++  java
  • EMD算法原理与Python实现

    本教程为脑机学习者Rose原创(转载请联系作者授权)发表于公众号:脑机接口社区(微信号:Brain_Computer).QQ交流群:903290195

    简介

    SSVEP信号中含有自发脑电和大量外界干扰信号,属于典型的非线性非平稳信号。传统的滤波方法通常不满足对非线性非平稳分析的条件,1998年黄鄂提出希尔伯特黄变换(HHT)方法,其中包含经验模式分解(EMD)和希尔伯特变换(HT)两部分。EMD可以将原始信号分解成为一系列固有模态函数(IMF) [1],IMF分量是具有时变频率的震荡函数,能够反映出非平稳信号的局部特征,用它对非线性非平稳的SSVEP信号进行分解比较合适。

    EMD算法原理

    任何复杂的信号均可视为多个不同的固有模态函数叠加之和,任何模态函数可以是线性的或非线性的,并且任意两个模态之间都是相互独立的。在这个假设基础上,复杂信号$x(t)$的EMD分解步骤如下:
    步骤1:
    寻找信号 全部极值点,通过三次样条曲线将局部极大值点连成上包络线,将局部极小值点连成下包络线。上、下包络线包含所有的数据点。

    步骤2:
    由上包络和下包络线的平均值$m_{1}(t)$ ,得出
    $$h_1(t)=x(t)-m_{1}(t)$$
    若$h_{1}(t)$满足IMF的条件,则可认为$h_{1}(t)$是$x(t)$的第一个IMF分量。

    步骤3:
    若$h_{1}(t)$不符合IMF条件,则将$h_{1}(t)$作为原始数据,重复步骤1、步骤2,得到上、下包络的均值$m_{11}(t)$,通过计算$h_{11}(t)=h_{1}(t)-m_{11}(t)$是否适合IMF分量的必备条件,若不满足,重复如上两步$k$次,直到满足前提下得到$h_{1k}(t)=h_{1(k-1)}(t)-m_{1k}(t)$。第1个IMF表示如下:
    $$c_{1}(t)=h_{1k}(t)$$

    步骤4:
    将$c_{1}(t)$从信号$x(t)$中分离得到:
    $$r_{1}=x(t)-c_{1}(t)$$
    将$r_{1}(t)$作为原始信号重复上述三个步骤,循环$n$次,得到第二个IMF分量$c_{2}(t)$直到第$n$个IMF分量 ,则会得出:

    $$egin{cases}
    r_{2}(t)=r_{1}(t)-c_{2}(t)
    cdots
    r_{n}(t)=r_{n-1}(t)-c_{n}(t)
    end{cases}
    $$

    步骤5:
    当$r_{n}(t)$变成单调函数后,剩余的$r_{n}(t)$成为残余分量。所有IMF分量和残余分量之和为原始信号$x(t)$:
    $$x(t)=sum^{n}c_{i}(t)+r_{n}(t)$$

    用EMD进行滤波的基本思想是将原信号进行EMD分解后,只选取与特征信号相关的部分对信号进行重构。如下图中a部分为原始信号,b部分为将原始信号进行EMD分解获得的6个IMF分量和1个残余分量,c部分为将分解获得的6个IMF分量和1个残余分量进行重构后的信号,可以看出SSVEP信号用EMD分解后,基本上包含了原有信号的全部信息。

    图片来源于[1]

    python实现EMD案例

    # 导入工具库
    import numpy as np
    from PyEMD import EMD, Visualisation
    

    构建信号
    时间t: 为0到1s,采样频率为100Hz,S为合成信号

    # 构建信号
    t = np.arange(0,1, 0.01)
    S = 2*np.sin(2*np.pi*15*t) +4*np.sin(2*np.pi*10*t)*np.sin(2*np.pi*t*0.1)+np.sin(2*np.pi*5*t)
    
    # 提取imfs和剩余信号res
    emd = EMD()
    emd.emd(S)
    imfs, res = emd.get_imfs_and_residue()
    # 绘制 IMF
    vis = Visualisation()
    vis.plot_imfs(imfs=imfs, residue=res, t=t, include_residue=True)
    

    # 绘制并显示所有提供的IMF的瞬时频率
    vis.plot_instant_freq(t, imfs=imfs)
    vis.show()
    

    脑机学习者Rose笔记分享,QQ交流群:903290195
    更多分享,请关注公众号

  • 相关阅读:
    python函数练习题2
    python函数练习题1
    数字是否是10的整数倍
    关于循环的作业:登陆程序
    用for循环写这段代码
    while循环语句
    在CentOS8 上安装Python3
    时隔半年再写购物车程序并改进
    vue上传
    根据生日计算年龄
  • 原文地址:https://www.cnblogs.com/RoseVorchid/p/11985368.html
Copyright © 2011-2022 走看看