function [Imf] = Emd(Sig); %对信号进行经验模式分解
if(nargin < 1),
error('At least one input is needed!');
end
Sig = Sig';
SigLen = length(Sig);
t = 1:SigLen;
c = Sig;
Imf = [];
nLoop = 1;
MaxLoop = 1000;
[IndMax, IndMin] = ExtrPoint(c); %提取信号的极值点:极大值点和极小值点
[Index_zer] = ZeroPoint(c); %提取信号的零点
NExtr = length(IndMin) + length(IndMax); %极值点个数
NZero = length(Index_zer); %零点个数
Bool = 1;
NEtd = 2;
IMFNum = 0;
while( NExtr >2 & Bool >0),
h = c;
nLoop = 1;
SD = 1;
while((SD>0.3|(abs(NZero-NExtr)>1))&(NExtr>2)&nLoop<MaxLoop) %镜像拓展序列
LMaxEtd = fliplr(IndMax(1:min(end,NEtd)));
LMinEtd = fliplr(IndMin(1:min(end,NEtd)));
hlMaxEtd = h(LMaxEtd);
hlMinEtd = h(LMinEtd);
LMaxEtd = -LMaxEtd +1;
LMinEtd = -LMinEtd +1;
RMaxEtd = fliplr(IndMax(max(end-NEtd+1,1):end));
RMinEtd = fliplr(IndMin(max(end-NEtd+1,1):end));
hrMaxEtd = h(RMaxEtd);
hrMinEtd = h(RMinEtd);
RMaxEtd = 2*SigLen - RMaxEtd;
RMinEtd = 2*SigLen - RMinEtd;
%计算信号的上包络线
Max_Env = interp1([LMaxEtd t(IndMax) RMaxEtd], [hlMaxEtd h(IndMax) hrMaxEtd], t, 'spline');
%计算信号的下包络线
Min_Env = interp1([LMinEtd t(IndMin) RMinEtd], [hlMinEtd h(IndMin) hrMinEtd], t, 'spline');
Mean_Env = (Max_Env +Min_Env)/2; %计算上下包络线的平均值
Preh = h;
h = h - Mean_Env;
alarm = 1.0e-08;
SD = sum (((Preh - h).^2)./(Preh.^2 + alarm));
[IndMax, IndMin] = ExtrPoint(h); %提取信号的极值点
[Index_zer] = ZeroPoint(h); %提取信号的零点
NExtr = length(IndMin) + length(IndMax);
NZero = length(Index_zer);
nLoop = nLoop+1;
end %提取到一个本征模分量
IMFNum = IMFNum + 1;
disp([num2str(IMFNum), 'IMFs have been obtained.']);
Imf = [Imf; h];
c = c - h;
[IndMax, IndMin] = ExtrPoint(c); %提取信号的极值点
[Index_zer] = ZeroPoint(c); %提取信号的零点
NExtr = length(IndMin) + length(IndMax);
NZero = length(Index_zer);
Bool = 1;
if((range(c)/range(Sig)) < 2e-4),
Bool = -1;
end
end
Imf = [Imf;c];
[n m ] = size(Imf);
xCor = [];
%选择本征模分量
norm_Sig = (Sig - mean(Sig)) / std(Sig);
for i = 1:n-1,
norm_Imf = (Imf(i,:)-mean(Imf(i,:))) / std(Imf(i,:));
Coef = xcorr(norm_Sig,norm_Imf) / SigLen;
xCor = [xCor max(abs(Coef))];
end
k = find(xCor > max(xCor)/8);
disp([num2str(length(k)),'IMFs have been selected.']);
Temp = zeros(length(k)+1, SigLen);
Temp1 = Sig;
for i = 1:length(k),
Temp(i,:) = Imf(k(i),:);
Temp1 = Temp1 -Imf(k(i),:);
end
Temp(length(k)+1,:) = Temp1; %最后一个为残差分量
Imf = Temp; |