表情识别和性别年龄预测

目录

一.表情识别

1.实现方法思路

2.代码实现

①计算嘴的宽高比

②计算嘴宽度、脸颊宽度的比值

③构造脸部位置检测器,读取人脸关键点定位模型

④循环对每一帧操作,获取关键点

⑥根据条件判断表情

⑧释放资源

二.年龄性别预测

1.加载下载后的网络

2.变量初始化

3.自定义函数,获取人脸包围框

4.获取人脸包围框、绘制人脸包围框(可能多个)

5.遍历每一个人脸包围框

6.调用模型,预测性别

7.调用模型,预测年龄

8.展示结果


一.表情识别

1.实现方法思路

人在微笑时,嘴角会上扬,嘴的宽度和与整个脸颊(下颌)的宽度之比变大和嘴部的高度比等。

2.代码实现

①计算嘴的宽高比

python 复制代码
from sklearn.metrics.pairwise import euclidean_distances
def MAR(shape):# 计算嘴的宽高比
    A = euclidean_distances(shape[50].reshape(1,2),shape[58].reshape(1,2))
    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

注意:使用euclidean_distances()方法计算距离必须是二维数据

②计算嘴宽度、脸颊宽度的比值

python 复制代码
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

③构造脸部位置检测器,读取人脸关键点定位模型

python 复制代码
detector = dlib.get_frontal_face_detector()# 构造脸部位置检测器
predictor = dlib.shape_predictor("../关键点定位/shape_predictor_68_face_landmarks.dat")#读取人脸关键点定位模型

④循环对每一帧操作,获取关键点

python 复制代码
cap=cv2.VideoCapture('test3.mp4')
while True:
    ret,frame = cap.read()
    # 获取图片中全部人脸位置
    faces = detector(frame,0)
    for face in faces:
        shape = predictor(frame,face) #获取关键点

⑤将关键点转换为坐标(x,y)的形式 并计算嘴部的高宽比和嘴宽/脸颊宽

python 复制代码
# 将关键点转换为坐标(x,y)的形式
        shape = np.array([[p.x,p.y] for p in shape.parts()])
        mar = MAR(shape)#计算嘴部的高宽比
        mjr = MJR(shape)#计算"嘴宽/脸颊宽"

⑥根据条件判断表情

python 复制代码
        result="正常"#默认是正常表情
        print("mar",mar,"\tmjr",mjr) #测试一下实际值,可以根据该值确定#可更具项目要求调整阀值。
        if mar > 0.5:
            result="大笑"
        elif mjr>0.45: # 超过闽值为微笑
            result="微笑"

⑦构建嘴部凸包并画出

python 复制代码
        mouthHull =cv2.convexHull(shape[48:61]) # 嘴型构造凸包
        frame =cv2_put_text_cn(frame,result,mouthHull[0,0])#多人脸
        cv2.drawContours(frame,[mouthHull],-1,(0,255,0), 1)
    cv2.imshow("Frame",frame)
    if cv2.waitKey(1)== 27:
        break

⑧释放资源

python 复制代码
cv2.destroyAllWindows()
cap.release()

二.年龄性别预测

网络结构图像首先被裁剪为227*227输入网络。

卷积核1:96×3×7×7+ReLU+max pooling3 × 3,stride=2,normalization,输出为96×28×28 。

卷积核2: 256×96×5×5+ReLU+max pooling3×3,stride=2,normalization,输出为256×14×14 。

卷积核3: 384×256×14×14+ReLU+max pooling3×3。

4、全连接:512个神经元+ReLU+dropout

5、全连接:512个神经元+ReLU+dropout

6、output:根据年龄或性别映射到最后的类。

模型下载地址:https://github.com/GilLevi/AgeGenderDeepLearning和

https://github.com/spmallick/learnopencv/blob/master/AgeGender/opencv_face_detector_uint8.pb

1.加载下载后的网络

python 复制代码
import cv2
from PIL import Image, ImageDraw, ImageFont
import numpy as np
faceProto ="model/opencv_face_detector.pbtxt"
faceModel ="model/opencv_face_detector_uint8.pb"
ageProto ="model/deploy_age.prototxt"
ageModel ="model/age_net.caffemodel"
genderProto ="model/deploy_gender.prototxt"
genderModel ="model/gender_net.caffemodel"
#加载网络
ageNet=cv2.dnn.readNet(ageModel,ageProto)
genderNet=cv2.dnn.readNet(genderModel,genderProto)
faceNet=cv2.dnn.readNet(faceModel,faceProto)

2.变量初始化

