You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

YOLOv5困倦检测程序不符合预期,如何修复双眼闭合触发逻辑?

修复YOLOv5困倦检测程序的触发逻辑问题

问题根源

你的代码存在三个核心问题导致功能不符合预期:

  1. YOLOv5结果解析错误:results.xywh返回的是张量,类别存储的是数字索引而非字符串,直接用字符串对比会永远不成立;同时你错误固定了检测框的索引,没有动态遍历所有检测结果。
  2. 触发逻辑错误:你用or判断单个眼睛闭合就触发,但需求是同时检测到双眼闭合才触发。
  3. 无触发冷却:每10ms调用一次detect,会连续触发蜂鸣器并重复计数,导致计数器疯狂增长且蜂鸣不停。

修复方案

  1. 遍历所有检测结果,用model.names将类别索引转换为对应名称。
  2. 检查当前帧是否同时包含R_close和L_close两个类别。
  3. 添加冷却机制,避免短时间内重复触发(比如设置1秒的冷却间隔)。

完整修复代码

import tkinter as tk
import customtkinter as ctk 

import torch
import numpy as np
import time

import cv2
from PIL import Image, ImageTk
import winsound

app = tk.Tk()
app.geometry("600x600")
app.title("Drowsy Boi 4.0")
ctk.set_appearance_mode("dark")

vidFrame = tk.Frame(height=480, width=600)
vidFrame.pack()
vid = ctk.CTkLabel(vidFrame, text='')
vid.pack()

counter = 0 
last_trigger_time = 0  # 记录上次触发时间,用于冷却
COOLDOWN = 1  # 冷却时间(秒)

counterLabel = ctk.CTkLabel(master = app, text=counter, height=40, width=120, font=("Arial", 20), text_color="white", fg_color="blue")
counterLabel.pack(pady=10)

def reset_counter(): 
    global counter
    counter = 0 
resetButton = ctk.CTkButton(master = app, text="Reset Counter", command=reset_counter, height=40, width=120, font=("Arial", 20), text_color="white", fg_color="teal") 
resetButton.pack()

model = torch.hub.load('ultralytics/yolov5', 'custom', path='D:/22.08.17code/monitor/best.pt', force_reload=True)
cap = cv2.VideoCapture(0)

def detect():
    global counter, last_trigger_time
    ret, frame = cap.read()
    if not ret:
        return
    
    frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) 
    results = model(frame)
    img = np.squeeze(results.render())

    # 获取当前帧所有检测到的类别名称
    detected_classes = set()
    # 遍历所有检测框
    for pred in results.pred[0]:
        class_idx = int(pred[5])
        class_name = model.names[class_idx]
        detected_classes.add(class_name)
    
    # 检查是否同时检测到双眼闭合,且处于冷却期外
    current_time = time.time()
    if 'R_close' in detected_classes and 'L_close' in detected_classes:
        if current_time - last_trigger_time > COOLDOWN:
            winsound.Beep(frequency=440, duration=500)  # 缩短蜂鸣时长避免刺耳
            counter += 1
            last_trigger_time = current_time

    imgarr = Image.fromarray(img)
    imgtk = ImageTk.PhotoImage(imgarr) 
    vid.imgtk = imgtk
    vid.configure(image=imgtk)
    counterLabel.configure(text=counter)
    vid.after(10, detect) 

detect()
app.mainloop()

关键改动说明

  • 使用results.pred[0]遍历所有检测框,通过model.names将类别索引转为名称,确保类别判断准确。
  • 用set存储检测到的类别,方便快速判断是否同时存在R_close和L_close。
  • 添加last_trigger_time和COOLDOWN变量,控制触发间隔,避免连续蜂鸣和重复计数。
  • 增加ret的判断,避免摄像头读取失败时程序出错。

内容的提问来源于stack exchange,提问作者CW K

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 05:43:26