项目备份

成为她曾经期待的样子 / 2023-08-20 / 原文

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()