目录
引言
声源定位(Sound Source Localization)是通过分析声音到达多个麦克风阵列的时间差异来推断声音来源的方向或位置的技术。它被广泛应用于声学领域,包括智能语音系统、机器人导航、视频会议、语音识别等场景。本文将深入分析基于**TDOA(Time Difference of Arrival,时间差到达法)**的声源定位技术,并详细解读代码实现。
1. 声源定位的基本原理
声源定位的原理是利用声音传播的时间差异来计算声源的方向或位置。考虑一个由两个麦克风组成的简单阵列,麦克风之间有一定的距离,当一个声音从某个方向传来时,两个麦克风接收到的声音会有时间差,这个时间差就称为TDOA(Time Difference of Arrival)。
通过计算TDOA,并结合麦克风之间的距离和声音的传播速度,可以推导出声源的相对角度(即DOA,Direction of Arrival)。
基本公式:
给定麦克风间距 d,声速 v,以及声音信号到达两麦克风的时间差 τ,我们可以通过如下公式计算声源的到达角度 θ:
θ = arcsin(τ * v / d)
其中:
τ 是通过 GCC-PHAT(广义互功率谱相位变换)算法计算得到的时间差。
v 是声速,约为 340 m/s。
d 是麦克风的距离。
多麦克风阵列:
对于更复杂的麦克风阵列,TDOA 值可以通过多个麦克风之间的时间差计算,并使用这些TDOA值进行三角定位或其他几何定位方法来精确计算声源位置。
2. GCC-PHAT算法简介
在实际应用中,直接通过交叉相关来计算TDOA可能受到噪声和混响的影响。为了解决这一问题,广义互功率谱相位变换(GCC-PHAT,Generalized Cross-Correlation with Phase Transform)算法是一种常用的稳健方法,它可以在噪声和回声环境下依然保持较高的定位精度。
GCC-PHAT的步骤:
对两个麦克风接收到的信号进行快速傅里叶变换(FFT),将信号从时域转换到频域。
计算频域上的互功率谱(cross-power spectrum)。
通过对互功率谱的相位进行归一化,去掉幅度信息,使得时间延迟的估计更加稳健。
进行逆傅里叶变换,将结果转换回时域,计算出峰值对应的时间差(TDOA)。
3. 代码实现详解
让我们一步一步分析你提供的代码,它使用了GCC-PHAT算法来进行基于TDOA的声源定位。
def gcc_phat(ref, sig, sr):
n_point = 2 * ref.shape[0] - 1 # 计算FFT的点数,零填充到信号长度的两倍
X = np.fft.fft(ref, n_point) # 对参考信号做FFT变换
Y = np.fft.fft(sig, n_point) # 对目标信号做FFT变换
XY = X * np.conj(Y) # 计算两信号的互功率谱,X乘以Y的共轭
c = XY / (abs(X) * abs(Y) + 10e-6) # 归一化相位信息,去掉幅度影响,增加稳定性
c = np.real(np.fft.ifft(c)) # 进行逆FFT,得到时域的相关函数
end = len(c)
center_point = end // 2
# FFT shift,使零时延对准中心
c = np.hstack((c[center_point + 1:], c[:center_point + 1]))
lag = np.argmax(abs(c)) - len(ref) + 1 # 找到最大相关点的位置,即时间延迟
tau = lag / sr # 计算时间延迟 tau
return tau
代码详解:
FFT 计算:对两个输入信号 ref 和 sig 进行快速傅里叶变换(FFT),将信号从时域转换到频域。
互功率谱计算:计算信号的互功率谱(cross-power spectrum),XY = X * np.conj(Y)。这表示参考信号和目标信号在频域的相位差。
相位归一化:通过相位归一化(即 PHAT 变换),消除幅度信息,只保留相位信息。这样可以减少噪声对TDOA计算的影响。
逆FFT:将归一化后的频域信号通过逆FFT转换回时域,以获得不同时间延迟的互相关函数。
找到最大时延点:在逆变换后的时域信号中找到最大峰值的位置,该位置对应于信号之间的时间差(TDOA)。
时间差换算:计算时间延迟 τ = lag / sr,其中 sr 是采样率,lag 是时延的样本数。
通过这个函数,给定两个麦克风的信号数据,GCC-PHAT可以有效估计出声音在两个麦克风之间的时间差 τ。
SOUND_SPEED = 340.0
MIC_DISTANCE = 0.15
sample_rate = 48000
MAX_TDOA = MIC_DISTANCE / float(SOUND_SPEED)
SOUND_SPEED:声速,约为340 m/s。
MIC_DISTANCE:两个麦克风之间的距离,设为0.15米。
sample_rate:采样率,设为48000 Hz。
MAX_TDOA:通过麦克风距离和声速计算出的最大时间差。
org_ref, sr = librosa.load("./data/ref.wav", sr=sample_rate)
org_sig, sr = librosa.load("./data/sig.wav", sr=sample_rate)
加载参考信号 ref.wav 和目标信号 sig.wav,并设置采样率为 48000Hz。
ref = librosa.util.frame(org_ref, 1024, 256).T
sig = librosa.util.frame(org_sig, 1024, 256).T
将信号划分为多个帧,每帧长度为1024个样本,帧移为256个样本。将信号帧处理是为了能够在时域内稳定估计DOA。
fai = []
for i in tqdm(range(len(ref))):
tau = gcc_phat(ref[i], sig[i], sample_rate) # 计算每帧的TDOA
theta = np.arcsin(tau / MAX_TDOA) * 180 / np.pi # 通过TDOA计算DOA角度
fai.append(theta)
遍历所有帧,调用 gcc_phat 函数计算每帧的时间延迟 τ,并利用TDOA公式 θ = arcsin(τ * v / d) 计算声源方向角度 θ。
theta 用度数表示(乘以180/π)。
plt.subplot(211)
plt.ylabel('DOA ')
plt.xlabel('Frame index')
plt.title('DOA')
plt.plot(fai) # 绘制每一帧的DOA角度变化
绘制每一帧的声源角度(DOA)随时间的变化曲线。
plt.subplot(212)
plt.ylabel('Amplitude')
plt.xlabel('Frame index')
plt.title('Waveform')
plt.plot(org_ref) # 绘制参考信号的波形
plt.tight_layout()
plt.show()
显示参考信号的波形,以及通过TDOA计算出的每一帧对应的DOA角度。
4. 声源定位中的挑战
噪声和回声影响:尽管GCC-PHAT可以在一定程度上降低噪声和回声的影响,但在极端复杂环境中,仍可能会出现误差。
多源信号干扰:当多个声源同时存在时,定位一个特定声源的方向会变得更加困难,需要结合更复杂的多源分离算法。
麦克风阵列设计:麦克风之间的距离、阵列布局和环境的声学特性都会影响TDOA的准确性。
结语
本文详细解析了基于TDOA的声源定位原理,并深入分析了使用GCC-PHAT算法计算TDOA的Python代码实现。TDOA是声源定位中的关键技术之一,它通过计算声音到达多个麦克风的时间差,结合几何关系来推导声源的方向或位置。尽管在实际应用中存在噪声、回声等挑战,但通过合适的信号处理技术,如GCC-PHAT,可以有效提高声源定位的精度。
学习资料来源:https://github.com/Ryuk17
标签:声源,plt,麦克风,时间差,TDOA,信号,ref From: https://blog.csdn.net/weixin_52734695/article/details/142436795