单通道语音增强之维纳滤波(一)

1.1 维纳滤波概况

  维纳滤波算法,最早起源于第二次世界大战期间,为解决军事上对空射击的控制问题,由数学家Norbert Wiener提出,主要用于从带噪的观测信号中提取出所需要的干净信号。维纳滤波算法至今已有近80年的历史,虽然古老,但是其思想一直延续至今,并得到了不断的完善和优化。维纳滤波算法的本质就是从噪声中提取信号的过滤和预测的方法,并以估计的结果与信号的真值间误差的最小均方值作为最佳准则。因此,维纳滤波器是统计意义上的最优滤波器,或者说是波形的最优线性估计器。此外,维纳滤波算法以其较小的运算复杂度和不错的降噪性能优势,在语音增强的工程领域一直发挥着很重要的作用。

  经过了几十年的发展,维纳滤波算法的种类和变体很多,其中比较实用,且应用较广的,算是频域的维纳滤波算法,而频域的维纳滤波算法中的变体、优化形式又十分丰富,也使得维纳滤波算法在语音增强的学术和工程领域都占有一席之地。这些多样的维纳滤波算法的性能,各有利弊,有好有坏,因此也不能说具体哪种维纳滤波更好。但是,发展到现在,基于维纳滤波的卡尔曼滤波算是这其中的佼佼者,它通过引入卡尔曼信息,更适应于动态系统非平稳条件下和最小均方误差意义下的最优估计,所以在这几年学术研究中比较热门,关于这方面的论文也比较多。

1.2 维纳滤波算法的分类

维纳滤波算法的分类

  根据维纳滤波算法应用域的不同,可以分为:时域的维纳滤波和频域的维纳滤波。而根据是否利用未来的信息来估计当前的值,又可将其分成因果系统和非因果系统,于是所有的维纳滤波算法便可以划分成四大类:因果时域维纳滤波器、非因果时域维纳滤波器、因果频域维纳滤波器和非因果频域维纳滤波器。

  对于因果的系统,只需要用到过去和当前的值来估计当前的期望值,而在非因果系统中,还需要用到未来的信息来估计当前的期望值,因此因果系统的维纳滤波和非因果系统的维纳滤波各自对应的增益函数解的形式也是不同的。并且由于非因果的维纳滤波器,可以运用未来的信息,所以效果较好;而因果的维纳滤波器不能利用“未来”的值,所以效果相比之下会差一点。另外,在工程应用中,频域的维纳滤波算法使用地更加广泛,因为其更容易实现,性能也相对更好;并且在学术领域,对于频域维纳滤波的研究也比较丰富,所以下面将着重介绍频域的维纳滤波算法。

  首先,对于因果解的频域维纳滤波,其增益函数的表达形式如下:

这里写图片描述

因为是因果系统,也就意味着上述增益函数的求解是物理可实现的,也就是说,我们不需要未来的信息,只是利用当前和过去的信息,便可以直接求得上述的维纳滤波器的增益函数值。但是,由于上述解的形式过于复杂,求解起来过于麻烦,所以因果的频域维纳滤波应用的并不是很广泛。

  而对于非因果解的频域维纳滤波器,其增益函数的表达形式如下:

这里写图片描述

进一步地,如果假设语音和噪声是非相关的,我们有:

这里写图片描述

其中这里写图片描述为纯净语音的功率谱,这里写图片描述为噪声的功率谱;此外,因为是非因果系统,也就意味着上述增益函数的求解是物理不可实现的,主要原因在于,我们无法获得未来的信息,然后利用上述公式,求得其增益函数的准确解,这里的“未来信息”我们可以理解为:需要用到未来的信息和当前、过去的信息一起来确定当前的纯净信号功率谱这里写图片描述和噪声功率谱这里写图片描述。因此,如何利用因果的方法(仅用当前和过去帧的输入)来解决这里写图片描述这里写图片描述的求解问题,成为了实现这类非因果频域维纳滤波器最重要的问题。接下来,就介绍几种用因果的方法去近似逼近这类非因果解的方法。

这里写图片描述

  利用因果的方法去逼近求解非因果的增益函数,主要方法有两大类:迭代的方法和非迭代的方法。而为了进一步的提升维纳滤波的性能,又可以对这两种方法施加一定的约束,于是便有了四大类求解方法,分别为:无约束的迭代维纳滤波、有约束的迭代维纳滤波、无约束的非迭代维纳滤波和有约束的非迭代维纳滤波。关于这四类非因果的频域维纳滤波方法的具体介绍,会在后面的维纳滤波专题中详细介绍。
  最后,必须提及的是,维纳滤波器是在一维平稳状态下的线性最优估计器,也就是说,只有输入信号是统计意义上是平稳信号时,其增益函数解才是最优解。并且由于是线性估计器,所以也就意味着其在解决一些复杂的非线性问题时(例如,噪音污染问题)不是最优的。再加上平时我们所使用的维纳滤波器,大多都是用因果的方法去近似非因果的增益函数表达式,所以这又进一步降低了其最优解的精确度。但是,不得不说,虽然受到这些理想假设和近似条件的限制,用因果方法实现的非因果频域维纳滤波器,在很多情况下的效果还是十分显著地。

  • 5
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是使用matlab实现语音增强维纳滤波的代码: ```matlab % 读取音频文件 [x, fs] = audioread('filename.wav'); % 设置参数 win = 256; % 窗口大小 hop = win/2; % 帧移 nfft = win; % FFT点数 alpha = 0.99; % 平滑系数 beta = 2; % 维纳滤波参数 % 分帧 frames = enframe(x, win, hop); % 加窗 w = hamming(win); frames_w = frames .* repmat(w', size(frames, 1), 1); % FFT spec = fft(frames_w, nfft, 2); % 幅度谱 mag_spec = abs(spec); % 相位谱 phase_spec = angle(spec); % 计算噪声幅度谱 noise_mag_spec = mean(mag_spec(:, 1:5), 2); % 平滑噪声幅度谱 smooth_noise_mag_spec = noise_mag_spec; for i = 2:size(mag_spec, 2) smooth_noise_mag_spec = alpha * smooth_noise_mag_spec + (1-alpha) * mag_spec(:, i-1); end % 计算信噪比 snr = mag_spec ./ repmat(smooth_noise_mag_spec, 1, size(mag_spec, 2)); % 维纳滤波 denoise_spec = mag_spec .* (snr./(1+snr).^beta); % 合成 denoise_frames = real(ifft(denoise_spec, nfft, 2)); denoise_frames = denoise_frames(:, 1:win-hop); denoise_signal = overlapadd(denoise_frames, hop); % 播放 sound(denoise_signal, fs); ``` 其中,`filename.wav`是需要进行语音增强的音频文件名,`win`是窗口大小,`hop`是帧移,`nfft`是FFT点数,`alpha`是平滑系数,`beta`是维纳滤波参数。代码中使用了`enframe`函数将音频信号分帧,使用了`hamming`窗进行加窗,使用了`fft`函数进行FFT变换,使用了`abs`函数计算幅度谱,使用了`angle`函数计算相位谱,使用了`mean`函数计算噪声幅度谱,使用了循环计算平滑噪声幅度谱,使用了`repmat`函数将噪声幅度谱扩展到与信号幅度谱相同的大小,使用了`./`和`.^`运算符计算信噪比和维纳滤波结果,使用了`ifft`函数进行IFFT变换,使用了`overlapadd`函数将分帧结果合成为语音信号。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值