自学内容网 自学内容网

《深度学习》Dlib库 人脸应用实例 表情识别

目录

一、了解代码

1、简介

2、流程

二、案例实现

1、脸部关键点位置

2、字体文件

3、完整代码

1)调试模式

2)运行结果


一、了解代码

1、简介

        代码内容为一个人脸表情识别程序,它使用dlib库进行人脸检测形状预测(即关键点定位),然后基于这些关键点计算特征值来判断人脸的表情(正常、微笑、大笑)。程序还使用opencv-python(cv2)库来处理视频帧和绘制结果,以及PIL库来在图像上添加中文文本

2、流程

  1. 定义两个函数MARMJR,用于计算嘴的宽高比嘴宽度与脸颊宽度的比值。
  2. 定义一个函数cv2AddChineseText,用于向图片中添加中文
  3. 使用dlib库中的get_frontal_face_detector()函数构造脸部位置检测器detector,并使用shape_predictor()函数读取人脸关键点定位模型predictor
  4. 打开视频文件,用cv2.VideoCapture()函数捕获视频。
  5. 进入视频读取的循环中,读取一帧视频数据。
  6. 使用detector函数检测脸部位置,返回检测到的脸部区域。
  7. 遍历每个检测到的脸部区域,使用predictor函数获取关键点位置。
  8. 将关键点位置转换为坐标形式。
  9. 调用MAR和MJR函数计算嘴的宽高比和嘴宽度与脸颊宽度的比值。
  10. 根据计算结果判断表情,并将表情结果添加到图像中。
  11. 使用cv2AddChineseText函数将中文结果添加到图像中。
  12. 使用cv2.drawContours函数绘制嘴型的凸包
  13. 显示带有结果标记的图像

二、案例实现

1、脸部关键点位置

2、字体文件

        地址:C:\Windows\Fonts

3、完整代码

import numpy as np
import dlib
import cv2
from sklearn.metrics.pairwise import euclidean_distances
from PIL import Image, ImageDraw, ImageFont

def MAR(shape):  # 计算嘴的宽高比
    x = shape[50]   # 举例,此处表示第50个特征点的坐标
    y = shape[50].reshape(1,2)    # reshape重塑坐标点的形状为一个1行2列的数组
    # euclidean_distances函数为计算两个点之间的欧几里得距离
    A = euclidean_distances(shape[50].reshape(1, 2), shape[58].reshape(1,2))   # 计算特征点50到58之间的距离,即嘴唇第一个位置高度
    B = euclidean_distances(shape[51].reshape(1, 2), shape[57].reshape(1,2))   # 计算嘴唇第二个高度
    C = euclidean_distances(shape[52].reshape(1, 2), shape[56].reshape(1,2))   # 计算第三个高度
    D = euclidean_distances(shape[48].reshape(1, 2), shape[54].reshape(1,2))   # 计算宽度
    return ((A + B + C) / 3) / D   # 返回宽高比

def MJR(shape):  # 计算嘴宽度、脸颊宽度的比值
    M = euclidean_distances(shape[48].reshape(1,2),shape[54].reshape(1,2))
    J = euclidean_distances(shape[3].reshape(1,2),shape[13].reshape(1,2))
    return M/J

def cv2AddChineseText(img,text,position,textColor=(0,255,0),textSize=30):
    """向图片中添加中文"""
    if (isinstance(img,np.ndarray)):  # 判断是否0penCV图片类型
        img = Image.fromarray(cv2.cvtColor(img,cv2.COLOR_BGR2RGB))  # 实现array到image的转换
    draw = ImageDraw.Draw(img)  # 在img图片上创建一个绘图的对象
    # 字体的格式
    fontStyle = ImageFont.truetype("STXINGKA.TTF",textSize,encoding = "utf-8")  # STXINGKA.TTF为Windows自带的字体风格文件  地址为C:\Windows\Fonts
    draw.text(position,text,textColor,font=fontStyle)
    return cv2.cvtColor(np.asarray(img),cv2.COLOR_BGR2RGB)       # 转换回0penCV格式


detector = dlib.get_frontal_face_detector()  # 构造脸部位置检测器
predictor = dlib.shape_predictor('shape_predictor_68_face_landmarks.dat')  # 读取人脸68关键点定位模型
cap = cv2.VideoCapture('特朗普.mp4')   # 打开视频
while True:
    ret,frame = cap.read()   # 读取每一帧照片
    faces = detector(frame,0)   # 调用脸部检测器对每一帧图像进行检测,0表示进行0次上采样,返回检测到的人脸矩形框坐标,左上角和右下角坐标
    for face in faces:   # 遍历检测到的人脸
        shape = predictor(frame,face)   # 根据检测到的面部位置,查找原图frame中脸部位置的特征点
        # 将关键点转换为坐标(x,y)形式
        shape = np.array([[p.x,p.y] for p in shape.parts()])  # shape.parts()表示获取面部特征点的迭代器,通过迭代返回每个特征点的坐标,共68组,转化为数组类型
        mar = MAR(shape)   # 计算嘴部的高宽比
        mjr = MJR(shape)   # 计算嘴宽/脸颊宽
        result = "正常"   # 默认是正常表情
        print("mar", mar, "\tmjr", mjr)  # 测试一下实际值,可以根据该值确定
        if mar > 0.5:   # 可更具项目要求调整闽值。
            result = "大笑"
        elif mjr > 0.45:  # 超过阈值为微笑
            result = "微笑"
        # frame = cv2AddChineseText(frame, result,(50,100))  # 输出中文,在指定位置坐标展示
        # cv2.putText # 只能输出英文
        mouthHull = cv2.convexHull(shape[48:61])  # 计算嘴型构造的点集的凸包,位置为关键点48到60
        # 凸包是一个最小的凸多边形,它能够包含给定点集中的所有点。
        frame = cv2AddChineseText(frame,result,mouthHull[0,0])  # 多人脸绘制中文,参数为原图、结果、绘制文本位置为凸包的第一个顶点
        cv2.drawContours(frame,[mouthHull],-1,(0,255,0), 1)  # 绘制轮廓
    cv2.imshow("Frame",frame)
    if cv2.waitKey(1) == 27:
        break
cv2.destroyAllWindows()
cap.release()

1)调试模式

        2)运行结果


原文地址:https://blog.csdn.net/qq_64603703/article/details/143082537

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!