当前位置: 首页 > news >正文

简单音频比较

简单的音频比较

频谱算法

import os
import numpy as np
import matplotlib.pyplot as plt
from pydub import AudioSegment
from imagehash import phash
from PIL import Image
import ioimport random
import timedef audio_to_spectrogram(audio_path, output_path=None, return_bytes=False):"""将音频文件转换为频谱图:param audio_path: 音频文件的路径:param output_path: 频谱图的输出路径,如果为None则不保存到文件:param return_bytes: 是否返回字节形式的频谱图:return: 如果return_bytes为True,返回内存中的图像字节;否则返回None"""audio = AudioSegment.from_file(audio_path)samples = np.array(audio.get_array_of_samples())if audio.channels == 2:samples = samples.reshape((-1, 2))samples = samples.mean(axis=1)print(f'处理音频: {audio_path}')plt.figure(figsize=(10, 4))plt.specgram(samples, Fs=audio.frame_rate, NFFT=1024, noverlap=512)plt.axis('off')# 保存到内存if return_bytes or not output_path:buf = io.BytesIO()plt.savefig(buf, format='png', bbox_inches='tight', pad_inches=0)buf.seek(0)# 如果同时需要保存到文件if output_path:plt.savefig(output_path, bbox_inches='tight', pad_inches=0)print(f'频谱图已保存至: {output_path}')plt.close()return buf.getvalue() if return_bytes else buf# 只保存到文件if output_path:plt.savefig(output_path, bbox_inches='tight', pad_inches=0)print(f'频谱图已保存至: {output_path}')plt.close()return Nonedef get_audio_perceptual_hash(audio_path):"""获取音频的感知哈希值:param audio_path: 音频文件的路径:return: 音频的感知哈希值"""# 直接获取内存中的频谱图数据spectrogram_buffer = audio_to_spectrogram(audio_path, return_bytes=False)# 从内存数据创建PIL图像对象image = Image.open(spectrogram_buffer)# 计算感知哈希hash_value = phash(image)return hash_valuedef compare_audio_similarity(audio_path1, audio_path2):"""对比两个音频文件的相似性:param audio_path1: 第一个音频文件的路径:param audio_path2: 第二个音频文件的路径:return: 汉明距离,值越小表示越相似"""hash1 = get_audio_perceptual_hash(audio_path1)hash2 = get_audio_perceptual_hash(audio_path2)hamming_distance = hash1 - hash2return hamming_distanceif __name__ == "__main__":audio_path1 = "audio1.wav"audio_path2 = "audio2.wav"print(compare_audio_similarity(audio_path1, audio_path2))

dtw比较

