如何在 Python 中关联两个音频事件(检测它们是不是相似)

Posted

技术标签:

【中文标题】如何在 Python 中关联两个音频事件(检测它们是不是相似)【英文标题】:How to Correlate Two Audio Events (Detect if they are Similar) in Python如何在 Python 中关联两个音频事件(检测它们是否相似) 【发布时间】:2019-08-01 22:28:19 【问题描述】:

对于我的项目,我必须检测两个音频文件是否相似,以及第一个音频文件何时包含在第二个音频文件中。我的问题是我尝试使用 librosa 的 numpy.correlate。我不知道我是否以正确的方式做这件事。如何检测音频是否包含在另一个音频文件中?

import librosa
import numpy
long_audio_series, long_audio_rate = librosa.load("C:\\Users\\Jerry\\Desktop\\long_file.mp3")
short_audio_series, short_audio_rate = librosa.load("C:\\Users\\Jerry\\Desktop\\short_file.mka")

for long_stream_id, long_stream in enumerate(long_audio_series):
    for short_stream_id, short_stream in enumerate(short_audio_series):
        print(numpy.correlate(long_stream, short_stream))

【问题讨论】:

这些事件是什么样的音频?一个典型的事件有多长? @jonnor 30 分钟是 long_audio 和短音频 1:30 分钟 【参考方案1】:

简单地比较音频信号long_audio_seriesshort_audio_series 可能行不通。我建议做的是音频指纹识别,更准确地说,基本上是 Shazam 所做的穷人版本。当然有patent 和paper,但您可能想从this very readable description 开始。这是该文章的中心图像,星座图 (CM):

如果您不想扩展到很多歌曲,您可以跳过整个哈希部分并专注于峰值查找。

所以你需要做的是:

    创建功率谱图(使用librosa.core.stft 很容易)。 在所有文件中查找局部峰值(可以使用 scipy.ndimage.filters.maximum_filter 完成)以创建 CM,即仅包含峰值的 2D 图像。生成的 CM 通常是二进制的,即包含 0 表示无峰,1 表示峰。 将查询 CM(基于 short_audio_series)滑动到每个数据库 CM(基于 long_audio_series)上。对于每个时间步数,有多少“星”(即1s)对齐并存储计数以及幻灯片偏移量(基本上是短音频在长音频中的位置)。 选择最大计数并返回相应的短音频和长音频中的位置。您必须转换 frame numbers back to seconds。

“幻灯片”示例(未经测试的示例代码):

import numpy as np

scores = 
cm_short = ...  # 2d constellation map for the short audio
cm_long = ...   # 2d constellation map for the long audio
# we assume that dim 0 is the time frame
# and dim 1 is the frequency bin
# both CMs contains only 0 or 1
frames_short = cm_short.shape[0]
frames_long = cm_long.shape[0]
for offset in range(frames_long-frames_short):
    cm_long_excerpt = cm_long[offset:offset+frames_short]
    score = np.sum(np.multiply(cm_long_excerpt, cm_short))
    scores[offset] = score
# TODO: find the highest score in "scores" and
# convert its offset back to seconds

现在,如果您的数据库很大,这将导致太多的比较,您还必须实施哈希方案,这也在我上面链接的文章中进行了描述。

请注意,所描述的过程仅匹配相同的录音,但允许出现噪音和轻微失真。如果这不是您想要的,请更好地定义相似性,因为这可能是各种各样的东西(鼓模式、和弦序列、乐器...)。一种经典的、基于 DSP 的方法来查找这些特征的相似性如下:为短帧(例如 256 个样本)提取适当的特征,然后计算相似度。例如,如果您对谐波含量感兴趣,您可以提取chroma vectors,然后计算色度向量之间的距离,例如余弦距离。当您计算数据库信号中每一帧与查询信号中每一帧的相似度时,您最终会得到类似于self similarity matrix (SSM) 或recurrence matrix (RM) 的结果。 SSM/RM 中的对角线通常表示相似的部分。

【讨论】:

“CM”是什么意思?我没有任何数据库 CM = 星座图 通常问题被表述为“使用样本查询音频文档数据库”。如果您只有一个 long 文件,那就是您的数据库。您的短文件就是您的查询。 如何滑动我的 CM 以匹配查询,对不起,我是音频处理的初学者? 为您的长文档和短文档创建一个 CM。使用 numpy 切片,从与短文档一样长的长文档中创建摘录。然后只需np.multiply 两个图像和np.sum 结果。那是你的数。现在,要幻灯片,从长 CM 中选择不同的摘录,移动一帧,依此类推。

以上是关于如何在 Python 中关联两个音频事件(检测它们是不是相似)的主要内容,如果未能解决你的问题,请参考以下文章

如何在phpmyadmin中关联同一张表的两个字段?

「软件设计」UML中关联,聚合和组合区别

如何覆盖 Grails GORM 中关系的级联删除?

在 Python 中检测并录制音频为 PCM 格式

在 sequelize 中关联两个表

如何使用 python 检测到某些东西已插入 linux 上的音频插孔?