音频快速去重(音频去重检测)是一项重要任务,尤其在音频内容管理、语音数据清洗、音乐平台内容审核等场景中非常有价值。其目标是在大规模音频库中快速识别出重复或近似重复的音频段。常用的音频去重算法,大致可以分为三大类:1是我们前面介绍过的音频指纹;2是通过深度学习进行生成embedding;3就是今天要介绍的感知哈希算法。不论哪种算法,其核心思想就是为相似音频生成相近的特征表达,然后通过计算距离的方式区分相似音频和不相似的音频。


🌟 音频感知哈希

感知哈希(Perceptual Hashing,简称pHash)是一类将多媒体(图像、音频、视频等)转换为“感知相似的哈希值”的技术。它不同于传统的加密哈希(如 MD5、SHA-1),感知哈希的目标是:即使内容有细微变化(如压缩、裁剪、噪声、变速等),相似内容也能得到相似的哈希值。

感知哈希一般用于图像领域,为了使其可以用于音频去重,需要对原始音频数据进行处理,提前其对应的感知哈希,本文介绍的算法具体的步骤如下:

  • 对音频进行分帧处理,对每一帧进行FFT计算

  • 计算每一帧的频谱,并将频谱通过33 个 Bark 滤波器

  • 相邻 Bark 滤波器的差值变化量用于描述频谱形态变化,如果 H > 0,则当前 bit 为 1,否则为 0

  • 每帧生成 32 位哈希(从 33 个 bark 中得到 32 个差值)

经过上述处理步骤,可以得到一个Nx32的hash矩阵,结果如下所示



🌟 哈希距离计算
音频不像图像那样可以resize到指定大小,因此不同音频的感知哈希长度可能不一样,因此需要使用滑动窗口来完成整理的哈希距离计算。即对较短序列 A 在较长序列 B 上滑动匹配,每 block_size个帧为一组,具体计算相似度其计算流程如下:
  • 选择短的作为A,长的作为B,定义滑窗个数为Nb-Na+1
  • 从 B 的每个偏移 i 开始,拿出长度为 A 的序列做对比;将对比序列划分为多个 block_size 大小的小段;每个块计算相似度,一般会采用SWAR加快计算速度

  • 对每个滑窗,若距离 ≤threshold,认为是匹配片段


上面两个音频样本经过滑动窗口计算最终的hash距离最大值为0.26。

虽然上述的音频去重算法虽然具有高效、轻量、工程可用性强等优点,但它也存在一些固有缺点和局限性,如下所述
  • 虽然是“感知”哈希,但其本质还是基于Bark频谱能量差分的结构化编码,仍容易受到注入:背景噪声变化(例如录音设备不同)淡化、回响、均衡器滤波等轻度后处理,小幅度剪辑(比如加了一个静音头或尾),这些都会导致哈希位的剧烈变化,使相似音频无法正确匹配

  • 该算法是基于固定帧长、固定帧移的滑窗处理,对非线性时间变化不敏感

  • 感知特征设计简单,未考虑语义内容,这意味着两个听起来相似但频谱不同的音频不会匹配成功(例如不同人说同一句话、不同乐器演奏同一旋律)

解决上述问题,可以采用更为鲁棒的学习型音频比对算法, 比如通过神经网络生成embedding,再进行相似度计算。


本文代码:https://github.com/Ryuk17/AudioDeduplication

参考文献:[1].https://www.phash.org/docs/pubs/thesis_zauner.pdf