什么是卡尔曼滤波?
卡尔曼滤波是一种利用线性系统状态方程,通过系统输入的观测数据,对系统状态进行最优估计的算法。由于观测数据中包括系统的噪声和干扰的影响,所以最优估计也可以看作滤波的过程。
卡尔曼滤波在测量方差已知的情况下,能够从一系列存在测量噪声的数据中,估计动态系统的状态。
你可以在任何含有不确定信息的动态系统中使用卡尔曼滤波,对系统下一步的走向做出有根据的预测,即使伴随着各种干扰,卡尔曼滤波总是能指出真实发生的情况。
在连续变化的系统中使用卡尔曼滤波是非常理想的,它具有占用内存小的优点(除了前一个状态量外,不需要保留其它历史数据),并且速度很快,很适合应用于实时问题和嵌入式系统。
代码如下:
import numpy as np
import librosa
import soundfile as sf
import pyroomacoustics as pra
def kalman(x, d, N = 64, sgm2v=1e-4):
nIters = min(len(x),len(d)) - N
u = np.zeros(N)
w = np.zeros(N)
Q = np.eye(N)*sgm2v
P = np.eye(N)*sgm2v
I = np.eye(N)
e = np.zeros(nIters)
for n in range(nIters):
u[1:] = u[:-1]
u[0] = x[n]
e_n = d[n] - np.dot(u, w)
R = e_n**2+1e-10
Pn = P + Q
r = np.dot(Pn,u)
K = r / (np.dot(u, r) + R + 1e-10)
w = w + np.dot(K, e_n)
P = np.dot(I - np.outer(K, u), Pn)
e[n] = e_n
return e
# x 原始参考信号
# v 理想mic信号
# 生成模拟的mic信号和参考信号
def creat_sim_sound(x,v):
rt60_tgt = 0.08
room_dim = [2, 2, 2]
e_absorption, max_order = pra.inverse_sabine(rt60_tgt, room_dim)
room = pra.ShoeBox(room_dim, fs=sr, materials=pra.Material(e_absorption), max_order=max_order)
room.add_source([1.5, 1.5, 1.5])
room.add_microphone([0.1, 0.5, 0.1])
room.compute_rir()
rir = room.rir[0][0]
rir = rir[np.argmax(rir):]
# x 经过房间反射得到 y
y = np.convolve(x,rir)
scale = np.sqrt(np.mean(x**2)) / np.sqrt(np.mean(y**2))
# y 为经过反射后到达麦克风的声音
y = y*scale
L = max(len(y),len(v))
y = np.pad(y,[0,L-len(y)])
v = np.pad(v,[L-len(v),0])
x = np.pad(x,[0,L-len(x)])
d = v + y
return x,d
if __name__ == "__main__":
x_org, sr = librosa.load('female.wav',sr=8000)
v_org, sr = librosa.load('male.wav',sr=8000)
x,d = creat_sim_sound(x_org,v_org)
e = kalman(x, d, N=256)
e = np.clip(e,-1,1)
sf.write('x.wav', x, sr, subtype='PCM_16')
sf.write('d.wav', d, sr, subtype='PCM_16')
sf.write('kalman.wav', e, sr, subtype='PCM_16')
参考资料: