Pseudo-lover 发表于 2016-5-4 09:55

经验模态分解(EMD)

今天看了些EMD信号分解方面的东西,matlab官网上有个Hilbert-Huang Transform的代码,代码效率极高啊,人家3句语句就解决了一个大问题,很牛啊!还有一个GRilling的EMD工具箱,好多文件,功能应该相当强大。    这里研究了研究matlab官网的代码,加了些注释、功能演示,效果如下    原始信号由3个正弦信号加噪声组成,如下下面为做EMD分解的结果第三次分解信号的瞬时频率如下第四次分解信号的Hilbert分析具体代码如下<font color="#000000">test.m文件
clc
clear all
close all
% = wavread('Hum.wav');
% Ts = 1/Fs;
% x = x(1:6000);
Ts = 0.001;
Fs = 1/Ts;
t=0:Ts:1;
x = sin(2*pi*10*t) + sin(2*pi*50*t) + sin(2*pi*100*t) + 0.1*randn(1, length(t));
imf = emd(x);
plot_hht(x,imf,1/Fs);
k = 4;
y = imf{k};
N = length(y);
t = 0:Ts:Ts*(N-1);
= HilbertAnalysis(y, 1/Fs);
yModulate = y./yenvelope;
= FFTAnalysis(yModulate, Ts);
Yf = FFTAnalysis(y, Ts);
figure
subplot(321)
plot(t, y)
title(sprintf('IMF%d', k))
xlabel('Time/s')
ylabel(sprintf('IMF%d', k));
subplot(322)
plot(f, Yf)
title(sprintf('IMF%d的频谱', k))
xlabel('f/Hz')
ylabel('|IMF(f)|');
subplot(323)
plot(t, yenvelope)
title(sprintf('IMF%d的包络', k))
xlabel('Time/s')
ylabel('envelope');
subplot(324)
plot(t(1:end-1), yfreq)
title(sprintf('IMF%d的瞬时频率', k))
xlabel('Time/s')
ylabel('Frequency/Hz');
subplot(325)
plot(t, yModulate)
title(sprintf('IMF%d的调制信号', k))
xlabel('Time/s')
ylabel('modulation');
subplot(326)
plot(f, YMf)
title(sprintf('IMF%d调制信号的频谱', k))
xlabel('f/Hz')
ylabel('|YMf(f)|');

findpeaks.m文件
function n = findpeaks(x)
% Find peaks. 找极大值点,返回对应极大值点的坐标
n    = find(diff(diff(x) > 0) < 0); % 相当于找二阶导小于0的点
u    = find(x(n+1) > x(n));
n(u) = n(u)+1;                      % 加1才真正对应极大值点
% 图形解释上述过程
% figure
% subplot(611)
% x = x(1:100);
% plot(x, '-o')
% grid on
%
% subplot(612)
% plot(1.5:length(x), diff(x) > 0, '-o')
% grid on
% axis()
%
% subplot(613)
% plot(2:length(x)-1, diff(diff(x) > 0), '-o')
% grid on
% axis()
%
% subplot(614)
% plot(2:length(x)-1, diff(diff(x) > 0)<0, '-o')
% grid on
% axis()
%
% n    = find(diff(diff(x) > 0) < 0);
% subplot(615)
% plot(n, ones(size(n)), 'o')
% grid on
% axis()
%
% u    = find(x(n+1) > x(n));
% n(u) = n(u)+1;
% subplot(616)
% plot(n, ones(size(n)), 'o')
% grid on
% axis()

plot_hht.m文件
function plot_hht(x,imf,Ts)
% Plot the HHT.
% :: Syntax
%    The array x is the input signal and Ts is the sampling period.
%    Example on use: = wavread('Hum.wav');
%                  plot_hht(x(1:6000),1/Fs);
% Func : emd
% imf = emd(x);
for k = 1:length(imf)
    b(k) = sum(imf{k}.*imf{k});
    th   = unwrap(angle(hilbert(imf{k})));% 相位
    d{k} = diff(th)/Ts/(2*pi);          % 瞬时频率
