形态学滤波(开-闭)在信号降噪中的应用以及其Maltab程序

数学形态学的基本运算单元是腐蚀和膨胀,很多高级的形态学算法均是以这两种原始运算单元作为基础的。

设原始信号为x(n),其中(n =1,2,…,N);定义结构元素为g(m),其中(=1,2,…,M;且NM)。

定义x(n)关于g(m)的腐蚀和膨胀操作为:

 

x(n)关于g(m)的的开运算和闭运算操作分别定义为:

 

 

形态学开闭运算是一对对偶变换,形态开运算可以抑制信号中的正脉冲噪声,而形态闭运算可以抑制信号中的负脉冲噪声。由于形态开、闭运算存在统计偏倚现象,导致单独使用他们的滤波效果并不是很好,因此通常采用开_闭或者闭_开组合滤波方法。

 

形态学滤波的效果也取决于结构元素的尺寸和形状,一般是根据信号的特点选取结构元素。

这里使用扁平状结构元素g(k)=[1,1,1,1,1]以及正弦结构b(k)=H×[0,0.0711,1,0.0711,0],其中k=0,1,2,3,4和H为min(x(n));采用开_闭以及闭_开组合滤波器对加速度信号进行处理,原始信号以及滤波后的信号如下如图所示。

 形态学滤波(开-闭)在信号降噪中的应用以及其Maltab程序_第1张图片形态学滤波(开-闭)在信号降噪中的应用以及其Maltab程序_第2张图片

形态学开闭处理,可以消除信号中的脉冲噪声,但需要选择较好的结构元素。

形态学滤波算法的Matlab程序如下所示:

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%形态学滤波
g=[1 1 1 1 1];
op=1;
a1=fushi2(a,g,op);
a1=pengzhang2(a1,g,op);
a1=pengzhang2(a1,g,op);
a1=fushi2(a1,g,op);

H=min(a);
g=H*[0 0.0711 1 0.0711 0];
a2=fushi2(a,g,op);
a2=pengzhang2(a2,g,op);
a2=pengzhang2(a2,g,op);
a2=fushi2(a2,g,op);

subplot(2,1,1)
plot(t,a1)
xlabel('时间/s','fontsize',10.5)
ylabel('加速度/m·s^{-2}','fontsize',10.5)
l1=legend('扁平型结构元素滤波后的加速度信号');
set(l1,'fontsize',10.5)
axis([0 100 0.5 3.5])
 
subplot(2,1,2)
plot(t,a2)
xlabel('时间/s','fontsize',10.5)
ylabel('加速度/m·s^{-2}','fontsize',10.5)
l1=legend('正弦型结构元素滤波后的加速度信号');
set(l1,'fontsize',10.5)
axis([0 100 0.5 3.5])

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

形态学膨胀处理函数(来源于网上!):

function d=pengzhang2(dat,g,op)
%op:0--g的原点在开始点,1--g的原点在中心点(要求g长度为奇数),2--g的原点在末点;目前只支持此3种
len = length(dat);
len_g = length(g);

switch op
    case 1,
    org_piont = ceil(len_g/2);
    case 2,
      org_piont =  len_g;
  otherwise,
    org_piont = 1;
end

for i=1:len
    dtmp(i) = dat(i);
     for j=1:len_g
         if (i-org_piont+j) >= 1 && (i-org_piont+j) <=len
             tmp = dat(i-org_piont+j) + g(j);
           if tmp > dtmp(i)
               dtmp(i) = tmp;
           end
       end
    end
end

 d = dtmp;

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

形态学腐蚀处理函数(来源于网上!):

function d=fushi2(dat,g,op)
%op:0--g的原点在开始点,1--g的原点在中心点(要求g长度为奇数),2--g的原点在末点;目前只支持此3种

len = length(dat);
len_g = length(g);

switch op
    case 1,
    org_piont = ceil(len_g/2);
    case 2,
      org_piont =  len_g;
  otherwise,
    org_piont = 1;

end

for i=1:len
    dtmp(i) = dat(i);
     for j=1:len_g
         if (i-org_piont+j) >= 1 && (i-org_piont+j) <=len
             tmp = dat(i-org_piont+j) - g(j);
           if tmp < dtmp(i)
               dtmp(i) = tmp;
           end
       end
    end
end

 d = dtmp;

 

你可能感兴趣的:(信号处理)