有没有任何方法可以增加我的哈希值的冲突数,以便进行音频处理?

xvw2m8pv  于 2021-09-29  发布在  Java
关注(0)|答案(1)|浏览(419)

因此,我试图制作一种针对澳大利亚鸟类的鸟类沙扎姆(因为我在这里没有看到)。请不要告诉我这对真实的音频样本不起作用,我很清楚这一点,我这么做只是为了好玩和学习更多的编码:)
到目前为止,我已经得到了这个代码(我承认我从互联网上偷了很多代码):

def hash_file(filename):
   """"This function returns the SHA-1 hash
   of the file passed into it"""

   # make a hash object
   h = hashlib.blake2s()

   # open file for reading in binary mode
   with open(filename,'rb') as file:

       # loop till the end of the file
       chunk = 0
       while chunk != b'':
           # read only 1024 bytes at a time
           chunk = file.read(1024)
           h.update(chunk)

   # return the hex representation of digest
   return h.hexdigest()

import os
from pydub import AudioSegment
from pydub.utils import make_chunks
list_of_sounds = {}

directory = r'Bird_Calls'
for filename in os.listdir(directory):
    if filename.endswith(".mp3"):
        #print(os.path.join(directory, filename))
        #print(hash_file(os.path.join(directory,filename)))
        hasha=hash_file(os.path.join(directory,filename))
        list_of_sounds[hasha] = [filename]
    else:
        continue

print(list_of_sounds)

import pyaudio
import wave

CHUNK = 1024
FORMAT = pyaudio.paInt16
CHANNELS = 1
RATE = 44100
RECORD_SECONDS = 5
WAVE_OUTPUT_FILENAME = "tmp.mp3"

p = pyaudio.PyAudio()

stream = p.open(format=FORMAT,
                channels=CHANNELS,
                rate=RATE,
                input=True,
                frames_per_buffer=CHUNK)

print("* recording")

frames = []

for i in range(0, int(RATE / CHUNK * RECORD_SECONDS)):
    data = stream.read(CHUNK)
    frames.append(data)

print("* done recording")

stream.stop_stream()
stream.close()
p.terminate()

wf = wave.open(WAVE_OUTPUT_FILENAME, 'wb')
wf.setnchannels(CHANNELS)
wf.setsampwidth(p.get_sample_size(FORMAT))
wf.setframerate(RATE)
wf.writeframes(b''.join(frames))
wf.close()

recorded=hash_file("tmp.mp3")

if recorded in list_of_sounds:
    print(filename)

问题是,当我录制音频时(即使只是播放我知道在数据库中的呼叫,然后只是录制以获取哈希值),哈希值仍然不同。我知道这是由于时间/音频质量/背景噪声等方面的轻微偏移造成的。有没有办法使我的哈希值“更模糊”以增加冲突的可能性?还是我完全走错了路。请不要向我指出dejavu程序的方向,我相信它工作得很好,但我想看看我是否能自己编写这个程序。谢谢

sc4hvdpw

sc4hvdpw1#

您已选择blake2s作为哈希函数。这是一个加密散列函数,这意味着它被设计用来对输入的每个字节产生一个非常不同的结果。
对你来说,这意味着:如果你的mp3只差一个字节,那么产生的哈希值就已经大不相同了。
增加碰撞的数量没有帮助。实际上情况正好相反:任何其他文件(即使是文本文件、word文档或类似文件)都会有更高的更改以匹配您的鸟歌。
您需要的是一个专门为音频设计的哈希函数。对于类似shazam的功能,即:
它对计时的要求相对严格,因为我们希望所有播放都具有相同的速度(这可能会因制造公差和温度而有所不同,但可能小于1%)
它必须允许时间转换,因为录制可能迟早会开始
它对频率的要求相对严格,因为它是以特定的频率录制的,我们希望回放会产生类似的结果(如果使用均衡器,并且每个扬声器都有不同的谐振频率,则结果可能会有所不同)
它必须允许振幅变化,因为播放声音可能更大或从更远的地方录制
它必须允许噪音和环境声音
对于鸟类来说,算法变得更加困难,因为
它必须允许时差,因为不是每只鸟都以相同的速度歌唱
它必须允许频率偏移,因为鸟类可能会以不同的频率唱歌,它们没有什么可调的

为了解决图片中显示的一些问题,shazam使用频谱而不是波形,因此您需要的是傅里叶变换(通常是fft,而不是很多DFT)。他们不会做一次,但他们会以小的增量做,所以他们会得到瀑布光谱图,比如

但是他们仍然需要考虑有一个时间偏移(X轴上的位移)和响度的差异(更强烈的颜色)。你还需要考虑两个轴上的位移和拉伸。
也许在光谱图上做一些像图像处理的事情。您可以尝试识别具有当前频率和缺失频率的边缘和区域,如下所示:

这样你可以说这两种声音都包含4个边缘,2个缺失频率区域和4个当前频率区域,并且它们彼此的相对位置是相似的。
这正是你需要的。

相关问题