import cv2
import dlib
import threading
import queue
import math
import time
start_time=time.time() #初始化计数器
minute_ant=0
minute_cnt=0
def euclidean_distance(p1, p2):
return math.sqrt((p1[0] - p2[0])**2 + (p1[1] - p2[1])**2)
def detect_faces():
global start_time, minute_ant, minute_cnt # 引入全局变量
ant = 0 # 初始化闭眼次数
cnt=0 #嘴巴张开次数
while True:
ret, frame = capture.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
faces = detector(gray, 1)
avg_brightness = int(gray.mean())
# 检查光线亮度,显示光线暗的提醒
if avg_brightness < 30:
cv2.putText(frame, "Light is too dim open Zero-dce", (10, 110), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 255), 2)
for face in faces:
cv2.rectangle(frame, (face.left(), face.top()), (face.right(), face.bottom()), (0, 255, 0), 2)
shape = predictor(gray, face)
# 左眼关键点坐标提取
left_eye_coords = [(shape.part(i).x, shape.part(i).y) for i in range(36, 42)]
# 右眼关键点坐标提取
right_eye_coords = [(shape.part(i).x, shape.part(i).y) for i in range(42, 48)]
# 嘴巴关键坐标提取
mouth1x=shape.part(49).x
mouth1y = shape.part(49).y
mouth2x = shape.part(51).x
mouth2y = shape.part(51).y
mouth3x = shape.part(53).x
mouth3y= shape.part(53).y
mouth4x = shape.part(55).x
mouth4y = shape.part(55).y
mouth5x = shape.part(57).x
mouth5y = shape.part(57).y
mouth6x = shape.part(59).x
mouth6y = shape.part(59).y
mdata1 = math.sqrt((mouth2x - mouth6x) * (mouth2x - mouth6x) + (mouth2y - mouth6y) * (mouth2y - mouth6y)) + math.sqrt((mouth3x - mouth5x) * (mouth3x - mouth5x) + (mouth3y - mouth5y) * (mouth3y - mouth5y))
mdata2 = 2 * math.sqrt((mouth1x - mouth4x) * (mouth1x - mouth4x) + (mouth1y - mouth4y) * (mouth1y - mouth4y));
mouth = mdata1 / mdata2
# 计算左眼 EAR
dataLE1 = euclidean_distance(left_eye_coords[1], left_eye_coords[5]) + euclidean_distance(left_eye_coords[2], left_eye_coords[4])
dataLE2 = 2 * euclidean_distance(left_eye_coords[0], left_eye_coords[3])
Leye = dataLE1 / dataLE2
# 计算右眼 EAR
dataRE1 = euclidean_distance(right_eye_coords[1], right_eye_coords[5]) + euclidean_distance(right_eye_coords[2], right_eye_coords[4])
dataRE2 = 2 * euclidean_distance(right_eye_coords[0], right_eye_coords[3])
Reye = dataRE1 / dataRE2
avg = (Reye + Leye) * 0.5 #计算平均值
if avg < 0.18:
ant += 1 # 闭眼次数累加
minute_ant+=1
# 在图像上显示统计信息
if mouth>=0.75:
cnt+=0.1
minute_cnt+=0.1
cv2.putText(frame, f" eye count: {ant}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 255), 2)
cv2.putText(frame, f"month count: {cnt}", (10, 70), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 255), 2)
elapsed_time = time.time() - start_time
if elapsed_time >= 60:
if(minute_cnt>=3 and minute_ant>=20):
cv2.putText(frame,f"You seem fatigued",(10,120),cv2.FONT_HERSHEY_SIMPLEX,0.8,(0,0,255),2)
print(f"时间 {int(elapsed_time / 60)} - 眨眼次数: {minute_ant}, 嘴巴张开次数: {minute_cnt}")
start_time = time.time() # 重置开始时间
minute_ant = 0 # 重置闭眼次数
minute_cnt = 0 # 重置嘴巴张开次数
frames_queue.put(frame)
capture = cv2.VideoCapture(0)
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")
frames_queue = queue.Queue()
# 创建并启动人脸检测线程
face_detection_thread = threading.Thread(target=detect_faces)
face_detection_thread.start()
while True:
if not frames_queue.empty():
frame = frames_queue.get()
cv2.imshow("face", frame)
if cv2.waitKey(1) & 0xFF == ord(' '):
break
capture.release()
cv2.destroyAllWindows()