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

yolo8+声纹识别(实时字幕)

现在已经完成了人脸识别跟踪 ✅,接下来要:

✅ 加入「声纹识别(说话人识别)」功能,识别谁在讲话,并在视频中“这个人”的名字旁边加上「正在讲话」。

这属于多模态识别(视觉 + 音频):

  1. 说明实现原理与推荐工具

  2. 给出整体流程架构

  3. 推荐稳定的开源工具包

  4. 展示如何与当前人脸识别结合


✅ 整体目标

希望实现:

  • 摄像头中显示所有人的名字(已完成)

  • 通过麦克风监听讲话内容

  • 根据声纹判断当前是谁在讲话

  • 在视频中对这个人显示“正在讲话”

✅ 实现路径(视觉 + 音频)

🔊 声纹识别部分(说话人识别)

目标技术名称推荐工具
声音中识别是谁说话人识别(Speaker Identification)pyannote-audio不推荐, resemblyzer推荐
声音中找谁在说话说话人活动检测(Voice Activity Detection, VAD)webrtcvad, silero-vad
声纹注册(采集说话人音频)Speaker Embeddingresemblyzer, speechbrain

1. pyannote-audio和resemblyzer区别核心功能对比

特性pyannote-audioresemblyzer
主要用途说话人分割(Diarization)、语音活动检测(VAD)、重叠语音检测声纹嵌入(Speaker Embedding)、实时声纹比对
模型复杂度高(多模块联合优化,端到端流程)低(轻量级,专注声纹向量提取)
预训练模型提供完整的说话人分割管道(如 speaker-diarization-3.1仅提供声纹编码器(如 VoiceEncoder
实时性较慢(适合离线处理)快(支持实时流式处理)
依赖项依赖 PyTorch 和 Hugging Face 模型库仅需 NumPy 和 PyTorch
典型应用场景会议记录、广播分析、多说话人数据集标注实时声纹验证、说话人聚类

2. 技术实现差异

pyannote-audio
  • 模块化设计
    包含独立的子模块(如 segmentationembeddingclustering),可灵活组合或替换16。

  • 端到端流程
    支持从语音活动检测到说话人聚类的完整流程,适合复杂场景(如重叠语音处理)6。

  • 性能优化
    部分版本(如 speaker-diarization-3.1)处理长音频较慢,推荐使用 v2 版本加速12。

resemblyzer
  • 轻量级
    仅实现声纹向量提取(512 维嵌入),需自行结合聚类算法(如 K-Means)完成分割5。

  • 实时性
    适合流式处理,单次推理速度快(约 0.1 秒/语音片段)5。

  • 易用性
    无需复杂配置,适合快速验证声纹相似度

✅ 推荐方案(轻量 + 可行)

🔧 声纹识别用 resemblyzer,搭配 YOLO 人脸

注意!!!!!!!!!!!!

先安装ffmpeg,resemblyzer会依赖

1. 为什么 resemblyzer 需要 ffmpeg

resemblyzer 的核心功能是处理音频文件(如 MP3、WAV 等),但它本身 不直接调用 ffmpeg,而是通过以下依赖链间接使用:

resemblyzer 
→ librosa(音频加载) 
→ audioread(解码非WAV格式) 
→ ffmpeg(实际解码工具)
  • 关键点
    只有处理 非WAV格式(如MP3、MP4) 时才需要 ffmpeg。如果仅使用 WAV 文件,可跳过安装。

✅ 安装【ffmpeg】

https://ffmpeg.org/打开网站下载自己的版本

接下来📦 安装其他依赖:

pip install resemblyzer sounddevice webrtcvad numpy 

💡 resemblyzer 是 Facebook 开源的轻量级声纹识别库,能实时从麦克风提取声纹并判断是否是目标用户。

✅ 总体流程图(视觉 + 音频结合):


✅ 示例代码框架(概要)

1、查看在PyCharm里面能不能使用ffmpeg

import subprocesstry:result = subprocess.run(["ffmpeg", "-version"], capture_output=True, text=True)if result.returncode == 0:print("✅ ffmpeg 已安装")else:print("❌ ffmpeg 未安装或异常")
except FileNotFoundError:print("❌ 未找到 ffmpeg 命令")

2、拿两段音频识别


from resemblyzer import VoiceEncoder, preprocess_wav
import numpy as np# 初始化编码器
encoder = VoiceEncoder()# 加载并预处理音频
wav1 = preprocess_wav("/Users/lianying/Desktop/yolo/1.m4a")  # 支持 .wav/.mp4 文件
wav2 = preprocess_wav("/Users/lianying/Desktop/yolo/2.m4a")# 提取声纹嵌入(512 维向量)
embed1 = encoder.embed_utterance(wav1)
embed2 = encoder.embed_utterance(wav2)# 计算相似度(余弦相似度)
similarity = np.dot(embed1, embed2)
print(f"声纹相似度: {similarity:.4f}")  # 0.0~1.0,>0.8 可视为同一人

已经成功识别声纹了 !!!!!!!

✅ 接下来整合以下功能:

模块状态
🧠 人脸识别 + 声纹识别✅ 已完成(已有)
🎙️ Whisper 语音识别✅ 可用(ffmpeg 已安装)
💬 实时字幕显示🔜 马上整合

已经安装好了 ffmpeg ✅,那现在可以 正式接入 Whisper 实现“说话内容转字幕”

🧠 模型大小选择:使用 Whisper 的哪个版本?(默认推荐 base

  • tiny(最快) / base(准确+轻)/ small(较高准确)

✅ 安装 Whisper(OpenAI 官方)

pip install -U openai-whisper

✅ Whisper 使用示例(语音转文字)

import whisper
model = whisper.load_model("base")  # 也可以用 "tiny", "small", "medium", "large"# 录音 → 保存为 temp.wav
import sounddevice as sd
from scipy.io.wavfile import writefs = 16000
duration = 3
audio = sd.rec(int(duration * fs), samplerate=fs, channels=1)
sd.wait()
write("temp.wav", fs, audio)# 语音识别
result = model.transcribe("temp.wav", language="zh")
print("识别内容:", result["text"])

🎯 目标

基于摄像头视频流,识别谁在讲话,并把“张三(正在讲话):你好啊,我是张三”样式的字幕实时显示在画面上(支持中文)

✅ 内容包含:

模块技术状态
人脸识别YOLOv8 + face_recognition
声纹识别Resemblyzer
语音转文字Whisper(base)
实时录音sounddevice
字幕显示PIL + 中文字体支持

✅ 使用前请确认:

如下文件夹结构:

import os
import cv2
import numpy as np
from PIL import ImageFont, ImageDraw, Image
import face_recognition
from resemblyzer import VoiceEncoder, preprocess_wav
import sounddevice as sd
from scipy.io.wavfile import write
import whisper
from ultralytics import YOLO# === 参数设置 ===
VOICE_DB = "voice_db"
FACES_DB = "faces"
FONT_PATH = "font/AlimamaDaoLiTi-Regular.ttf"  # 中文黑体字体路径(请确保该字体文件存在)
SAMPLE_RATE = 16000
RECORD_DURATION = 1  # 录音时间(秒)
CONFIDENCE_THRESHOLD = 0.75# === 初始化模型 ===
print("加载 YOLOv8 模型...")
yolo_model = YOLO("/Users/lianying/Desktop/yolo/model_face.pt")  # 检测人脸用
print("加载人脸识别数据库...")
known_encodings, known_names = [], []
for name in os.listdir(FACES_DB):for img_file in os.listdir(os.path.join(FACES_DB, name)):img_path = os.path.join(FACES_DB, name, img_file)img = face_recognition.load_image_file(img_path)enc = face_recognition.face_encodings(img)if enc:known_encodings.append(enc[0])known_names.append(name)print("加载声纹识别数据库...")
encoder = VoiceEncoder()
speaker_embeddings = {}
for file in os.listdir(VOICE_DB):if file.endswith(".wav"):name = file.split(".")[0]wav = preprocess_wav(os.path.join(VOICE_DB, file))embed = encoder.embed_utterance(wav)speaker_embeddings[name] = embedprint("加载 Whisper 模型...")
asr_model = whisper.load_model("base")# === 字体 ===
font = ImageFont.truetype(FONT_PATH, 24)# === 摄像头 ===
cap = cv2.VideoCapture(0)
frame_count = 0
interval = int(30 * RECORD_DURATION)  # 每 interval 帧识别一次
current_speaker = ""
current_text = ""while True:ret, frame = cap.read()if not ret:breakframe_count += 1# 每 interval 帧录音 + 声纹识别 + Whisperif frame_count % interval == 0:print("\n[INFO] 正在录音并分析说话人...")audio = sd.rec(int(RECORD_DURATION * SAMPLE_RATE), samplerate=SAMPLE_RATE, channels=1)sd.wait()write("temp.wav", SAMPLE_RATE, audio)# 声纹识别wav = preprocess_wav("temp.wav")embed = encoder.embed_utterance(wav)best_name, best_score = "", 0.5for name, ref in speaker_embeddings.items():sim = np.dot(embed, ref)if sim > best_score:best_score = simbest_name = namecurrent_speaker = best_name if best_score > CONFIDENCE_THRESHOLD else ""# Whisper 语音识别result = asr_model.transcribe("temp.wav", language="zh")current_text = result["text"].strip()print(f"[识别] {current_speaker}:{current_text}")# 人脸检测 + 标注results = yolo_model.predict(frame, classes=[0], conf=0.4, verbose=False)for result in results:boxes = result.boxes.xyxy.cpu().numpy().astype(int)for box in boxes:x1, y1, x2, y2 = boxface_crop = frame[y1:y2, x1:x2]rgb_crop = cv2.cvtColor(face_crop, cv2.COLOR_BGR2RGB)encs = face_recognition.face_encodings(rgb_crop)name = "未知"if encs:matches = face_recognition.compare_faces(known_encodings, encs[0])face_distances = face_recognition.face_distance(known_encodings, encs[0])if True in matches:best_match = np.argmin(face_distances)name = known_names[best_match]# 准备显示信息label = nameif name == current_speaker:label += "(正在讲话)"if current_text:label += f":{current_text}"# 绘图(PIL 支持中文)pil_img = Image.fromarray(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))draw = ImageDraw.Draw(pil_img)draw.rectangle([x1, y1, x2, y2], outline="green", width=2)draw.text((x1, y1 - 30), label, font=font, fill=(255, 0, 0))frame = cv2.cvtColor(np.array(pil_img), cv2.COLOR_RGB2BGR)cv2.imshow("实时人脸 + 声纹 + 字幕识别", frame)if cv2.waitKey(1) & 0xFF == ord("q"):breakcap.release()
cv2.destroyAllWindows()

http://www.dtcms.com/a/278771.html

相关文章:

  • 从“炼丹”到“流水线”——如何用Prompt Engineering把LLM微调成本打下来?
  • 前端缓存优化全景指南:从HTTP到应用层的性能加速实践
  • 学习软件测试的第十五天
  • PHP password_verify() 函数
  • 设备巡检系统的主要用途
  • Java 大视界 -- 基于 Java 的大数据可视化在城市地下管网管理与风险预警中的应用
  • 2025-07-14如何批量下载behance网站里的图片?
  • 神经网络项目--基于FPGA的AI简易项目(1-9图片数字识别)
  • 如何基于FFMPEG 实现视频推拉流
  • liunx常用命令(二)
  • SLAM 前端
  • 一文读懂循环神经网络(RNN)—语言模型+n元语法(1)
  • LightGBM(Light Gradient Boosting Machine)
  • 3分钟搭建自动签到打卡RPA程序:验证码自动识别
  • ImportError: DLL load failed while importing _base: 找不到指定的程序。
  • 深浅拷贝以及函数缓存
  • Node.js + Express的数据库AB View切换方案设计
  • 触想CX-3588主板在安保巡检领域的落地实践:解锁机器人自主智能
  • 【【异世界历险之数据结构世界(二叉树)】】
  • CVE-2025-33073(Windows提权)
  • Popover API 实战指南:前端弹层体验的原生重构
  • 操作系统-第一章操作系统和第二章进程(知识点学习/期末复习/笔试/面试/考研)
  • mpegts.c中handle_packet() 函数代码注释
  • 每天10个单词 20250714 day4
  • CompletableFuture 源码解析
  • vLLM与SGLang在自然语言处理领域的技术架构与性能对比研究
  • Linux中的系统日志(Rsyslog)
  • 【机器人编程基础】python文件的打开和关闭
  • 【Python3教程】Python3高级篇之MySQL - mysql-connector 驱动介绍及示例
  • [论文阅读] 人工智能 + 软件工程 | 用大语言模型+排名机制,让代码评论自动更新更靠谱