数学形态学的基本运算单元是腐蚀和膨胀,很多高级的形态学算法均是以这两种原始运算单元作为基础的。
设原始信号为x(n),其中(n =1,2,…,N);定义结构元素为g(m),其中(m =1,2,…,M;且N≥M)。
定义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));采用开_闭以及闭_开组合滤波器对加速度信号进行处理,原始信号以及滤波后的信号如下如图所示。
形态学开闭处理,可以消除信号中的脉冲噪声,但需要选择较好的结构元素。
形态学滤波算法的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;