- 概述
- 0. 需要调用的子函数
- 0.1 Gnoisegen函数
- 0.2 snrr函数
- 1. 语音信号输入和加噪
- 1.1 语音信号输入
- 1.2 语音信号加噪
- 2. 改进算法
- 2.1 改进的阈值估计方法
- 2.2 改进的阈值函数
- 3. 改进算法有效性验证
- 4. 改进算法去噪效果图
概述
对传统的阈值估计方法和阈值函数进行改进,并通过比较传统算法和改进算法去噪后信噪比验证改进算法的有效性。
【参考文献】
范小龙,谢维成,蒋文波,李毅,黄小莉.一种平稳小波变换改进阈值函数的电能质量扰动信号去噪方法[J].电工技术学报,2016,31(14):219-226.
0. 需要调用的子函数 0.1 Gnoisegen函数
用于在语音信号上叠加高斯白噪声。
function [y,noise] = Gnoisegen(x,snr)%x是原始信号,y是加噪信号
noise=randn(size(x));
Nx=length(x);
signal_power=1/Nx*sum(x.*x);
noise_power=1/Nx*sum(noise.*noise);
noise_variance=signal_power/(10^(snr/10));
noise=sqrt(noise_variance/noise_power)*noise;
y=x+noise;
0.2 snrr函数
用于计算去噪后信噪比,以评价去噪性能。
S
N
R
=
10
l
g
1
L
∑
n
=
1
L
x
2
(
n
)
1
L
∑
n
=
1
L
[
x
(
n
)
−
y
(
n
)
]
2
\ SNR = 10lg\frac{\frac{1}{L}\sum_{n=1}^Lx^2(n)}{\frac{1}{L}\sum_{n=1}^L[x(n)-y(n)]^2}
SNR=10lgL1∑n=1L[x(n)−y(n)]2L1∑n=1Lx2(n)
式中,
x
(
n
)
x(n)
x(n)为原始语音信号,
y
(
n
)
y(n)
y(n)为去噪后的语音信号,
L
L
L为语音信号总采样点数。
function z=snrr(x,y)%x是原始信号,y是去噪后信号
y1=sum(x.^2);
y2=sum((y-x).^2);
z=10*log10((y1/y2));
end
1. 语音信号输入和加噪
1.1 语音信号输入
将待处理的wav语音文件拖入D盘中。
【注】 由于文章中不能插入文件,本文中处理的“test.wav”音频文件将另外作为资源上传。
[u,fs]=audioread('D:\test.wav');%声音获取函数audioread,采样率为fs
z=u.';
y=z(1,:);
y=y-mean(y);
y=y/max(abs(y));
sound(y,fs);%播放原始语音信号
1.2 语音信号加噪
语音信号加高斯白噪声。
[s,noise]=Gnoisegen(y,10);%加高斯白噪声,信噪比设置为10dB
sound(s,fs);%播放加噪语音信号
2. 改进算法
2.1 改进的阈值估计方法
采用阈值分层处理法,各分解尺度的阈值为:
λ
j
=
σ
2
l
g
(
k
j
)
l
n
(
1
+
j
)
\lambda_j=\frac{\sigma\sqrt{2lg(k_j)}}{ln(1+j)}
λj=ln(1+j)σ2lg(kj)
式中,
j
j
j为分解尺度,
k
j
k_j
kj为分解尺度为
j
j
j的高频小波系数的长度,
σ
\sigma
σ为所有高频小波系数的均方差:
σ
=
m
e
d
i
a
n
(
∣
c
D
∣
)
0.6745
\sigma=\frac{median(|cD|)}{0.6745}
σ=0.6745median(∣cD∣)
式中,
c
D
cD
cD为所有的高频小波系数。
d
^
j
,
k
=
{
d
j
,
k
−
λ
1
+
e
(
d
j
,
k
−
λ
)
2
a
−
λ
2
e
1
a
,
d
j
,
k
⩾
λ
0
,
∣
d
j
,
k
∣
<
λ
d
j
,
k
+
λ
1
+
e
(
−
d
j
,
k
−
λ
)
2
a
+
λ
2
e
1
a
,
d
j
,
k
⩽
−
λ
\hat d_{j,k}= \begin{cases} \d_{j,k}-\frac{\lambda}{1+e^{\frac{(d_{j,k}-\lambda)^2}{a}}}-\frac{\lambda}{2e^{\frac{1}{a}}}, & \text{$d_{j,k}\geqslant\lambda$} \[2ex] 0, & \text{$|d_{j,k}|\lt\lambda$} \[2ex] \d_{j,k}+\frac{\lambda}{1+e^{\frac{(-d_{j,k}-\lambda)^2}{a}}}+\frac{\lambda}{2e^{\frac{1}{a}}}, & \text{$d_{j,k}\leqslant-\lambda$} \end{cases}
d^j,k=⎩⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎪⎪⎪⎪⎧dj,k−1+ea(dj,k−λ)2λ−2ea1λ,0,dj,k+1+ea(−dj,k−λ)2λ+2ea1λ,dj,k⩾λ∣dj,k∣<λdj,k⩽−λ
式中,
d
j
,
k
d_{j,k}
dj,k为加噪语音信号的小波系数,
d
^
j
,
k
\hat d_{j,k}
d^j,k为加噪语音信号去噪处理后的小波系数,
λ
\lambda
λ为阈值,
a
a
a为调节因子,取值范围为
[
0
,
+
∞
)
[0,+\infty)
[0,+∞)。
调节a的值可以得到不同的阈值函数,a取
[
0
,
+
∞
)
[0,+\infty)
[0,+∞)时,阈值函数在硬阈值函数和软阈值函数之间波动。a=0时阈值函数等效于硬阈值函数,a→
+
∞
+\infty
+∞时等效于软阈值函数。
【注】 为实现a的自动最优选取,在程序中设置一个循环使a取遍
[
0
,
100
]
[0,100]
[0,100],间隔为0.1。
b=0;
e=[];
for a=0:0.1:100 %调节因子a的自动最优选取
b=b+1;
%5层分解
wname='sym4';%选取sym4小波基
lev=5;%分解层数设置为5
[c,l]=wavedec(s,lev,wname);%小波分解
a5=appcoef(c,l,wname,lev);%分解尺度为5的低频小波系数
d5=detcoef(c,l,5);%分解尺度为5的高频小波系数
d4=detcoef(c,l,4);%分解尺度为4的高频小波系数
d3=detcoef(c,l,3);%分解尺度为3的高频小波系数
d2=detcoef(c,l,2);%分解尺度为2的高频小波系数
d1=detcoef(c,l,1);%分解尺度为1的高频小波系数
cD=[d1,d2,d3,d4,d5];
sigma=median(abs(cD))/0.6745;%均方差
thr1=(sigma*sqrt(2*(log10(length(d1)))))/(log(1+1));%第一层阈值
for i=1:length(d1)
if(d1(i)>=thr1)
cD1(i)=d1(i)-thr1/(1+exp(((d1(i)-thr1).^2)/a))-thr1/(2*exp(1/a));%估计第一层小波系数
else if(abs(d1(i))<thr1)
cD1(i)=0;
else
cD1(i)=d1(i)+thr1/(1+exp(((-d1(i)-thr1).^2)/a))+thr1/(2*exp(1/a));
end
end
end
thr2=(sigma*sqrt(2*(log10(length(d2)))))/(log(2+1));%第二层阈值
for i=1:length(d2)
if(d2(i)>=thr2)
cD2(i)=d2(i)-thr2/(1+exp(((d2(i)-thr2).^2)/a))-thr2/(2*exp(1/a));%估计第二层小波系数
else if(abs(d2(i))<thr2)
cD2(i)=0;
else
cD2(i)=d2(i)+thr2/(1+exp(((-d2(i)-thr2).^2)/a))+thr2/(2*exp(1/a));
end
end
end
thr3=(sigma*sqrt(2*(log10(length(d3)))))/(log(3+1));%第三层阈值
for i=1:length(d3)
if(d3(i)>=thr3)
cD3(i)=d3(i)-thr3/(1+exp(((d3(i)-thr3).^2)/a))-thr3/(2*exp(1/a));%估计第三层小波系数
else if(abs(d3(i))<thr3)
cD3(i)=0;
else
cD3(i)=d3(i)+thr3/(1+exp(((-d3(i)-thr3).^2)/a))+thr3/(2*exp(1/a));
end
end
end
thr4=(sigma*sqrt(2*(log10(length(d4)))))/(log(4+1));%第四层阈值
for i=1:length(d4)
if(d4(i)>=thr4)
cD4(i)=d4(i)-thr4/(1+exp(((d4(i)-thr4).^2)/a))-thr4/(2*exp(1/a));%估计第四层小波系数
else if(abs(d4(i))<thr4)
cD4(i)=0;
else
cD4(i)=d4(i)+thr4/(1+exp(((-d4(i)-thr4).^2)/a))+thr4/(2*exp(1/a));
end
end
end
thr5=(sigma*sqrt(2*(log10(length(d5)))))/(log(5+1));%第五层阈值
for i=1:length(d5)
if(d5(i)>=thr5)
cD5(i)=d5(i)-thr5/(1+exp(((d5(i)-thr5).^2)/a))-thr5/(2*exp(1/a));%估计第五层小波系数
else if(abs(d5(i))<thr5)
cD5(i)=0;
else
cD5(i)=d5(i)+thr5/(1+exp(((-d5(i)-thr5).^2)/a))+thr5/(2*exp(1/a));
end
end
end
cd=[a5,cD5,cD4,cD3,cD2,cD1];
c=cd;
yhs=waverec(cd,l,wname);%小波重构
yhsx(b)=snrr(y,yhs);
e(b,:)=yhs;
end
[yhm,p]=max(yhsx);
fprintf('调节因子a取%.1f时去噪效果最好,去噪后信噪比为%4.4f\n',(p-1)/10,yhm);
ysm=e(p,:);%ysm即为改进算法去噪后的语音信号
sound(ysm,fs);%播放去噪后的语音信号
3. 改进算法有效性验证
为验证改进算法的有效性,另外用传统的去噪算法对语音信号进行去噪。阈值估计方法分别选取sqtwolog、rigrsure、heursure、minimaxi阈值,阈值函数分别选取软、硬阈值函数。
snrxn=snrr(y,s);
fprintf('原加噪信号信噪比:%4.4f\n',snrxn);
wavec='sym4';%选取sym4小波基
xdh1=wden(s,'sqtwolog','h','mln',5,wavec);
snrxdh1=snrr(y,xdh1);
fprintf('sqtwolog阈值+硬阈值函数去噪后信噪比:%4.4f\n',snrxdh1);
xds1=wden(s,'sqtwolog','s','mln',5,wavec);
snrxdh1=snrr(y,xds1);
fprintf('sqtwolog阈值+软阈值函数去噪后信噪比:%4.4f\n',snrxdh1);
xdh2=wden(s,'rigrsure','h','mln',5,wavec);
snrxdh2=snrr(y,xdh2);
fprintf('rigrsure阈值+硬阈值函数去噪后信噪比:%4.4f\n',snrxdh2);
xds2=wden(s,'rigrsure','s','mln',5,wavec);
snrxds2=snrr(y,xds2);
fprintf('rigrsure阈值+软阈值函数去噪后信噪比:%4.4f\n',snrxds2);
xdh3=wden(s,'heursure','h','mln',5,wavec);
snrxdh3=snrr(y,xdh3);
fprintf('heursure阈值+硬阈值函数去噪后信噪比:%4.4f\n',snrxdh3);
xds3=wden(s,'heursure','s','mln',5,wavec);
snrxds3=snrr(y,xds3);
fprintf('heursure阈值+软阈值函数去噪后信噪比:%4.4f\n',snrxds3);
xdh4=wden(s,'minimaxi','h','mln',5,wavec);
snrxdh4=snrr(y,xdh4);
fprintf('minimaxi阈值+硬阈值函数去噪后信噪比:%4.4f\n',snrxdh4);
xds4=wden(s,'minimaxi','s','mln',5,wavec);
snrxds4=snrr(y,xds4);
fprintf('minimaxi阈值+软阈值函数去噪后信噪比:%4.4f\n',snrxds4);
得到改进算法和传统算法去噪后的信噪比,加以比较:
改进算法去噪后的信噪比均大于传统算法去噪后的信噪比,此改进算法的有效性得以验证。
【注】 为控制变量,在用改进算法和传统算法进行去噪时,分解层数均选取为5,小波基均选取sym4小波基。
figure(1)
subplot(311);
plot(y,'k-');
axis([0,84720,-1,1]);
xlabel('采样点');
ylabel('幅值');
title('原始语音信号');
subplot(312);
plot(s,'k-');
axis([0,84720,-1,1]);
xlabel('采样点');
ylabel('幅值');
title('加噪语音信号');
subplot(313);
plot(ysm,'k-');
axis([0,84720,-1,1]);
xlabel('采样点');
ylabel('幅值');
title('改进算法去噪效果图');
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)