最近要尝试使用小波对一组信号信号进行滤波,但由于这组信号采自不同环境下(受噪声影响大小不同),使用同一种小波基和参数设定总会导致出现一类信号效果不佳,故尝试先对信号进行一定标准的分类,再分别加以不同的处理方法。
由于做的时候真是对小波变换的数学基础一窍不通,也不知道到底是因为什么原因导致了滤波效果不佳,也不知道该怎么消除其影响,就只能基于自己的猜想和尝试了,具体过程如下:
本次实验选用的小波基是sym6小波,进行5层小波分解,其滤波效果较好,对于手上的待处理信号能够在滤去噪声和保留原信号上有一个较好的平衡。
由于待处理信号受噪声的影响相差较大,直接使用小波滤波处理虽可较为完整地保存下原带噪信号的特征和轮廓,但对于一些受噪声影响较大的信号的滤波效果并不明显,从而对于信号整体的滤波效果并不是很好。
而通过观察发现,经过小波分解的信号中低频的近似分量对于信号特征有较为完整的保存,噪声成分较少,故本文尝试通过设定一种标准对信号进行筛选,在对受噪声影响较大的原信号的处理中使用保留信号经小波分解后位于低频的近似分量进行重构以获得噪声较少的滤波效果。
试采取对信号进行快速傅里叶变换(FFT),从频域对其进行处理,经过对频域图和相应统计信息的观察和分析,可猜想导致两种处理方法效果不同的原因可能为信号的频域分布较为集中,从而直接影响了自适应阈值法对于高频噪声的滤去效果。因此可尝试对信号频域的能量分布进行统计分析来确定分组依据。
本文对原信号进行3层小波包分解(即n = 3,其实可根据情况再进行调整),将其划分为8个频段(2^n),其中信号中的大部分有效信息都存在于低频,故尝试设定表达式以分析信号的能量分布情况。
具体设定如下:
其中pEnergy为第i个频段中能量占总能量的比例。
接下来对pEnergy序列求解得到标准差STD_ENERGY,作为标记该信号的值。由于pEnergy是各频段占总能量的能量比,故可以不用做归一化处理且不受信号总能量的影响,易知STD_ENERGY的值越大,信号能量在频域上越分散,也应当更易区分和滤去,之后通过多次观察和实验,确定一个合适的阈值threshold,作为区分两类信号的值。
处理流程:
1. 调用wavedec函数对原信号进行小波基为sym6的5层小波分解,得到第五层近似系数CD5和5层细节系数CA1-CA5,存放在列向量C中
2. 计算得到pEnergy序列的标准差STD_ENERGY,与设定好的阈值stdThreshold进行对比,若STD_ENERGY > stdThreshold,则使用A方法,反之则使用B方法
A. 调用wthresh函数对每层信号进行自适应阈值滤波处理,滤去噪声后进行小波重构得到滤波后信号
B. 对列向量C中的高频细节信号CA1-CA4进行置零处理,再将置零后的CA1Z-CA4Z与CD5,CA5组合为新的列向量FC,再对它进行基于5层sym6小波的分层自适应阈值滤波处理。
3. 滤波结束,输出结果
如果哪里有问题或者什么建议的话,希望诸位能够指出来,非常感谢!!!Matlab代码如下
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%滤波%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%小波变换和分层处理%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
[C,L] = wavedec(sample,5,'sym6');%对原信号进行sym小波基的5层分解
%从C中分离出每层的小波系数
CD5 = C(1:L(1));
CA5 = C((L(1)+1):(L(1)+L(2)));
CA4 = C((sum(L(1:2))+1):sum(L(1:3)));
CA3 = C((sum(L(1:3))+1):sum(L(1:4)));
CA2 = C((sum(L(1:4))+1):sum(L(1:5)));
CA1 = C((sum(L(1:5))+1):sum(L(1:6)));
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%滤波处理%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
[THR1,SORH,KEEPAPP]=ddencmp('den','wv',CD5);
C1f = wthresh(CD5,SORH,THR1);
[THR2,SORH,KEEPAPP]=ddencmp('den','wv',CA5);
C2f = wthresh(CA5,SORH,THR2);
[THR3,SORH,KEEPAPP]=ddencmp('den','wv',CA4);
C3f = wthresh(CA4,SORH,THR3);
[THR4,SORH,KEEPAPP]=ddencmp('den','wv',CA3);
C4f = wthresh(CA3,SORH,THR4);
[THR5,SORH,KEEPAPP]=ddencmp('den','wv',CA2);
C5f = wthresh(CA2,SORH,THR5);
[THR6,SORH,KEEPAPP]=ddencmp('den','wv',CA1);
C6f = wthresh(CA1,SORH,THR6);
FC=[C1f;C2f;C3f;C4f;C5f;C6f]; %分层进行自适应阈值滤波
s = waverec(FC,L,'sym6'); %小波重构
ZC3 = zeros(length(CA4),1); %对分层中的高频系数置0
ZC4 = zeros(length(CA3),1);
ZC5 = zeros(length(CA2),1);
ZC6 = zeros(length(CA1),1);
FC2 = [CD5;CA5;ZC3;ZC4;ZC5;ZC6];%滤去高频段的分层系数
s2s = waverec(FC2,L,'sym6');
[c2,l2] = wavedec(s2s,5,'sym6');
[THR2,NKEEP]=wdcbm(c2,l2,3);
[s2,CXC,LXC,PERF,PERFL2]=wdencmp('lvd',c2,l2,'sym6',5,THR2,'s');%对合成信号再进行5层sym6小波滤波
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%滤波结束%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%频带能量分布计算%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
wpname='sym6';
n=3;
wpt1=wpdec(sample,n,wpname); %对数据进行小波包分解,分为8个频段
for i=1:2^n %wpcoef(wpt1,[n,i-1])是求第n层第i个节点的系数
Energy(i)=norm(wpcoef(wpt1,[n,i-1]),2);%求第i个节点的平方和表示频带能量
end
Energy_total=sum(Energy);%求总能量
for i=1:2^n
pEnergy(i)= Energy(i)/Energy_total;%求每个节点的能量占总能量的比值
end
%小波包分解的向量中元素顺序并非按频率由低到高排列,故进行交换
[pEnergy(4) pEnergy(3)] = deal(pEnergy(3),pEnergy(4));
[pEnergy(7) pEnergy(5)] = deal(pEnergy(5),pEnergy(7));
[pEnergy(8) pEnergy(6)] = deal(pEnergy(6),pEnergy(8));
[pEnergy(8) pEnergy(7)] = deal(pEnergy(7),pEnergy(8));
% JUDGE_ENERGY = 0;
% for i = 1:8
% JUDGE_ENERGY = JUDGE_ENERGY + i^2*pEnergy(i);%得出8个频段能量的分布(平方和)
% end
STD_ENERGY = std(pEnergy);%求解频段序列的标准差
STD_ENERGY