在YOLOv8中实时检测时播放音频文件

0 投票
1 回答
33 浏览
提问于 2025-04-14 15:36

我正在做一个YOLOv8项目,目的是检测疲劳状态,并在检测到疲劳时播放一个警报音频文件。现在我遇到的问题是,我无法实时播放音频,因为我的检测结果最开始是存储在一个结果列表里的。等我关闭检测窗口后,程序才会访问这个结果列表,然后才开始不停地播放音频。我该怎么解决这个问题呢?

import os
from ultralytics import YOLO

import torch
import matplotlib
import numpy as np
import cv2
import pygame  

pygame.init()
sound_to_play = pygame.mixer.Sound(r'D:\ML\Syncronised vigilance for driver\alarm.wav')  
sound_to_play.play()

model = YOLO(r'C:\Users\HP\Downloads\last.pt')

cap = cv2.VideoCapture(0) 
while True:
    ret, frame = cap.read()

    results = model.predict(source="0",show=True)  
    for r in results:
        if len(r.boxes.cls)>0:
            dclass=r.boxes.cls[0].item()
            print(dclass)
            if dclass==2.0:
              sound_to_play.play()
    if cv2.waitKey(1) == ord('q'):
        break

pygame.quit()
cap.release()
cv2.destroyAllWindows()

问题在于我的代码首先进行检测并将结果存储在一个列表中,然后才进入循环。我希望的结果是能够同时进行检测和检查类别值。

1 个回答

1

正如你所说,目前的代码是先对整个视频进行检测,因为它在 results = model.predict(source="0",show=True) 中是这样设置的。你需要做的是把每一帧单独传给 predict() 函数,这样才能执行后面的逻辑。你可以通过两种方式来实现。第一种是使用 stream=True,这会用到一个生成器,只在内存中保留当前帧的结果。你可以查看这个 文档,里面有个例子。代码大概会是这样的(可能需要根据具体情况做一些调整):

model = YOLO(r'last.pt')
results = model.predict(source="0", show=True, stream=True)
for r in results:
    # logic for playing sound if the condition was fulfilled
    if len(r.boxes.cls)>0:
            dclass=r.boxes.cls[0].item()
            print(dclass)
            if dclass==2.0:
              sound_to_play.play()
    # you may need to use this statement to activate show=True option
    #next(results)

另一种方法是手动遍历每一帧(就像你现在做的那样),然后把它们一个一个传给 predict() 函数,像这样 source=frame

cap = cv2.VideoCapture(0) 
while True:
    ret, frame = cap.read()
    results = model.predict(source=frame, show=True)  
    for r in results:
        if len(r.boxes.cls)>0:
            dclass=r.boxes.cls[0].item()
            print(dclass)
            if dclass==2.0:
              sound_to_play.play()

你可能还需要添加一些额外的代码,以便在这些情况下正确执行 show=True 选项。

撰写回答