end
= sort(-b);
b   = 1-b/max(b);                     % 后面绘图的亮度控制
% Hilbert瞬时频率图
N = length(x);
c = linspace(0,(N-2)*Ts,N-1);         % 0:Ts:Ts*(N-2)
for k = v(1:2)                        % 显示能量最大的两个IMF的瞬时频率
    figure
    plot(c,d{k});
    xlim();
    ylim();
    xlabel('Time/s')
    ylabel('Frequency/Hz');
    title(sprintf('IMF%d', k))
end
% 显示各IMF
M = length(imf);
N = length(x);
c = linspace(0,(N-1)*Ts,N);             % 0:Ts:Ts*(N-1)
for k1 = 0:4:M-1
    figure
    for k2 = 1:min(4,M-k1)
      subplot(4,2,2*k2-1)
      plot(c,imf{k1+k2})
      set(gca,'FontSize',8,'XLim',);
      title(sprintf('第%d个IMF', k1+k2))
      xlabel('Time/s')
      ylabel(sprintf('IMF%d', k1+k2));
      
      subplot(4,2,2*k2)
       = FFTAnalysis(imf{k1+k2}, Ts);
      plot(f, yf)
      title(sprintf('第%d个IMF的频谱', k1+k2))
      xlabel('f/Hz')
      ylabel('|IMF(f)|');
    end
end
figure
subplot(211)
plot(c,x)
set(gca,'FontSize',8,'XLim',);
title('原始信号')
xlabel('Time/s')
ylabel('Origin');
subplot(212)
= FFTAnalysis(x, Ts);
plot(f, Yf)
title('原始信号的频谱')
xlabel('f/Hz')
ylabel('|Y(f)|');
emd.m文件
function imf = emd(x)
% Empiricial Mode Decomposition (Hilbert-Huang Transform)
% EMD分解或HHT变换
% 返回值为cell类型,依次为一次IMF、二次IMF、...、最后残差
x   = transpose(x(:));
imf = [];
while ~ismonotonic(x)
    x1 = x;
    sd = Inf;
    while (sd > 0.1) || ~isimf(x1)
      s1 = getspline(x1);         % 极大值点样条曲线
      s2 = -getspline(-x1);       % 极小值点样条曲线
      x2 = x1-(s1+s2)/2;
      
      sd = sum((x1-x2).^2)/sum(x1.^2);
      x1 = x2;
    end
   
    imf{end+1} = x1;
    x          = x-x1;
end
imf{end+1} = x;
% 是否单调
function u = ismonotonic(x)
u1 = length(findpeaks(x))*length(findpeaks(-x));
if u1 > 0
    u = 0;
else
    u = 1;
end
% 是否IMF分量
function u = isimf(x)
N= length(x);
u1 = sum(x(1:N-1).*x(2:N) < 0);                     % 过零点的个数
u2 = length(findpeaks(x))+length(findpeaks(-x));    % 极值点的个数
if abs(u1-u2) > 1
    u = 0;
else
    u = 1;
end
% 据极大值点构造样条曲线
function s = getspline(x)
N = length(x);
p = findpeaks(x);
s = spline(,,1:N);
FFTAnalysis.m文件
% 频谱分析
function = FFTAnalysis(y, Ts)
Fs = 1/Ts;
L = length(y);
NFFT = 2^nextpow2(L);
y = y - mean(y);
Y = fft(y, NFFT)/L;
Y = 2*abs(Y(1:NFFT/2+1));
f = Fs/2*linspace(0, 1, NFFT/2+1);
end
HilbertAnalysis.m文件
% Hilbert分析
function = HilbertAnalysis(y, Ts)
yh = hilbert(y);
yenvelope = abs(yh);                % 包络
yangle = unwrap(angle(yh));         % 相位
yf = diff(yangle)/2/pi/Ts;          % 瞬时频率
end</font>转自:http://blog.sina.com.cn/s/blog_6163bdeb0102e2b3.html
页: [1]
查看完整版本: 经验模态分解(EMD)