使用了Mediapipe库进行面部检测和面部特征点检测,并通过简单的几何计算实现了微笑检测

        本文将详细讲解一个利用OpenCV和Mediapipe库实现的实时面部表情识别系统。我们将逐行分析代码,解释其各部分的功能和实现细节。希望通过这篇文章,读者能够深入理解这段代码,并能独立实现类似的项目。

分部详解

导入库
import cv2 import mediapipe as mp import time

首先,我们需要导入所需的库:

  • cv2 是OpenCV库,用于图像处理和计算机视觉。
  • mediapipe 是一个跨平台的机器学习库,专门用于实时计算机视觉应用。
  • time 用于计算帧率(FPS)。
  • 初始化Mediapipe模块
    mp_face_detection = mp.solutions.face_detection mp_drawing = mp.solutions.drawing_utils mp_face_mesh = mp.solutions.face_mesh

    我们需要初始化Mediapipe的几个模块:

  • mp_face_detection 用于面部检测。
  • mp_drawing 用于在图像上绘制检测结果。
  • mp_face_mesh 用于面部特征点检测。
  • 初始化摄像头
    cap = cv2.VideoCapture(0)

    cv2.VideoCapture(0) 用于打开默认摄像头(索引为0),以便获取实时视频流。

    初始化Face Detection和Face Mesh模型
    with mp_face_detection.FaceDetection(min_detection_confidence=0.5) as face_detection, \ mp_face_mesh.FaceMesh(min_detection_confidence=0.1, min_tracking_confidence=0.1) as face_mesh:

    我们使用 with 语句来初始化Face Detection和Face Mesh模型:

  • min_detection_confidencemin_tracking_confidence 是两个重要的参数,用于控制模型的检测和追踪信心阈值。
  • 初始化FPS计算
    start_time = time.time() frame_count = 0

    我们使用 start_timeframe_count 来计算每秒帧数(FPS),以评估系统的实时性能。

    读取和处理视频帧
    while cap.isOpened(): ret, frame = cap.read() if not ret: break

    进入视频读取和处理的主循环。在每一帧中:

  • cap.read() 读取视频帧。
  • if not ret: break 检查是否成功读取帧,如果失败则退出循环。
  • 图像转换
    rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)

    Mediapipe需要RGB格式的图像,因此我们需要将每帧从BGR转换为RGB。

    面部检测
    results_detection = face_detection.process(rgb_frame)

    调用 face_detection.process(rgb_frame) 对帧进行面部检测,并将结果存储在 results_detection 中。

    面部特征点检测
    results_mesh = face_mesh.process(rgb_frame)

    调用 face_mesh.process(rgb_frame) 对帧进行面部特征点检测,并将结果存储在 results_mesh 中。

    绘制检测结果
    if results_detection and results_detection.detections: for detection in results_detection.detections: mp_drawing.draw_detection(frame, detection)

    如果检测到面部,我们使用 mp_drawing.draw_detection(frame, detection) 在帧上绘制面部检测结果。

    绘制面部特征点
    if results_mesh and results_mesh.multi_face_landmarks: for face_landmarks in results_mesh.multi_face_landmarks: mp_drawing.draw_landmarks(frame, face_landmarks)

    如果检测到面部特征点,我们使用 mp_drawing.draw_landmarks(frame, face_landmarks) 在帧上绘制面部特征点。

    简单的面部表情识别
    left_lip = face_landmarks.landmark[61] right_lip = face_landmarks.landmark[291] upper_lip = face_landmarks.landmark[13] lower_lip = face_landmarks.landmark[14] lip_distance = abs(upper_lip.y - lower_lip.y) lip_width = abs(left_lip.x - right_lip.x) if lip_distance / lip_width > 0.05: expression = "Smiling" else: expression = "Neutral"

    这里我们添加了一个简单的面部表情识别功能:

  • 提取嘴唇的四个关键点:左嘴角、右嘴角、上嘴唇和下嘴唇。
  • 计算嘴唇上下边缘的距离和嘴唇的宽度。
  • 使用简单的比率判断是否在微笑。
  • 显示面部表情
    cv2.putText(frame, f'Expression: {expression}', (10, 60), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)

    在帧上显示检测到的面部表情。

    计算和显示FPS
    frame_count += 1 elapsed_time = time.time() - start_time fps = frame_count / elapsed_time cv2.putText(frame, f'FPS: {fps:.2f}', (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)

    计算并显示FPS,方便我们评估系统的性能。

    显示结果
    cv2.imshow('Facial Expression Analysis', frame) if cv2.waitKey(1) & 0xFF == ord('q'): break

    使用 cv2.imshow 显示结果,并监听键盘事件,当按下 q 键时退出循环。

    释放资源
    cap.release() cv2.destroyAllWindows()

    释放摄像头资源并关闭所有窗口。

    整体代码

    import cv2
    import mediapipe as mp
    import time
    
    # 初始化Mediapipe Face模块
    mp_face_detection = mp.solutions.face_detection
    mp_drawing = mp.solutions.drawing_utils
    mp_face_mesh = mp.solutions.face_mesh
    
    # 初始化摄像头
    cap = cv2.VideoCapture(0)
    
    # 初始化Face Detection和Face Mesh模型
    with mp_face_detection.FaceDetection(min_detection_confidence=0.5) as face_detection, \
         mp_face_mesh.FaceMesh(min_detection_confidence=0.1, min_tracking_confidence=0.1) as face_mesh:
    
        # 初始化FPS计算
        start_time = time.time()
        frame_count = 0
    
        while cap.isOpened():
            # 读取视频帧
            ret, frame = cap.read()
            if not ret:
                break
    
            # 将图像转换为RGB格式
            rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    
            # 进行Face Detection
            results_detection = face_detection.process(rgb_frame)
    
            # 进行Face Mesh
            results_mesh = face_mesh.process(rgb_frame)
    
            # 如果检测到面部
            if results_detection and results_detection.detections:
                for detection in results_detection.detections:
                    mp_drawing.draw_detection(frame, detection)
    
            # 如果检测到面部并提取到了面部特征点
            if results_mesh and results_mesh.multi_face_landmarks:
                for face_landmarks in results_mesh.multi_face_landmarks:
                    mp_drawing.draw_landmarks(frame, face_landmarks)
    
                    # 简单的面部表情识别(如微笑检测)
                    left_lip = face_landmarks.landmark[61]
                    right_lip = face_landmarks.landmark[291]
                    upper_lip = face_landmarks.landmark[13]
                    lower_lip = face_landmarks.landmark[14]
    
                    lip_distance = abs(upper_lip.y - lower_lip.y)
                    lip_width = abs(left_lip.x - right_lip.x)
    
                    # 设定一个简单的阈值来判断微笑
                    if lip_distance / lip_width > 0.05:
                        expression = "Smiling"
                    else:
                        expression = "Neutral"
    
                    # 在帧上显示面部表情
                    cv2.putText(frame, f'Expression: {expression}', (10, 60), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
    
            # 计算FPS
            frame_count += 1
            elapsed_time = time.time() - start_time
            fps = frame_count / elapsed_time
    
            # 在帧上显示FPS
            cv2.putText(frame, f'FPS: {fps:.2f}', (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2)
    
            # 显示结果
            cv2.imshow('Facial Expression Analysis', frame)
    
            # 检测按键,按 'q' 键退出循环
            if cv2.waitKey(1) & 0xFF == ord('q'):
                break
    
        # 释放资源
        cap.release()
        cv2.destroyAllWindows()
    

    效果展示

    微笑,基本上只要你不哭,一般就判断为微笑了。

    这里不微笑的时候,一定要正对摄像头,不然很容易导致识别不灵敏。

    当然了,你也可以不绘制脸部的点,这样可能会显著提升一点FPS帧数。

    结论

            通过这段代码,我们实现了一个实时的面部表情识别系统。我们使用了Mediapipe库进行面部检测和面部特征点检测,并通过简单的几何计算实现了微笑检测。在此希望通过本文的讲解,广大读者能够深入理解每一部分代码的功能,并能够在此基础上扩展和改进系统的功能。

    作者:WenJGo

    物联沃分享整理
    物联沃-IOTWORD物联网 » 使用了Mediapipe库进行面部检测和面部特征点检测,并通过简单的几何计算实现了微笑检测

    发表回复