使用了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库进行面部检测和面部特征点检测,并通过简单的几何计算实现了微笑检测。在此希望通过本文的讲解,广大读者能够深入理解每一部分代码的功能,并能够在此基础上扩展和改进系统的功能。

  • 11
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WenJGo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值