如何在Python中获取梅尔频谱图峰值数组以制作音频指纹?
获取频谱图峰值数组实现音频指纹
第一步:修正梅尔频谱生成逻辑
你的原代码生成的是STFT的对数幅度谱,并非梅尔频谱。先补充梅尔频谱转换步骤,同时保留代码可运行性:
import librosa, librosa.display import numpy as np import matplotlib.pyplot as plt import IPython.display as ipd def MEL_SPECTOGRAM(signal, sr, fileName): ipd.Audio(signal, rate=sr) n_fft = 2048 hop_length = 512 n_mels = 128 # 梅尔滤波器数量,可按需调整 # 生成梅尔频谱 mel_spectro = librosa.feature.melspectrogram( y=signal, sr=sr, n_fft=n_fft, hop_length=hop_length, n_mels=n_mels ) log_mel_spectro = librosa.amplitude_to_db(mel_spectro, ref=np.max) normalized_mel = librosa.util.normalize(log_mel_spectro) # 可视化梅尔频谱 librosa.display.specshow( normalized_mel, sr=sr, hop_length=hop_length, cmap='magma', x_axis='time', y_axis='mel' ) plt.colorbar(format='%+2.0f dB') plt.title(f'Mel Spectrogram - {fileName}') plt.show() return normalized_mel
第二步:提取频谱图峰值数组
音频指纹的核心是提取局部峰值,这里用非极大值抑制算法,筛选出每个时间帧内频率维度的局部最大值,同时通过阈值过滤低能量噪声点:
def extract_spectro_peaks(mel_spectro, threshold=0.2, neighborhood_size=3): """ 提取梅尔频谱的局部峰值 :param mel_spectro: 归一化后的梅尔频谱数组(形状:[n_mels, n_frames]) :param threshold: 峰值能量阈值,过滤低于该值的点 :param neighborhood_size: 邻域大小,检查周围n个点是否当前点为最大值 :return: 峰值数组,每个元素为(频率索引, 时间帧索引, 能量值) """ peaks = [] n_mels, n_frames = mel_spectro.shape for frame_idx in range(n_frames): frame = mel_spectro[:, frame_idx] for mel_idx in range(n_mels): # 跳过边缘点,避免索引越界 if mel_idx < neighborhood_size//2 or mel_idx >= n_mels - neighborhood_size//2: continue # 检查当前点是否为邻域内最大值且超过阈值 neighborhood = frame[mel_idx - neighborhood_size//2 : mel_idx + neighborhood_size//2 + 1] if frame[mel_idx] == np.max(neighborhood) and frame[mel_idx] > threshold: peaks.append((mel_idx, frame_idx, frame[mel_idx])) return np.array(peaks)
第三步:整合使用示例
# 加载音频文件 audio_path = "your_audio_file.wav" signal, sr = librosa.load(audio_path, sr=None) # 生成梅尔频谱 mel_spectro = MEL_SPECTOGRAM(signal, sr, audio_path.split("/")[-1]) # 提取峰值数组 peak_array = extract_spectro_peaks(mel_spectro, threshold=0.15, neighborhood_size=3) print(f"提取到的峰值数量:{len(peak_array)}") print("前5个峰值(频率索引, 时间帧索引, 能量值):") print(peak_array[:5])
关键说明
- 梅尔频谱转换:使用
librosa.feature.melspectrogram直接生成梅尔滤波后的频谱,比手动转换更可靠,贴合人耳听觉特性 - 峰值筛选:通过邻域最大值判断+能量阈值,确保提取的是真正有区分度的特征点,这些点就是构建音频指纹的核心元素
- 参数调整:
n_mels(梅尔滤波器数量)、threshold(峰值阈值)、neighborhood_size(邻域大小)可根据音频类型调整,优化指纹的唯一性和鲁棒性
内容的提问来源于stack exchange,提问作者Nau_Mar
相关产品推荐
相关产品推荐

