使用卡尔曼滤波器进行回声消除

回声消除的基本原理就是基于自适应滤波器来消除回声,而目前流行的方法基本上都是基于NLMS自适应滤波器算法优化而来,有收敛速度慢、回声消除能力不强、无法快速跟踪回声路径变化等问题。而基于卡尔曼滤波的回声消除,在各方面则要比NLMS算法强得多,能够极大提升回声消除的效果。因此这篇文章简单介绍下怎样使用卡尔曼滤波来进行回声消除。

lms filter

回声消除的原理就是通过远端参考信号\boldsymbol x\hat{\boldsymbol h}进行卷积得到估计的回声信号\hat {\boldsymbol y}​,然后从近端麦克风信号\boldsymbol d中减去回声信号\hat {\boldsymbol y}​得到回声消除后的信号\boldsymbol e,lms自适应滤波器就是通过随机梯度下降最小化误差信号e(n)的均方误差,来估计声学回声路径\hat{\boldsymbol h}逼近真实回声路径\boldsymbol h

lms滤波器算法步骤如下:
假设真实的回声路径\boldsymbol h长度为L
\boldsymbol h = [h_0 h_1 h_2 h_3...h_{L-1}]^T
在n时刻输入的远端参考信号为:
\boldsymbol x(n) = [x(n) x(n-1) x(n-2)... x(n-L+1)]^T
估计的回声为:
\hat y(n) = \boldsymbol x^T(n).\hat{\boldsymbol h}
估计的回声和近端信号间的误差为:
e(n) = d(n) - \hat y(n)
系数更新公式:
\hat{\boldsymbol h}_{n+1} = \hat{\boldsymbol h}_n + 2 \mu \boldsymbol x(n)e^* (n)

kalman filter

背景

卡尔曼滤波是一种利用线性系统状态方程,通过系统输入输出观测数据,对系统状态进行最优估计的算法。由于观测数据中包括系统中的噪声和干扰的影响,所以最优估计也可看作是滤波过程。
简单来说就是系统利用前一时刻的状态,当前的输入值和可能的测量值来得到当前时刻下的状态的最优估计,因此卡尔曼滤波器和自适应滤波器一样都是递归算法。
他的广泛应用已经超过30年,包括机器人导航,控制,传感器数据融合甚至在军事方面的雷达系统以及导弹追踪等等。近来更被应用于计算机图像处理,例如头脸识别,图像分割,图像边缘检测等等。

由于关于怎样使用卡尔曼滤波器做回声消除已经有前辈做出来了,所以为了可以更加容易的理解卡尔曼滤波器,只是应用形象的描述方法来讲解,然后简单介绍卡尔曼滤波器公式,推导就省略了。

最简单的例子

考虑你正在驾驶一辆直线行驶的小车,你通过油门深浅控制小车前进,车上有速度计可以测量你的车目前的速度,但是由于精度,传感器误差等影响,测量值并不精确,所以你需要解决的问题是:如何精确测量小车在某个时刻的真实速度。

我们定义:
\mu_ n是n时刻系统的输入,即小车的油门
y_n​是n时刻系统的测量值,即小车的速度计的速度
x_n是n时刻系统的状态,即小车的真实速度
我们将小车看作一个系统,示意图如下:

定义\hat x_n​是n时刻估计的系统的状态,那我们的目标就是精确估计\hat x_n​,让\hat x_n​和x_n​之间的误差最小
首先建立输入与状态之间的模型,假设x_n跟当前的油门输入\mu_ n和上一个时刻我们计算得到的小车速度\hat x_{n-1}​有关:
x_n = Ax_{n-1} + B\mu_n + \omega_n
A表示上个状态与当前状态的关系,B表示当前输入与当前状态的关系,\hat x_n就是我们估计得到的n时刻小车速度,但很不幸,真实的场景下的小车速度肯定会受到比如风速、摩擦力等影响导致真实速度与估计速度出现偏差,所以我们的模型加上了噪声项\omega_n​,称为过程噪声。
因为我们无法对噪声进行精确建模,所以我们的估计值是不考虑噪声的影响的:
\hat x_n^- = A\hat x_{n-1} + B\mu_n
这里\hat x_n^-是我们通过上一个状态以及模型估算出来的当前状态,我们叫它先验状态估计
很明显这个状态是不精确的,我们还需要利用到测量值y_n,我们建立状态与测量值之间的模型,然后利用当前状态估计测量值,这样我们就能通过测量值知道我们的状态是否估计准确:
y_n = Cx_n + \upsilon_n
C表示当前状态与当前测量值之间的关系,在这个例子测量值和状态都是小车的速度,所以这里C表示测量速度和估计速度间的转换关系,但因为测量值也会有误差,所以我们的测量模型也加上了噪声项\upsilon_n​,称为测量噪声。
通过这个模型,我们又有另一种方式去计算小车状态了:
\hat x_{n_{mea}} = C^{-}y_n

