MATLAB基于小波变换的语音信号去噪算法改进


概述

对传统的阈值估计方法和阈值函数进行改进,并通过比较传统算法和改进算法去噪后信噪比验证改进算法的有效性。

【参考文献】
范小龙,谢维成,蒋文波,李毅,黄小莉.一种平稳小波变换改进阈值函数的电能质量扰动信号去噪方法[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=10lgL1n=1L[x(n)y(n)]2L1n=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为所有的高频小波系数。

2.2 改进的阈值函数

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,k1+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小波基。

4. 改进算法去噪效果图

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('改进算法去噪效果图');

改进算法去噪效果图


  • 13
    点赞
  • 82
    收藏
    觉得还不错? 一键收藏
  • 16
    评论
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值