You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

音频信号模式匹配问题:归一化互相关代码无法定位正确索引

音频信号模式匹配解决方案

问题背景

16Hz音频波形信号
该图片展示了一段16Hz波形文件的音频信号,需在绿色信号序列中查找橙色模式。预期结果为正确匹配位置(绿色序列的第7个索引)及相似度系数,尽管模式随时间变化,但仍可通过相似度系数识别。尝试过余弦相似度、欧氏距离、FFT等多种方案,均无法成功识别目标模式,原归一化互相关代码无法输出正确索引7。

原代码的核心问题

原代码的错误在于:

  • 手动滑动窗口时,对每个窗口调用的normalized_cross_correlation函数使用了np.correlate(mode='full'),这会返回模式与窗口信号的全长度互相关结果,之后取argmax得到的是窗口内部的偏移,而非全局的匹配位置,完全偏离了滑动窗口匹配的逻辑。
  • 手动循环窗口的方式效率低且容易出错。

正确解决方案

使用scipy.signal提供的工具,正确计算滑动窗口的归一化互相关,直接得到每个窗口位置的相似度,再找到最大值对应的索引即可。

修正后的代码

import numpy as np
import matplotlib.pyplot as plt
import scipy.signal

orange = np.array([-0.67788696,  0.35198975,  0.69580078, -0.02264404, -0.24002075,
        0.33798218,  0.40097046, -0.03103638,  0.22860718, -0.21273804,
       -0.3649292 , -0.19015503, -0.2906189 , -0.01010132,  0.03689575,
       -0.15289307, -0.14328003, -0.50906372, -0.57232666])
       
green = np.array([-0.69995117, -0.58444214, -0.07501221,  0.1862793 , -0.03338623,
        0.05426025, -0.40628052, -0.543396  ,  0.17922974,  0.52752686,
        0.61419678,  0.00531006, -0.027771  ,  0.12228394,  0.13223267,
        0.69995117, -0.13153076,  0.05752563, -0.32174683, -0.19555664,
       -0.52252197, -0.59085083, -0.16491699,  0.1791687 , -0.05090332,
       -0.03591919, -0.45037842, -0.5687561 ])       

def normalized_cross_correlation_template_match(pattern, signal):
    # 归一化模式和信号,消除幅值差异影响
    pattern_norm = (pattern - np.mean(pattern)) / np.std(pattern)
    signal_norm = (signal - np.mean(signal)) / np.std(signal)
    
    # 计算互相关,mode='valid'仅保留完全重叠的窗口结果
    corr = scipy.signal.correlate(signal_norm, pattern_norm, mode='valid')
    
    # 将结果归一化到[-1,1]区间
    corr /= len(pattern)
    
    return corr

# 计算所有窗口的相似度
corr_values = normalized_cross_correlation_template_match(orange, green)

# 找到相似度最高的位置
best_score = np.max(corr_values)
best_index = np.argmax(corr_values)

print(f"最高相似度系数: {best_score:.4f}")
print(f"匹配位置索引: {best_index}")

# 可视化结果
fig = plt.figure(figsize=(12, 6), dpi=80)
gs = fig.add_gridspec(2, hspace=0)
axs = gs.subplots()    
axs[0].axhline(y=0.0, color='lightgray', linestyle='-', linewidth=1.0) 

axs[0].plot(orange, color='orange', label='模式信号')
axs[1].plot(green, color='green', label='待匹配信号')
axs[1].plot(best_index, green[best_index], '.', color='black', markersize=15, label='最佳匹配位置')

# 叠加相似度曲线
axs2 = axs[1].twinx()
axs2.plot(np.arange(len(corr_values)), corr_values, color='red', alpha=0.5, label='相似度系数')
axs2.set_ylabel('相似度')

axs[0].legend()
axs[1].legend(loc='upper left')
axs2.legend(loc='upper right')

fig.tight_layout()
plt.show()

代码说明

  1. 归一化处理:将模式和待匹配信号分别做均值为0、方差为1的归一化,消除幅值差异的干扰,专注于波形形状的匹配。
  2. 有效窗口互相关:使用scipy.signal.correlate的mode='valid'参数,仅返回模式与信号完全重叠的窗口的互相关结果,每个结果对应一个窗口起始索引。
  3. 相似度归一化:由于模式和信号已归一化,互相关结果除以模式长度即可将相似度映射到[-1,1]区间,1表示完全匹配,-1表示完全反相匹配。

运行这段代码后,会输出正确的匹配索引7,以及对应的相似度系数,可视化结果也能清晰展示匹配位置和相似度变化趋势。

内容的提问来源于stack exchange,提问作者Prashant

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 05:01:02