好了,现在用了两种方式来估计小车状态,分别是\hat x_n^-​和\hat x_{n_{mea}}​​,因为这两种方式估计都有误差,所以我们可以结合这两种方式来精确估计小车状态,那么卡尔曼滤波器就可以派上用场了,它结合这两条信息给出最优的状态估计,示意图如下:

接下来我们就可以对卡尔曼滤波器原理做一个概述了:
卡尔曼滤波器基于以下假设,然后不断的利用上一个状态迭代估计当前状态:
1、状态转移模型,控制模型和观测模型是线性的
2、过程噪声和观测噪声假设为零均值高斯噪声

我们怎么对两个状态的估计结果相结合呢,很自然的可以想到对两者的结果进行加权:
\hat x_n = \hat x_n^- + K_n(\hat x_{n_{mea}} - \hat x_n^-)
当K=0时,\hat x_n = \hat x_n^-
当K=1时,\hat x_n = \hat x_{n_{mea}}

所以卡尔曼滤波器的目标就是寻找K,使\hat x_nx_n之间的误差最小,定义状态的误差为:
e_n = x_n - \hat x_n
将误差也看做高斯分布,对应的协方差矩阵为:
P_n = E[e_ne_n^{T}]
为了使估计的状态\hat x_n最优,目标是最小化后验状态误差的协方差P_n

推导步骤就省略不写了,对于我们使用卡尔曼滤波器的话只需要知道其思想原理以及怎么使用就可以了,最终我们得到卡尔曼滤波器的公式如下:

时间更新方程:
1、\hat x_n^- = A \hat x_{n-1} + B\mu_n
2、P_n^- = AP_{n-1}A^T + Q
状态更新方程:
3、K_n = [P_n^-C^T][CP_n^-C^T+R]^{-1}
4、\hat x_n = \hat x_n^- + K_n(y_n - C \hat x_n^-)
5、P_n = (I-K_nC)P_n^-

其中:
\hat x_n^-:是n时刻的先验状态估计值
\hat x_{n-1}​:n-1时刻的后验状态估计值
A:n-1时刻状态到n时刻状态的转移矩阵
\mu_n:n时刻的输入
B:输入转换为状态的矩阵
P_n^-:n时刻先验状态估计的误差协方差
P_{n-1}:n-1时刻后验状态估计的误差协方差
Q:系统的过程噪声\omega_n的协方差
K_n:卡尔曼增益
C:状态到测量的转换矩阵
R:测量噪声\upsilon_n​的的协方差
\hat x_n​:n时刻的后验状态估计值
y_n​:观测值
P_n​:n时刻后验状态估计的误差协方差
I:单位矩阵

使用卡尔曼滤波器回声消除

很显然,在回声消除系统中,回声路径就是我们需要估计的系统状态,因此我们可以利用卡尔曼滤波器来对回声路径进行估计。
我们令n时刻参考信号为x(n),近端录制信号为y(n),n时刻的误差输出为e(n),n时刻卡尔曼滤波器的状态为\hat h(n)
一般我们认为回声路径是一个稳定的非常缓慢变化的过程,遵循一阶马尔可夫模型。因此,对比卡尔曼滤波器的状态更新方程,其中A为单位矩阵,没有对回声路径的控制项,所以B\mu_n​可以忽略,这样状态更新方程可以定义为:
\hat h(n) = \hat h(n-1) + K(n)[y(n) - C \hat h(n-1)]
其中y(n) - C \hat h(n-1)就是卡尔曼滤波器测量误差,即:
\hat h(n) = \hat h(n-1) + K(n)e(n)

