修改眨眼检测代码实现蜂鸣器按EAR阈值自动启停的求助
代码修改方案
核心修改点如下:
- 修正原代码阻塞问题:删除蜂鸣器触发逻辑中的
time.sleep()阻塞调用,避免主循环卡住无法实时检测EAR变化 - 调整阈值匹配需求:新增两级EAR阈值,
EAR_HIGH_THRESH=0.2(高于该值直接禁用蜂鸣器)、EAR_LOW_THRESH=0.1(低于该值才开始累计触发时长) - 新增蜂鸣器即时关闭逻辑:当EAR高于阈值、重置报警状态时,直接拉低蜂鸣器GPIO电平,实现睁眼立即停响
- 修正原代码的导入遗漏:补全
time.sleep的模块前缀,避免运行报错 - 调整触发帧计数:按30FPS摄像头、持续3秒触发的需求,将连续帧阈值设为90,可根据自己的摄像头帧率自行调整(要N秒触发就设为 帧率*N)
修改后完整代码
# 导入必要的包 from imutils.video import VideoStream from imutils import face_utils import numpy as np import argparse import imutils import time import dlib import cv2 def euclidean_dist(ptA, ptB): # 计算并返回两个点之间的欧氏距离 return np.linalg.norm(ptA - ptB) def eye_aspect_ratio(eye): # 计算两组垂直眼周关键点(x,y)坐标之间的欧氏距离 A = euclidean_dist(eye[1], eye[5]) B = euclidean_dist(eye[2], eye[4]) # 计算水平眼周关键点(x,y)坐标之间的欧氏距离 C = euclidean_dist(eye[0], eye[3]) # 计算眼睛纵横比EAR ear = (A + B) / (2.0 * C) # 返回眼睛纵横比 return ear # 构造参数解析器并解析参数 ap = argparse.ArgumentParser() ap.add_argument("-c", "--cascade", required=True, help = "人脸级联分类器文件路径") ap.add_argument("-p", "--shape-predictor", required=True, help="人脸关键点预测器文件路径") ap.add_argument("-a", "--alarm", type=int, default=0, help="是否使用TrafficHat蜂鸣器的布尔标识") args = vars(ap.parse_args()) # 检查是否使用GPIO/TrafficHat作为报警设备 if args["alarm"] > 0: import RPi.GPIO as GPIO GPIO.setwarnings(False) GPIO.setmode(GPIO.BCM) buzzer=18 GPIO.setup(buzzer,GPIO.OUT) print("[INFO] 使用蜂鸣器报警...") # --------------------------修改部分:阈值调整-------------------------- # 两级EAR阈值 EAR_LOW_THRESH = 0.1 # 低于该值开始累计触发时长 EAR_HIGH_THRESH = 0.2 # 高于等于该值直接禁止报警 # 按30FPS、3秒触发计算,可根据需求调整 EYE_AR_CONSEC_FRAMES = 90 # 初始化帧计数器以及标识报警是否开启的布尔变量 COUNTER = 0 ALARM_ON = False # --------------------------修改结束-------------------------- # 加载OpenCV的Haar级联分类器用于人脸检测(比dlib内置的HOG检测器更快,但准确率更低),然后创建人脸关键点预测器 print("[INFO] 加载人脸关键点预测器...") detector = cv2.CascadeClassifier(args["cascade"]) predictor = dlib.shape_predictor(args["shape_predictor"]) # 分别获取左右眼对应的面部特征点索引 (lStart, lEnd) = face_utils.FACIAL_LANDMARKS_IDXS["left_eye"] (rStart, rEnd) = face_utils.FACIAL_LANDMARKS_IDXS["right_eye"] # 启动视频流线程 print("[INFO] 启动视频流线程...") vs = VideoStream(src=0).start() # vs = VideoStream(usePiCamera=True).start() time.sleep(1.0) while True: # 从线程化视频文件流中抓取帧,调整大小并转换为灰度图 frame = vs.read() frame = imutils.resize(frame, width=450) gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) # 在灰度帧中检测人脸 rects = detector.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30), flags=cv2.CASCADE_SCALE_IMAGE) # 遍历检测到的人脸 for (x, y, w, h) in rects: # 从Haar级联检测的边界框构造dlib矩形对象 rect = dlib.rectangle(int(x), int(y), int(x + w), int(y + h)) # 确定人脸区域的人脸关键点,然后将人脸关键点(x,y)坐标转换为NumPy数组 shape = predictor(gray, rect) shape = face_utils.shape_to_np(shape) # 提取左右眼坐标,然后使用坐标计算双眼的眼睛纵横比 leftEye = shape[lStart:lEnd] rightEye = shape[rStart:rEnd] leftEAR = eye_aspect_ratio(leftEye) rightEAR = eye_aspect_ratio(rightEye) # 计算双眼的平均眼睛纵横比 ear = (leftEAR + rightEAR) / 2.0 # 计算左右眼的凸包,然后可视化每只眼睛 leftEyeHull = cv2.convexHull(leftEye) rightEyeHull = cv2.convexHull(rightEye) cv2.drawContours(frame, [leftEyeHull], -1, (0, 255, 0), 1) cv2.drawContours(frame, [rightEyeHull], -1, (0, 255, 0), 1) # --------------------------修改部分:逻辑调整-------------------------- if ear < EAR_LOW_THRESH: # EAR低于0.1才开始计数 COUNTER += 1 # 计数达到阈值触发报警 if COUNTER >= EYE_AR_CONSEC_FRAMES: if not ALARM_ON: ALARM_ON = True # 开启蜂鸣器,删除阻塞的sleep逻辑 if args["alarm"] > 0: GPIO.output(buzzer, GPIO.HIGH) # 在帧上绘制报警提示 cv2.putText(frame, "DROWSINESS ALERT!", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2) elif ear >= EAR_HIGH_THRESH: # EAR高于等于0.2,直接重置计数器、关闭报警 COUNTER = 0 if ALARM_ON: ALARM_ON = False # 立即关闭蜂鸣器 if args["alarm"] > 0: GPIO.output(buzzer, GPIO.LOW) # EAR在0.1~0.2之间时,保持当前计数器和报警状态不变 # --------------------------修改结束-------------------------- # 在帧上绘制计算得到的眼睛纵横比,用于调试和设置正确的眼睛纵横比阈值和帧计数器 cv2.putText(frame, "EAR: {:.3f}".format(ear), (300, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 255), 2) # 显示帧 cv2.imshow("Frame", frame) key = cv2.waitKey(1) & 0xFF # 如果按下`q`键,则跳出循环 if key == ord("q"): break # 清理资源 if args["alarm"]>0: GPIO.output(buzzer, GPIO.LOW) GPIO.cleanup() cv2.destroyAllWindows() vs.stop()
内容的提问来源于stack exchange,提问作者이수환
相关产品推荐
相关产品推荐

