声振论坛

 找回密码
 我要加入

QQ登录

只需一步,快速开始

查看: 2702|回复: 0

[其他] 经验模态分解(EMD)

[复制链接]
发表于 2016-5-4 09:55 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?我要加入

x
今天看了些EMD信号分解方面的东西,matlab官网上有个Hilbert-Huang Transform的代码,代码效率极高啊,人家3句语句就解决了一个大问题,很牛啊!还有一个GRilling的EMD工具箱,好多文件,功能应该相当强大。
    这里研究了研究matlab官网的代码,加了些注释、功能演示,效果如下
    原始信号由3个正弦信号加噪声组成,如下
1.png
下面为做EMD分解的结果
2.png 3.png
第三次分解信号的瞬时频率如下
4.png
第四次分解信号的Hilbert分析
5.png
具体代码如下
  1. <font color="#000000">test.m文件
  2. clc
  3. clear all
  4. close all
  5. % [x, Fs] = wavread('Hum.wav');
  6. % Ts = 1/Fs;
  7. % x = x(1:6000);
  8. Ts = 0.001;
  9. Fs = 1/Ts;
  10. t=0:Ts:1;
  11. x = sin(2*pi*10*t) + sin(2*pi*50*t) + sin(2*pi*100*t) + 0.1*randn(1, length(t));
  12. imf = emd(x);
  13. plot_hht(x,imf,1/Fs);
  14. k = 4;
  15. y = imf{k};
  16. N = length(y);
  17. t = 0:Ts:Ts*(N-1);
  18. [yenvelope, yfreq, yh, yangle] = HilbertAnalysis(y, 1/Fs);
  19. yModulate = y./yenvelope;
  20. [YMf, f] = FFTAnalysis(yModulate, Ts);
  21. Yf = FFTAnalysis(y, Ts);
  22. figure
  23. subplot(321)
  24. plot(t, y)
  25. title(sprintf('IMF%d', k))
  26. xlabel('Time/s')
  27. ylabel(sprintf('IMF%d', k));
  28. subplot(322)
  29. plot(f, Yf)
  30. title(sprintf('IMF%d的频谱', k))
  31. xlabel('f/Hz')
  32. ylabel('|IMF(f)|');
  33. subplot(323)
  34. plot(t, yenvelope)
  35. title(sprintf('IMF%d的包络', k))
  36. xlabel('Time/s')
  37. ylabel('envelope');
  38. subplot(324)
  39. plot(t(1:end-1), yfreq)
  40. title(sprintf('IMF%d的瞬时频率', k))
  41. xlabel('Time/s')
  42. ylabel('Frequency/Hz');
  43. subplot(325)
  44. plot(t, yModulate)
  45. title(sprintf('IMF%d的调制信号', k))
  46. xlabel('Time/s')
  47. ylabel('modulation');
  48. subplot(326)
  49. plot(f, YMf)
  50. title(sprintf('IMF%d调制信号的频谱', k))
  51. xlabel('f/Hz')
  52. ylabel('|YMf(f)|');

  53. findpeaks.m文件
  54. function n = findpeaks(x)
  55. % Find peaks. 找极大值点,返回对应极大值点的坐标
  56. n    = find(diff(diff(x) > 0) < 0); % 相当于找二阶导小于0的点
  57. u    = find(x(n+1) > x(n));
  58. n(u) = n(u)+1;                      % 加1才真正对应极大值点
  59. % 图形解释上述过程
  60. % figure
  61. % subplot(611)
  62. % x = x(1:100);
  63. % plot(x, '-o')
  64. % grid on
  65. %
  66. % subplot(612)
  67. % plot(1.5:length(x), diff(x) > 0, '-o')
  68. % grid on
  69. % axis([1,length(x),-0.5,1.5])
  70. %
  71. % subplot(613)
  72. % plot(2:length(x)-1, diff(diff(x) > 0), '-o')
  73. % grid on
  74. % axis([1,length(x),-1.5,1.5])
  75. %
  76. % subplot(614)
  77. % plot(2:length(x)-1, diff(diff(x) > 0)<0, '-o')
  78. % grid on
  79. % axis([1,length(x),-1.5,1.5])
  80. %
  81. % n    = find(diff(diff(x) > 0) < 0);
  82. % subplot(615)
  83. % plot(n, ones(size(n)), 'o')
  84. % grid on
  85. % axis([1,length(x),0,2])
  86. %
  87. % u    = find(x(n+1) > x(n));
  88. % n(u) = n(u)+1;
  89. % subplot(616)
  90. % plot(n, ones(size(n)), 'o')
  91. % grid on
  92. % axis([1,length(x),0,2])

  93. plot_hht.m文件
  94. function plot_hht(x,imf,Ts)
  95. % Plot the HHT.
  96. % :: Syntax
  97. %    The array x is the input signal and Ts is the sampling period.
  98. %    Example on use: [x,Fs] = wavread('Hum.wav');
  99. %                    plot_hht(x(1:6000),1/Fs);
  100. % Func : emd
  101. % imf = emd(x);
  102. for k = 1:length(imf)
  103.     b(k) = sum(imf{k}.*imf{k});
  104.     th   = unwrap(angle(hilbert(imf{k})));  % 相位
  105.     d{k} = diff(th)/Ts/(2*pi);          % 瞬时频率
  106. end
  107. [u,v] = sort(-b);
  108. b     = 1-b/max(b);                     % 后面绘图的亮度控制
  109. % Hilbert瞬时频率图
  110. N = length(x);
  111. c = linspace(0,(N-2)*Ts,N-1);           % 0:Ts:Ts*(N-2)
  112. for k = v(1:2)                          % 显示能量最大的两个IMF的瞬时频率
  113.     figure
  114.     plot(c,d{k});
  115.     xlim([0 c(end)]);
  116.     ylim([0 1/2/Ts]);
  117.     xlabel('Time/s')
  118.     ylabel('Frequency/Hz');
  119.     title(sprintf('IMF%d', k))
  120. end
  121. % 显示各IMF
  122. M = length(imf);
  123. N = length(x);
  124. c = linspace(0,(N-1)*Ts,N);             % 0:Ts:Ts*(N-1)
  125. for k1 = 0:4:M-1
  126.     figure
  127.     for k2 = 1:min(4,M-k1)
  128.         subplot(4,2,2*k2-1)
  129.         plot(c,imf{k1+k2})
  130.         set(gca,'FontSize',8,'XLim',[0 c(end)]);
  131.         title(sprintf('第%d个IMF', k1+k2))
  132.         xlabel('Time/s')
  133.         ylabel(sprintf('IMF%d', k1+k2));
  134.       
  135.         subplot(4,2,2*k2)
  136.         [yf, f] = FFTAnalysis(imf{k1+k2}, Ts);
  137.         plot(f, yf)
  138.         title(sprintf('第%d个IMF的频谱', k1+k2))
  139.         xlabel('f/Hz')
  140.         ylabel('|IMF(f)|');
  141.     end
  142. end
  143. figure
  144. subplot(211)
  145. plot(c,x)
  146. set(gca,'FontSize',8,'XLim',[0 c(end)]);
  147. title('原始信号')
  148. xlabel('Time/s')
  149. ylabel('Origin');
  150. subplot(212)
  151. [Yf, f] = FFTAnalysis(x, Ts);
  152. plot(f, Yf)
  153. title('原始信号的频谱')
  154. xlabel('f/Hz')
  155. ylabel('|Y(f)|');
  156. emd.m文件
  157. function imf = emd(x)
  158. % Empiricial Mode Decomposition (Hilbert-Huang Transform)
  159. % EMD分解或HHT变换
  160. % 返回值为cell类型,依次为一次IMF、二次IMF、...、最后残差
  161. x   = transpose(x(:));
  162. imf = [];
  163. while ~ismonotonic(x)
  164.     x1 = x;
  165.     sd = Inf;
  166.     while (sd > 0.1) || ~isimf(x1)
  167.         s1 = getspline(x1);         % 极大值点样条曲线
  168.         s2 = -getspline(-x1);       % 极小值点样条曲线
  169.         x2 = x1-(s1+s2)/2;
  170.       
  171.         sd = sum((x1-x2).^2)/sum(x1.^2);
  172.         x1 = x2;
  173.     end
  174.    
  175.     imf{end+1} = x1;
  176.     x          = x-x1;
  177. end
  178. imf{end+1} = x;
  179. % 是否单调
  180. function u = ismonotonic(x)
  181. u1 = length(findpeaks(x))*length(findpeaks(-x));
  182. if u1 > 0
  183.     u = 0;
  184. else
  185.     u = 1;
  186. end
  187. % 是否IMF分量
  188. function u = isimf(x)
  189. N  = length(x);
  190. u1 = sum(x(1:N-1).*x(2:N) < 0);                     % 过零点的个数
  191. u2 = length(findpeaks(x))+length(findpeaks(-x));    % 极值点的个数
  192. if abs(u1-u2) > 1
  193.     u = 0;
  194. else
  195.     u = 1;
  196. end
  197. % 据极大值点构造样条曲线
  198. function s = getspline(x)
  199. N = length(x);
  200. p = findpeaks(x);
  201. s = spline([0 p N+1],[0 x(p) 0],1:N);
  202. FFTAnalysis.m文件
  203. % 频谱分析
  204. function [Y, f] = FFTAnalysis(y, Ts)
  205. Fs = 1/Ts;
  206. L = length(y);
  207. NFFT = 2^nextpow2(L);
  208. y = y - mean(y);
  209. Y = fft(y, NFFT)/L;
  210. Y = 2*abs(Y(1:NFFT/2+1));
  211. f = Fs/2*linspace(0, 1, NFFT/2+1);
  212. end
  213. HilbertAnalysis.m文件
  214. % Hilbert分析
  215. function [yenvelope, yf, yh, yangle] = HilbertAnalysis(y, Ts)
  216. yh = hilbert(y);
  217. yenvelope = abs(yh);                % 包络
  218. yangle = unwrap(angle(yh));         % 相位
  219. yf = diff(yangle)/2/pi/Ts;          % 瞬时频率
  220. end</font>
复制代码

本帖被以下淘专辑推荐:

回复
分享到:

使用道具 举报

您需要登录后才可以回帖 登录 | 我要加入

本版积分规则

QQ|小黑屋|Archiver|手机版|联系我们|声振论坛

GMT+8, 2024-12-1 09:13 , Processed in 0.060169 second(s), 24 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表