我们得到到卡尔曼滤波器回声消除的更新公式如下:
e(n) = y(n) - x(n)^T\hat h(n-1)
P(n)^- = P(n-1) + Q
K(n) = [P(n)^-x(n)][x(n)P(n)^-x(n)^T+R]^{-1}
\hat h(n) = \hat h(n-1) + K(n)e(n)
P(n) = (I-K(n)X(n)^T)P(n)^-

要使用卡尔曼滤波回声消除还需要估计两个噪声协方差矩阵Q 和R,一般说来也都是根据输入输出参数以及滤波器参数来进行估计,这里就不展开讲了

总结

lms自适应滤波器是通过最小化近端信号与误差信号的均方误差,通过随机梯度下降来达到估计回声路径的目的,所以当近端有双讲时,会使滤波器迅速发散,步长设置小,误差较小,但收敛慢,步长设置大 ,收敛快,但误差大。
而kalman滤波器的目标是最小化状态误差的协方差,可以分析,在双讲时,意味着测量误差很大,这时候K就很小,状态的估计值更倾向于估计出来的结果,即滤波器系数不更新,因此双讲时滤波器不易发散,当测量误差小时,K很大,状态的估计值更倾向于测量值,所以很快就可以收敛。所以同时兼顾了快速跟踪以及双讲,要比基于lms的自适应滤波器的效果好很多

效果对比

在这里我对比3个自适应滤波器的回声消除效果,AEC3的自适应滤波器、滴滴开源的子带ipnlms滤波器、以及我自己实现的卡尔曼滤波器

1、线性回声的语料:

远端信号近端信号
AEC3滴滴卡尔曼滤波

 2、在iphone上录制的真实语料:

远端信号近端信号
AEC3滴滴卡尔曼滤波

在回声是线性的情况下,AEC3自适应滤波器约能消除15dB回声 ,滴滴IPNLMS约能消除21dB回声, 而卡尔曼滤波可以消除高达45dB,基本可以完全消除线性回声

在iphone真实录制的语料下,回声有非线性失真,因此相比线性回声,回声消除能力都有所下降,AEC3自适应滤波器仅能消除约4dB回声,滴滴IPNLMS约能消除8dB回声,而卡尔曼滤波还能消除高达21dB回声

 上述自适应滤波器对比测试语料放在:https://github.com/ewan-xu/AecSamples

kalman滤波器简单实现

在这里贴上使用python实现一个简单的时域卡尔曼自适应滤波,代码如下:

import numpy as np
import librosa

def kalman_filter(x, d, M = 64):
    length = min(len(x),len(d))
    beta = 0.9
    R = 1e-2
    Q = 1e-5
    H = np.zeros(M)
    P = np.full(M,Q)
    y = np.zeros(length-M)
    e = np.zeros(length-M)
    
    for n in range(length-M):
        x_n = x[n:n+M][::-1]
        d_n = d[n] 
        y_n = np.dot(H, x_n.T)
        e_n = d_n - y_n
        R = beta*R + (1-beta)*(e_n**2)
        Pn = P + Q
        K = Pn*x_n.T/(x_n*Pn*x_n.T + R)
        H = H + K*e_n
        P = (1.0 - K*x_n.T)*Pn
        y[n] = y_n
        e[n] = e_n
    return y, e
    
if __name__ == "__main__":
    x = librosa.core.load('ref.wav',sr=8000,mono=True)[0]
    d = librosa.core.load('rec.wav',sr=8000,mono=True)[0]

    M = 64
    y, e = kalman_filter(x,d,M)

    librosa.output.write_wav('estimate.wav',y,sr=8000)
    librosa.output.write_wav('error.wav',e,sr=8000)

还有基于频域的卡尔曼滤波,以及其他的自适应滤波器,感兴趣的同学可以去我的repository中查看: https://github.com/ewan-xu/pyaec