python 复制代码
ageList=['0-2岁','4-6岁','8-12岁','15-20岁','25-32岁','38-43岁','48-53岁','60-100岁']
genderList=['男性','女性']
mean =(78.4263377603,87.7689143744,114.895847746)#模型均焦

3.自定义函数,获取人脸包围框

python 复制代码
def getBoxes(net,frame):
    frameHeight,frameWidth=frame.shape[:2]
    blob=cv2.dnn.blobFromImage(frame,1.0,(300,300),[104,117,123],True,False)
    net.setInput(blob)
    detections=net.forward()

    faceBoxes=[]
    for i in range(detections.shape[2]):
        confidence=detections[0,0,i,2]
        if confidence>0.7:#筛选一下,将置信度大于0.7侧保留,其余不要了
            x1=int(detections[0,0,i,3]*frameWidth)
            y1 = int(detections[0, 0, i, 4] * frameHeight)
            x2 = int(detections[0, 0, i, 5] * frameWidth)
            y2 = int(detections[0, 0, i, 6] * frameHeight)
            faceBoxes.append([x1,x2,y1,y2])
            # 绘制人脸框
            cv2.rectangle(frame,(x1,y1),(x2,y2),(0,255,0),int(round(frameHeight/150)),6)
    # 返回绘制了人脸框的帧frame、人脸包围框faceBoxes
    return frame, faceBoxes

4.获取人脸包围框、绘制人脸包围框(可能多个)

python 复制代码
cap = cv2.VideoCapture(0)#装载摄像头
while True:
    _,frame = cap.read()
    frame = cv2.flip(frame,1)#镜像处理
    # 获取人脸包围框、绘制人脸包围框(可能多个)
    frame, faceBoxes = getBoxes(faceNet,frame)
    if not faceBoxes:  # 没有人脸时检测下一帧,后续循环操作不再继续。print("当前镜头中没有人")
        continue
复制代码
没有人脸时检测下一帧,后续循环操作不再继续、

5.遍历每一个人脸包围框

复制代码
处理frame,将其处理为符合DNN输入的格式
python 复制代码
    for faceBox in faceBoxes:
    # 处理frame,将其处理为符合DNN输入的格式
        x1, y1, x2, y2 = faceBox
        face = frame[y1:y2, x1: x2]
        blob = cv2.dnn.blobFromImage(face, 1.0, (227,227), mean)  # 模型输入为227*277,参考论文

6.调用模型,预测性别

python 复制代码
# 调用模型,预测性别
        genderNet.setInput(blob)
        genderOuts = genderNet.forward()
        gender = genderList[genderOuts[0].argmax()]

7.调用模型,预测年龄

python 复制代码
# 调用模型,预测年龄
        ageNet.setInput(blob)
        ageOuts = ageNet.forward()
        age = ageList[ageOuts[0].argmax()]

8.展示结果

python 复制代码
        result = "{},{}".format(gender,age)  # 格式化文本(年龄、性别)
        frame =cv2_put_text_cn(frame,result, (x1,y1-30)) #输出中文性别和年龄
        cv2.imshow("result",frame)
    if cv2.waitKey(1)== 27:# 按下ESC键,退出程序
        break
cv2.destroyAllWindows()
cap.release()
相关推荐
apocelipes32 分钟前
golang unique包和字符串内部化
java·python·性能优化·golang
Geoking.1 小时前
NumPy zeros() 函数详解
python·numpy
Full Stack Developme1 小时前
java.text 包详解
java·开发语言·python
丁浩6662 小时前
Python机器学习---2.算法:逻辑回归
python·算法·机器学习
B站_计算机毕业设计之家3 小时前
计算机毕业设计:Python农业数据可视化分析系统 气象数据 农业生产 粮食数据 播种数据 爬虫 Django框架 天气数据 降水量(源码+文档)✅
大数据·爬虫·python·机器学习·信息可视化·课程设计·农业
Q_Q5110082853 小时前
python+uniapp基于微信小程序的旅游信息系统
spring boot·python·微信小程序·django·flask·uni-app·node.js
鄃鳕3 小时前
python迭代器解包【python】
开发语言·python
懷淰メ3 小时前
python3GUI--模仿百度网盘的本地文件管理器 By:PyQt5(详细分享)
开发语言·python·pyqt·文件管理·百度云·百度网盘·ui设计
Q_Q5110082853 小时前
python基于web的汽车班车车票管理系统/火车票预订系统/高铁预定系统 可在线选座
spring boot·python·django·flask·node.js·汽车·php
新子y4 小时前
【小白笔记】普通二叉树(General Binary Tree)和二叉搜索树的最近公共祖先(LCA)
开发语言·笔记·python