圣经里的菜刀 发表于 2014-6-14 11:29

关于Hilbert谱的一些问题

大家好,我刚开始接触HHT,在做些练习,用HHT画出来的Hilbert谱的频率范围是0到1,这个结果肯定不对,但是不知道什么原因,也不知道该怎么修改,希望大神指点,谢谢。

shuihai707 发表于 2014-6-15 20:46

程序贴出来,图贴出来,用事实说话。

圣经里的菜刀 发表于 2014-6-16 16:26

shuihai707 发表于 2014-6-15 20:46
程序贴出来,图贴出来,用事实说话。

嗯嗯好的,谢谢指点,我试着把程序和图贴出来,用的褚福磊的机械故障诊断中的现代信号处理方法这本书里的程序

圣经里的菜刀 发表于 2014-6-16 16:26

shuihai707 发表于 2014-6-15 20:46
程序贴出来,图贴出来,用事实说话。

function = HHT(Sig),%计算HHT的主程序
if(nargin <1),
    error('At least one input is needed!');
end
Imf = Emd(Sig'); %对信号进行经验模式分解
= size(Imf);
= size(Imf);
t = 1: SigLen;
HHSpectrum = zeros(max(1,nImf-1), SigLen);
AmpSpectrum = zeros(max(1, nImf - 1), SigLen);

for k = 1:nImf - 1,
    Imf0 = real(Imf(k,:));
    = InstFreq(Imf0);
    HHSpectrum(k,:) = freq';
    AmpSpectrum(k,:) = Amp';
end

%组合所有本征模分量的瞬时频率和瞬时功率为Hilbert谱

MaxFreq = max(max(HHSpectrum));
MaxFreq = ceil(MaxFreq/0.5)*0.5;
NumFreq = 128;
freq = linspace(0,MaxFreq,NumFreq);
Spectrum = zeros(NumFreq,SigLen);
Temp = HHSpectrum;
Temp = min(round((Temp/MaxFreq)* NumFreq)+1, NumFreq);
for k = 1:nImf - 1,
    for n = 1:SigLen,
      Spectrum(Temp(k,n),n) = Spectrum(Temp(k,n),n) + AmpSpectrum(k,n);
    end
end
%显示信号的Hilbert谱
clf;
mesh(t, freq, Spectrum);
colormap jet;
axis();
shading interp;
title('Hilbert-Huang spectrum');
ylabel('Frequency');
xlabel('Time');

圣经里的菜刀 发表于 2014-6-16 16:28

shuihai707 发表于 2014-6-15 20:46
程序贴出来,图贴出来,用事实说话。

function = 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;
= ExtrPoint(c);       %提取信号的极值点:极大值点和极小值点
= 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(, , t, 'spline');
%计算信号的下包络线
    Min_Env = interp1(, , 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));
    = ExtrPoint(h);   %提取信号的极值点
    = ZeroPoint(h);          %提取信号的零点
    NExtr = length(IndMin) + length(IndMax);
    NZero = length(Index_zer);
    nLoop = nLoop+1;
end   %提取到一个本征模分量
IMFNum = IMFNum + 1;
disp();
Imf = ;
c = c - h;
= ExtrPoint(c);         %提取信号的极值点
= 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 = ;
= 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 = ;
end
k = find(xCor > max(xCor)/8);
disp();
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;

圣经里的菜刀 发表于 2014-6-16 16:29

shuihai707 发表于 2014-6-15 20:46
程序贴出来,图贴出来,用事实说话。

function = ExtrPoint(Sig);      %提取信号的极大值和极小值点

if(nargin == 0)
    error('At least one input is required');
end
SigLen = length(Sig);
DSig = diff(Sig);
DSig1 = DSig(1:end - 1);
DSig2 = DSig(2: end);
Pos_min = find(DSig1.*DSig2<0 & DSig1<0) + 1;
Pos_max = find(DSig1.*DSig2<0 &DSig1>0) + 1;
Pos_max = sort();
Pos_min = sort()

圣经里的菜刀 发表于 2014-6-16 16:30

function = ZeroPoint(Sig);   %提取信号的过零点
if(nargin == 0)
    error('At least one input is required');
end
SigLen = length(Sig);
s1 = Sig(1:SigLen-1);
s2 = Sig(2:SigLen);
PZero = find(s1.*s2 <0);
IndZero = find( Sig == 0);
if(length(IndZero) > 0),
    zero = find(Sig ==0);
    DZero = diff();
    LZero = find(DZero == 1);
    RZero = find(DZero ==-1) - 1;
    IndZero = round((LZero + RZero) / 2);
    PZero = sort();
end

shuihai707 发表于 2014-6-17 18:28

看程序太累,论坛有现成的主流程序,法国人的EMD,自己用用试试,有问题再提问吧。

圣经里的菜刀 发表于 2014-6-18 19:43

shuihai707 发表于 2014-6-17 18:28
看程序太累,论坛有现成的主流程序,法国人的EMD,自己用用试试,有问题再提问吧。

嗯嗯,非常感谢,我找找那个程序试试
页: [1]
查看完整版本: 关于Hilbert谱的一些问题