基于Python数组互相关系数定位音频片段起始位置的问题
定位音频片段的精确起始时间戳(带置信度阈值)
整体问题
我希望创建一个函数,定位音频片段在原音频文件中的精确起始时间戳。测试时使用了一段5分钟的音频和一段43秒的片段,在Audacity中对齐后确认片段起始于00:01:55.554920。
函数需要仅在置信度超过设定阈值时返回结果,阈值作为函数参数。我的实现思路是检查对齐后信号的相关系数是否超过阈值,简化代码如下:
def find_excerpt_starting_sample(original_audio, excerpt, threshold): # 计算每个滞后值的互相关系数 xcorr = cross_correlation(original_audio, excerpt) # 若最大相关系数超过阈值则返回对应滞后值 if np.max(xcorr) > threshold: return np.argmax(xcorr) else: raise Exception("No correlation over threshold found.")
但始终找不到合适的cross_correlation函数,所有尝试返回的数组值都不在0-1范围内。
简化问题
由于音频测试无果,我用数值数组模拟场景:
y1 = [2, 22, 14, 8, 0, 4, 8, 16, 26, 6, 12, 14, 16, 2, 6] y2 = [4, 8, 16, 26, 6, 12]
y2是y1的子集(起始于索引5)。为确保函数不受振幅影响,将y2的值减半:
y1 = [2, 22, 14, 8, 0, 4, 8, 16, 26, 6, 12, 14, 16, 2, 6] y2 = [2, 4, 8, 13, 3, 6]
我希望创建一个互相关函数,返回的数组在滞后值为5处的值为1。
现有尝试
np.corrcoef
滑动片段计算相关系数的方法有效:
import numpy as np import matplotlib.pyplot as plt corr = np.zeros(len(y1) - len(y2)) for i in range(len(y1) - len(y2)): corr[i] = np.corrcoef(y1[i:i+len(y2)], y2)[0][1] print(corr) plt.plot(corr) plt.show()
输出:
[ 0.18961375 -0.71250433 -0.56075283 -0.08468414 0.21913077 1. -0.04179451 -0.46803451 -0.24815461]
但该方法对长数组效率极低。
scipy.signal.correlate
尝试使用scipy.signal的correlate函数,但它仅返回卷积值,无法量化相关性:
from scipy import signal xcorr = signal.correlate(y1, y2, mode="full") lags = signal.correlation_lags(len(y1), len(y2), mode="full") print(xcorr) print(lags) plt.plot(lags, xcorr) plt.show()
输出:
[ 12 138 176 392 390 332 224 232 356 402 596 486 478 414 422 252 186 88 28 12] [-5 -4 -3 -2 -1 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14]
尝试了两种归一化方案,但最大值都不为1:
方案一
corr = signal.correlate(y1 / np.std(y1), y2 / np.std(y2), 'full') / min(len(y1), len(y2)) lags = signal.correlation_lags(len(y1), len(y2), mode="full") print(corr) plt.plot(lags, corr) plt.show()
输出最大值为3.65741371。
方案二
y1n = y1 / np.std(y1) y2n = y2 / np.std(y2) xcorr = signal.correlate(y1n, y2n, mode="full") lags = signal.correlation_lags(len(y1), len(y2), mode="full") print(xcorr) plt.plot(lags, xcorr) plt.show()
输出最大值为21.94448224。
求助
我对相关性知识了解有限,虽已深入研究但仍未解决问题,希望有人能指出我的错误并给出解决方向。非常感谢!
内容的提问来源于stack exchange,提问作者RomainP
相关产品推荐
相关产品推荐

