我正在开展一个项目,该项目将无线电数据转换为文本,以寻找特定类型的无线电聊天。在大多数情况下,无线电信号是死气沉沉的。会定期对特定类型的市政事件(火灾、医疗、警察)进行标注。每个标注都有独特的一系列声音,用于识别类型的呼叫。在耳朵里,它们听起来是一样的。但由于噪声/失真、音量,信号每次都不完全相同。
我正在尝试做的是确定一种方法,根据前面的声音按市政类型自动对每个标注进行分类。我目前使用的技术是首先在 15 分钟的 mp3 数据剪辑中获取原始信号数据。我通过消除沉默将它剪成片段。然后我拍摄剪辑的前 4 秒,使用 imagemagick 将其转换为频谱图,然后使用 imagemagick 的compare -metric phash
技工将其与之前保存的已知有效信号记录的频谱图进行比较。该解决方案工作正常,但不是很好。它会导致误报到耳朵甚至不靠近。如果我减少允许的汉明距离,则会导致我对有效标注进行错误分类。如果我增加汉明距离,我会得到误报。另一个问题是它需要大量处理(原始 -> 删除静音 -> 每个剪辑 -> 获取 4s 剪辑 -> 频谱图 -> 比较 -> 如果匹配 -> 保存剪辑)。最终,方法似乎有缺陷……必须有更好的方法。
这是一个示例文件https://drive.google.com/file/d/1GcU6zQDr2G39a5Szpr-A6rPBYjv9Zrch/view?usp=sharing. 这是 15 分钟的信号数据。如果您跳到 1:52,您会听到医疗呼叫的声音,这是一个音量逐渐增大的单音调,每次都是相同的音调。另一个医疗电话发生在 2:07。如果您跳到 3:44,您将听到前面的火灾报警声音。这是一种奇怪的声音,几乎听起来像一个老式的调制解调器,但每次火灾都是一样的。5 点 35 分又有一场火灾。火灾呼叫的波形相似但不完全相同。在这个项目之前,我对信号处理的了解完全为零,我仍然知道略高于零。我的直觉告诉我必须有某种方法来平滑波形,然后做某种机制来比较波形的形状,而不是确切的高度(所以如果一个标注只是稍微响亮或安静,它们就会匹配)。类似于正则表达式的东西,但用于信号数据,但我不知道这是否有意义,或者是否没有更好的方法。当我在网上查看时,很多都是像音频指纹这样的东西,但这对我来说没有意义,因为我不是要识别整个文件,而是查看我的原始文件是否包含此音频文件。它似乎与Shazam中使用的算法相似,但我在那篇论文中找不到实际的算法,它似乎只是在谈论生成星座,而不是关于如何实际生成星座的细节。
我的担忧归结为两个主要问题。首先,什么是正确的算法,其次我如何实际执行它。我有使用 python、node 和 golang 的经验/访问权限。如果我知道正确的算法,我想我可以找出其余的,但如果有一个众所周知的库已经解决了这个问题,那就更好了。
编辑:
根据 Max 的回答,我取得了一些进展。但我仍然陷入僵局。
testFile, sr = librosa.load("/app/src/1601317821107.mp3")
matchFile, sr = librosa.load("/app/src/medicSound3.wav")
corr = scipy.signal.correlate(testFile, matchFile, mode="full", method="fft")
如果我绘图corr
,我会得到下图。
这清楚地显示了给定文件中的 4 个匹配项,这是完全正确的。如果我对一个没有实际匹配的文件运行它,那么该图永远不会有任何高于 10 的峰值。所以下一个挑战是如何定位每个峰值的起点。我已经尝试过scipy.signal.find_peaks
,但这给了我很多高峰,而不仅仅是我寻求的 4 个。我试过摆弄prominence
, width
,height
参数,但没有一个真正找到我要找的东西。在这种情况下,我正在寻找每场主要比赛的开始。如果我知道起始索引,我相信我可以简单地将其除以采样率 (22050) 以获得以秒为单位的位置。另一个问题是corr
数组的长度是 thetestFile
和matchFile
数组的总和。这导致我的索引corr
数组不完全匹配它们在testFile
数组中的位置。
想法?