有任何疑问,欢迎加微信交流:xu19315519614

  • 11
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
### 回答1: 回声消除是指通过信号处理技术,将回声音频信号从原始音频信号中减去或减弱的过程。在实际应用中,回声源常常是由于信号在传输过程中受到反射或折射等因素的影响产生的。回声消除技术主要用于电话通信、语音识别和音频采集等领域,以提高语音质量和减少干扰。 回声消除中常用的一种滤波器是RLS滤波器(递归最小二乘滤波器)。其原理基于递归最小二乘算法,通过对滤波器系数的不断调整,实时地预测和减去回声信号。 RLS滤波器通过将输入信号与滤波器的权值系数相乘,得到输出信号。输出信号与观测信号之间的误差用来调整滤波器的权值系数,使其逼近最佳值。通过反复迭代,滤波器能够根据实时情况调整权值系数,达到不断减小回声信号的效果。 在RLS滤波器中,误差检测与更新滤波器的过程是核心步骤。误差检测使用观测信号和滤波器的输出信号之差,计算出当前的误差值。更新滤波器的权值系数则使用误差值和输入信号的相关矩阵,通过递归最小二乘算法进行计算。 RLS滤波器通过不断调整滤波器的权值系数,实时减小回声信号的干扰,使得输出信号更加接近原始信号。这种滤波器在回声消除和降噪方面有着广泛的应用。同时,RLS滤波器也有一定的计算复杂度,需要较大的计算量和存储资源来实现。 ### 回答2: 回声消除是一种信号处理技术,用于在音频通讯中减弱或消除回声回声是由于音频信号从扬声器输出到麦克风输入时,经过房间内表面的反射而产生的。它严重影响语音通讯的质量,尤其是在电话会议和语音识别系统中。 回声消除的一种常见方法是使用自适应滤波器,其中最常用的是回声消除自适应滤波器(RLS)。RLS滤波器基于最小均方差(LMS)算法,通过在线学习和逐步更新滤波器系数来减弱或消除回声。 RLS滤波器的原理如下:首先,它使用一个称为冲击响应的反馈滤波器模型来估计回声路径。然后,通过将输入信号和估计的冲击响应模型进行卷积,可以生成一个估计的回声信号。接下来,估计的回声信号与实际麦克风输入信号之间的误差被计算出来。 在每次迭代中,RLS滤波器使用LMS算法来调整滤波器系数,以最小化回声估计与实际输入信号之间的误差。LMS算法通过计算误差和输入信号之间的乘积来确定滤波器系数的更新量。然后,通过将更新量与学习速率参数相乘,并与当前的滤波器系数相加,可以得到新的滤波器系数。 通过多次迭代学习和更新滤波器系数,RLS滤波器可以逐渐减小误差,从而减弱或消除回声。这种自适应的方法有效地适应了回声路径中可能出现的变化和干扰。 总结而言,RLS滤波器是一种常用的回声消除方法,通过在线学习和逐步更新滤波器系数来减弱或消除回声。它基于最小均方差算法,并使用LMS算法来调整滤波器系数。这种方法能够有效地提高语音通讯的质量。 ### 回答3: 回声消除(Echo Cancellation)是一种用于在语音通信中消除回声干扰的技术。它通过使用回声消除(Echo Cancellation)滤波器来抵消由于信号在通信中的传输延迟引起的回声回声通常发生在电话、音频会议、语音识别和语音广播等通信场景中。它是由于音频信号从一个发射源传输到接收器时,一部分信号会在传输途中被反射或传播,并在接收器处被重新接收。这种反射和重复的信号形成了回声回声会导致通信中的不良效果,如听到自己的声音或互相干扰等问题。 为了解决这个问题,使用rls滤波器(Recursive Least Squares Filter)来进行回声消除。rls滤波器是一种最小均方(Least Square)滤波器,它能够根据观测到的输入和输出信号来估计回声路径的特征,然后将该估计值用于抵消回声信号。 rls滤波器利用了递归滤波的原理,通过不断更新滤波器的参数来逼近真实的回声路径。具体来说,它通过计算观测到的输入信号与重建的回声信号之间的差异,并将该差异信号输入到滤波器中。然后,根据差异信号和滤波器的参数来调整滤波器的权重,以逐渐消除回声信号。 rls滤波器的优点是能够实时地估计回声路径并进行抵消,且对于回声路径的变化也有较好的适应性。它在实际应用中广泛用于语音通信系统和音频处理设备中,提高了通信质量和用户体验。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值