YOLOv5困倦检测程序不符合预期,如何修复双眼闭合触发逻辑?
修复YOLOv5困倦检测程序的触发逻辑问题
问题根源
你的代码存在三个核心问题导致功能不符合预期:
- YOLOv5结果解析错误:
results.xywh返回的是张量,类别存储的是数字索引而非字符串,直接用字符串对比会永远不成立;同时你错误固定了检测框的索引,没有动态遍历所有检测结果。 - 触发逻辑错误:你用
or判断单个眼睛闭合就触发,但需求是同时检测到双眼闭合才触发。 - 无触发冷却:每10ms调用一次
detect,会连续触发蜂鸣器并重复计数,导致计数器疯狂增长且蜂鸣不停。
修复方案
- 遍历所有检测结果,用
model.names将类别索引转换为对应名称。 - 检查当前帧是否同时包含
R_close和L_close两个类别。 - 添加冷却机制,避免短时间内重复触发(比如设置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
相关产品推荐
相关产品推荐

