- EMD(Empirical Mode Decomposition)是由美国国家宇航局的华裔科学家Norden e. Huang博士于1998年提出的一种新的处理非平稳信号的方法:希尔伯特—黄变化(HHT)的重要组成部分 。
- 依据数据自身的 时间尺度特征来进行信号分解,无须预先设定任何基函数,自适应地进行信号主要成分分析
- 基于EMD的时频分析方法既适合于 非线性、非平稳信号 的分析,也适合于 线性、平稳信号 的分析,并且对于线性、平稳信号的分析也比其他的时频分析方法更好地反映了信号的物理意义。
【 1. 本征模态函数 IMF 】
- IMF(Intrinsic Mode Function)本征模态函数,就是我们分解后得到的信号分量。
- 一个本征模函数必须满足以下两个条件:
⑴ 函数在整个时间范围内,局部极值点和过零点的数目必须相等或最多相差一个;
⑵ 在任意时刻点,局部最大值的包络(上包络线)和局部最小值的包络(下包络线) 平均必须为零。 - IMF 的各个分量分别代表了原始信号中的各频率分量,并按照从高频到低频的顺序依次排列。这也就是(非常简单的情况下的)IMF的物理含义。
【 2. 算法步骤 】
- 找到原信号 x(t) 所有的极值点;
- 找出上下极值点的包络线 e m a x ( t ) e_{max}(t) emax(t) 和 e m i n ( t ) e_{min}(t) emin(t),并求出上下包络线的平均值m(t) ,我们把m(t)叫做均值包络线,在x(t)中减去m(t):h(t)=x(t)-m(t),我们把h(t)叫做中间信号;
- 判断 h(t) 是否为 IMF;
- 如果不是,则以h(t)代替 x(t),重复以上步骤直到 h(t) 满足判据,则h(t)就是需要提取的 IMF;
- 如果是,就从原信号中扣除它,重复以上步骤,直到信号最后剩余部分rn就只是单调序列或者常值序列。这样,经过EMD方法分解就将原始信号x(t)分解成一系列 IMF 以及剩余部分的线性叠加。
【 3. MATLAB代码 】
data=load('sinusoidalSignalExampleData.mat','X','fs'); %载入数据
t = (0:length(X)-1)/fs; %横坐标轴值
plot(t,X); %绘制原始信号图
xlabel('Time(s)') %横坐标标签
emd(X,'Interpolation','pchip') %emd分解
【 4. C代码 】
我想把EMD这样的算法嵌入到单片机中,但是网上几乎没有EMD的C代码。但是,找着找着,发现了 MATLAB 的C/C++语言转换工具…
官方说,有些MATLAB内置函数是无法进行转化的。但是,我从官方的描述 可实现C语言转换的MTLAB代码 中找到了emd !
于是…在 emd 函数的官方描述中:MATLAB关于emd的官方说明 MATLAB生成C代码有两个限制条件:
- 时间表不支持。
- 如果要用到插值方法,则“Interpolation”一定是常量。
所以,在生成C代码时,我们只考虑转换 [imf,residual,info] = emd(x) 这种形式的emd函数。
通过参考这篇文章:参考教程:Matlab中eig内置函数转为C语言 生成了下图最终的工程,转换成功。
【 5. 应用、缺点和改进 】
- EMD主要用于 信号的分解、滤波,比如心率信号采集。
- 但是EMD也有缺点,会出现模态混叠和端点效应现象。模态混叠就是不同模态的信号混叠在一起,一般有两种情况:一是不同特征尺度的信号在一个IMF分量中出现,另一种是同一个特征尺度的信号被分散到不同的IMF分量中。
- 改进:EEMD、CEMD
【 6. 相关链接 】
1. 这篇文章能让你明白经验模态分解(EMD)——基础理论篇
2. 这篇文章能让你明白经验模态分解(EMD)——IMF的物理含义