我们将探讨如何使用OpenCV和YOLO目标检测模型来检测视频中的眼睛闭合,并在眼睛闭合超过特定阈值时发出警告。我们还将讨论将这种方法应用于实时检测的可能性。眼睛闭合检测在许多现实世界的应用中都是一个重要的用例,从监控驾驶员疲劳到确保关键环境中的警觉性。
先决条件
在开始之前,请确保已安装以下库:
- OpenCV:用于视频处理和显示结果。
- Ultralytics YOLO:一个流行且高效的深度学习模型,用于目标检测。
要安装必要的库,你可以运行:
pip install opencv-python
pip install ultralytics
眼睛闭合检测算法概述
- 加载YOLO模型:我们加载一个预训练的YOLO模型(best.pt)用于眼睛检测。这个模型被训练来识别两种状态:“闭合”和“打开”的眼睛。下载模型
- 读取输入视频:使用OpenCV逐帧读取视频。
- 执行目标检测:使用YOLO检测每帧中眼睛的状态。
- 跟踪眼睛闭合持续时间:如果检测到眼睛“闭合”超过指定阈值,将显示警告。
- 显示结果:结果被写入输出视频文件,如果需要,警告消息会被叠加在帧上。
逐步实现
以下是使用YOLO和OpenCV检测视频中眼睛闭合的完整Python代码:
import cv2
from ultralytics import YOLO
# Load the pre-trained YOLO model
model = YOLO("best.pt")
names = model.names
# Open the video file
cap = cv2.VideoCapture("video.mp4")
assert cap.isOpened(), "Error reading video file"
w, h, fps = (int(cap.get(x)) for x in (cv2.CAP_PROP_FRAME_WIDTH, cv2.CAP_PROP_FRAME_HEIGHT, cv2.CAP_PROP_FPS))
# Initialize video writer to save the output
video_writer = cv2.VideoWriter("output.avi", cv2.VideoWriter_fourcc(*"mp4v"), fps, (w, h))
# Initialize variables for eye closure detection
eye_closed_frames = 0
eye_closed_threshold_seconds = 1 # Threshold in seconds
eye_closed_threshold_frames = eye_closed_threshold_seconds * fps # Convert seconds to frames
while cap.isOpened():
success, im0 = cap.read()
if not success:
print("Video frame is empty or video processing has been successfully completed.")
break
# Predict the state of the eyes using YOLO
results = model.predict(im0, show=False)
boxes = results[0].boxes.xyxy.cpu().tolist()
clss = results[0].boxes.cls.cpu().tolist()
annotator = Annotator(im0, line_width=2, example=names)
eye_closed = False # Flag to check if the eye is closed in the current frame
If boxes are not None:
for box, cls in zip(boxes, clss):
clsName = names[int(cls)]
xmax = int(box[0])
ymin = int(box[1])
xmin = int(box[2])
ymax = int(box[3])
# Set color based on the class name
if clsName == 'closed':
clr = (0, 0, 255)
eye_closed = True # Mark eye as closed
elif clsName == 'opened':
clr = (0, 255, 0)
# Draw the bounding box and label
cv2.FONT_HERSHEY_SIMPLEX
Font_scale = 1
Font_thickness = 2
tw, th = cv2.getTextSize(clsName, font, font_scale, font_thickness)[0]
cv2.rectangle(im0, (xmin, ymin), (xmax, ymax), color=clr, thickness=2)
cv2.putText(im0, clsName, (xmax, ymin - 5), font, font_scale, color=clr, thickness=font_thickness)
# Check for eye closure duration
if eye_closed:
Eye_closed_frames += 1
else:
# Reset counter if the eye is not closed
# Display warning if eye has been closed for more than the threshold
if eye_closed_frames > eye_closed_threshold_frames:
print("Warning: Eye has been closed for more than 2 seconds!")
cv2.putText(im0, "WARNING: Eye closed for more than 2 seconds!", (50, 50), font, font_scale, (0, 0, 255), font_thickness)
# Write the processed frame to the output video
video_writer.write(im0)
# Release resources
cap.release()
video_writer.release()
代码解释
- 模型加载:使用ultralytics库中的YOLO类加载YOLO模型,并提取类名。
- 视频处理:使用cv2.VideoCapture打开输入视频,并初始化视频写入器以保存输出。
- 逐帧检测:逐帧处理视频。对于每一帧,使用YOLO模型检测眼睛并将其分类为“闭合”或“打开”。
- 眼睛闭合检测:计数器(eye_closed_frames)跟踪眼睛被检测为“闭合”的连续帧数。如果这个计数超过阈值(在这种情况下,是1秒钟的帧数),则显示警告消息。
- 警告消息显示:每当眼睛闭合超过阈值持续时间时,警告消息就会动态叠加在视频上。
实时检测的可能性
上述方法可以适应使用网络摄像头或实时视频流进行实时检测。以下是如何实现这一点的方法:
- 捕获实时视频:将视频文件输入更改为实时视频流,方法是将cv2.VideoCapture参数更改为0(默认网络摄像头)。
cap = cv2.VideoCapture(0) # Use 0 for the default camera, or 1, 2, etc. for other cameras
- 优化实时性能:为确保流畅的实时性能,你可能需要通过使用较小的模型(如YOLOv5s)或在可用的情况下在GPU上运行来优化模型推理速度。
- 实时显示结果:使用cv2.imshow()实时显示视频流:
cv2.imshow("Eye Closure Detection", im0) if cv2.waitKey(1) & 0xFF == ord('q'): # Press 'q' to quit break
结合YOLO和OpenCV,你可以有效地检测视频或甚至实时中的眼睛闭合。这项技术在许多实际应用中都有应用,包括驾驶员监控系统、疲劳检测和在各种安全关键领域中的警觉性验证。通过利用像YOLO这样的深度学习模型,你可以在检测微妙的面部表情(如眼睛闭合)方面实现高准确性和性能。