import librosa
import numpy as np
from librosa.sequence import dtw
import matplotlib.pyplot as plt
import matplotlib
# 设置matplotlib支持中文显示
matplotlib.rcParams['font.sans-serif'] = ['SimHei']  # 用黑体显示中文
matplotlib.rcParams['axes.unicode_minus'] = False  # 正常显示负号from pathlib import Path
import time
import logginglogger = logging.getLogger(__name__)def compare_audio_dtw(audio1_path, audio2_path, chunk_duration=1.0, visualize=False, save_dir=None):"""使用DTW算法分析audio1的每个片段在audio2中的位置和相似度参数:audio1_path: 第一个音频文件路径(会被分段)audio2_path: 第二个音频文件路径(完整搜索空间)chunk_duration: 每个分段的时长(秒)visualize: 是否生成MFCC可视化图像save_dir: 可视化图像保存目录,如果为None则为'images'返回:list: 包含每个片段的匹配信息的列表,每项为(片段索引, 匹配时间点, 相似度得分)"""start_time = time.time()# 创建可视化保存目录if visualize:save_dir = save_dir or 'images'img_dir = Path(save_dir)if not img_dir.exists():img_dir.mkdir(parents=True, exist_ok=True)# === 加载音频 ===logger.info(f"加载音频文件: {audio1_path}, {audio2_path}")y1, sr = librosa.load(audio1_path, sr=None, res_type='kaiser_fast', offset=0.0, duration=None, mono=True)y2, _ = librosa.load(audio2_path, sr=sr, res_type='kaiser_fast', mono=True)  # 保持同采样率logger.info(f"{audio1_path} 采样率: {sr}")logger.info(f"{audio2_path} 采样率: {sr}")# === 参数设置 ===chunk_samples = int(chunk_duration * sr)num_chunks = len(y1) // chunk_sampleslogger.info(f"音频1 总共 {num_chunks} 段,每段 {chunk_duration} 秒")# 结果列表results = []# === 对每段做 DTW 匹配 audio2 ===for i in range(num_chunks):chunk = y1[i * chunk_samples : (i + 1) * chunk_samples]mfcc_chunk = librosa.feature.mfcc(y=chunk, sr=sr, n_mfcc=13)mfcc2 = librosa.feature.mfcc(y=y2, sr=sr, n_mfcc=13)# 可视化 mfcc_chunk 和 mfcc2if visualize:plt.figure(figsize=(12, 6))# 显示第一个音频片段的MFCCplt.subplot(1, 2, 1)plt.imshow(mfcc_chunk, aspect='auto', origin='lower')plt.title(f'MFCC - audio1 segment {i}')plt.ylabel('MFCC coefficients')plt.xlabel('Frames')plt.colorbar(format='%+2.0f dB')# 显示第二个音频文件的MFCCplt.subplot(1, 2, 2)plt.imshow(mfcc2, aspect='auto', origin='lower')plt.title('MFCC - audio2 full file')plt.ylabel('MFCC coefficients')plt.xlabel('Frames')plt.colorbar(format='%+2.0f dB')plt.tight_layout()plt.savefig(f'{img_dir}/mfcc_comparison_{i}.png')  # 保存图像到文件plt.close()  # 关闭图形以避免内存问题# 计算DTWD, wp = dtw(mfcc_chunk, mfcc2, subseq=True, metric='euclidean')# 找到最佳匹配位置best_idx = np.argmin(D[-1])best_time = librosa.frames_to_time(best_idx, sr=sr)# 获取最小代价和归一化相似度min_cost = D[-1, best_idx]max_possible_cost = np.max(D)similarity_score = 1 - (min_cost / max_possible_cost) if max_possible_cost > 0 else 1# 添加到结果列表results.append((i, best_time, similarity_score))logger.info(f"第{i}段 匹配位置: {best_time:.2f} 秒,相似度: {similarity_score:.2f}")# 计算耗时elapsed_time = time.time() - start_timelogger.info(f"分析完成,耗时: {elapsed_time:.2f} 秒")return resultsdef format_results(results):"""格式化结果为易读的字符串"""output = []for idx, time_pos, score in results:output.append(f"片段 {idx}: 在 {time_pos:.2f} 秒处匹配,相似度 {score:.2f}")return "\n".join(output)if __name__ == "__main__":# 设置基本日志配置logging.basicConfig(level=logging.INFO,format='%(asctime)s - %(levelname)s - %(message)s',datefmt='%Y-%m-%d %H:%M:%S')# 示例用法audio1_path = "audio1.wav"audio2_path = "audio2.wav"results = compare_audio_dtw(audio1_path, audio2_path, visualize=True)print("\n匹配结果:")print(format_results(results))
http://www.xdnf.cn/news/211933.html

相关文章:

  • 数据库day-08
  • C#中winform窗体如何捕获键盘按键事件
  • 深度学习篇---模型权重变化与维度分析
  • 阿里云 OpenManus 实战:高效AI协作体系
  • “情况说明“以后,Unity XR 开发者如何选择?
  • HTTP(超文本传输协议)全面总结
  • 蓝桥杯 10. 凯撒加密
  • [C]基础14.字符函数和字符串函数
  • 网络原理—应用层和数据链路层
  • 指针(5)
  • Spring Boot 集成 ActiveMQ 实现异步消息通信(一)
  • 跨平台项目部署全攻略:Windows后端+Mac前端在服务器的协同实战
  • Arduion 第一天,变量的详细解析
  • 三格电子——四路CAN转4G网关使用中的常见问题
  • 【深度学习新浪潮】ISP芯片算法技术简介及关键技术分析
  • 深度解析 MyBatis`@TableField(typeHandler = JacksonTypeHandler.class)`:优雅处理复杂数据存储
  • 深入理解二分查找
  • AI防摔倒检测系统
  • 实验七:基于89C51和DS18B20的温度采集与显示
  • 【从滚动条缺失到布局体系:前端布局问题的系统性思考】
  • pytorch 一些常用语法
  • 图漾官网Sample_V1版本C++语言完整参考例子---单相机版本
  • 企业办公协同平台安全一体化生态入住技术架构与接口标准分析报告
  • ubnuntu使用conda进行虚拟环境迁移,复制,克隆
  • Dify 使用模版转换实现更丰富的输入格式支持
  • linux FTP服务器搭建
  • 通信协议——SPI通信协议
  • Go语言中的错误处理
  • CSS:编写位置分类
  • PDF编辑器:Foxit PDF Editor Pro 版功能解析