当前位置: 首页 > article >正文

《深度学习》Dlib 人脸应用实例 性别年龄预测 案例实现

目录

一、了解代码

1、目的

2、流程

1)模型初始化

2)变量初始化

3)自定义函数

4)自定义函数:

5)视频捕获和处理循环:

二、案例实现

1、初始化模型

代码内容:

2、变量初始化

3、定义函数获取人脸框

4、定义绘制中文文本的函数

5、主循环

运行结果:


一、了解代码

1、目的

        基于OpenCV和深度学习模型的人脸识别年龄估计性别识别系统。它主要通过摄像头实时捕获视频帧,对每一帧进行人脸检测,并对检测到的人脸进行年龄和性别的预测。

2、流程

        1)模型初始化

                加载人脸检测、年龄估计和性别识别的模型。这些模型分别通过其配置文件(prototxt或pbtxt文件)和权重文件(caffemodel或pb文件)进行加载。

        2)变量初始化

                分别定义年龄范围性别选项

        3)自定义函数

                getBoxes用于从视频帧中检测人脸,并返回带有检测到的人脸框的图像和人脸框的坐标列表。使用faceNet模型进行人脸检测,将检测结果中置信度大于0.7的人脸框绘制在图像上。

        4)自定义函数

                定义函数cv2AddChineseText用于在图像上添加中文文本。由于OpenCV原生不支持中文文本绘制,该函数首先将OpenCV图像转换为PIL图像,然后使用PIL的ImageDrawImageFont绘制中文文本,最后再将图像转换回OpenCV格式

        5)视频捕获和处理循环

                使用cv2.VideoCapture打开视频文件(或摄像头,如果路径是设备ID)。在循环中,逐帧读取视频,使用getBoxes函数检测人脸。对于每个检测到的人脸,裁剪出人脸区域,然后分别使用ageNetgenderNet模型进行年龄和性别预测。使用cv2AddChineseText函数将预测结果(年龄和性别)以中文文本的形式绘制在图像上的人脸框上方。显示处理后的图像。如果按下Esc键(ASCII码27),则退出循环。

二、案例实现

1、初始化模型

        提前下载好模型,模型的网址如下:

https://github.com/GilLevi/AgeGenderDeepLearning

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

        代码内容:
import cv2
from PIL import Image, ImageDraw, ImageFont
import numpy as np

"""======模型初始化========"""
# 模型(网络模型/预训练模型):face/aqe/qender(脸、年龄、性别)

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、变量初始化

        初始化设置识别出来的人脸的性别和年龄段,

"""变量初始化"""
# 初始化设置年龄段和性别
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、定义函数获取人脸框

def getBoxes(net, frame):
    frameHeight,frameWidth = frame.shape[:2]   # 获取视频帧的高度、宽度

    # 使用OpenCV中的深度神经网络模块将图像转变成深度神经网络可以识别处理的格式
    # 1.0表示图像的缩放因子
    # 输出blob图像大小为300*300,表示无论输入图像多大都会调整为300*300像素
    # [104,117,123]为图像通道的均值列表,BGR,用于从每个像素减去对应通道均值
    # 第一个True表示是否交换蓝色和红色通道
    # 第二个False表示是否对图像进行归一化处理,即 将每个像素点除以255,以转变为0-1之间的值
    blob = cv2.dnn.blobFromImage(frame, 1.0,(300,300),[104,117,123],True,False)
    net.setInput(blob)  # 调用网络模型,输入上述的blob图片进行人脸检测
    detections = net.forward()  # 对模型进行前向传播

    faceBoxes = []  # faceBoxes存储检测到的人脸边界框坐标
    xx = detections.shape[2]   # 表示前向传播的第三个维度的结果
    for i in range(detections.shape[2]):
        # confidence中每一行保存了7个数据,第3个数据表示置信度,第4,5,6,7分别表示人脸归一化后的坐标位置
        confidence = detections[0, 0, i, 2]

        if confidence > 0.7:  # 筛选一下,将置信度大于0.7侧保留,其余不要了
            x1 = int(detections[0, 0, i, 3] * frameWidth)   # 左边界x
            y1 = int(detections[0, 0, i, 4] * frameHeight)  # 上边界y
            x2 = int(detections[0, 0, i, 5] * frameWidth)   # 右边界x
            y2 = int(detections[0, 0, i, 6] * frameHeight)  # 下边界y
            faceBoxes.append([x1,y1,x2,y2])  # 人脸框的坐标
            # 绘制人脸框
            cv2.rectangle(frame,(x1,y1),(x2,y2),(0,255,0),int(frameHeight/150),6)

        return frame,faceBoxes   # 返回绘制完人脸框的图像和人脸框的坐标

4、定义绘制中文文本的函数

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")
    draw.text(position,text,textColor,font=fontStyle)
    return cv2.cvtColor(np.asarray(img),cv2.COLOR_BGR2RGB)       # 转换回0penCV格式

5、主循环

"""打开摄像头,将每一帧画面传入神经网络中"""
cap = cv2.VideoCapture("人.mp4")   # 装载摄像头
while True:
    _,frame = cap.read()
    #frame = cv2.flip(frame,1)  # 镜像处理

    # 获取人脸包围框、绘制人脸包围框(可能多个)
    frame, faceBoxes = getBoxes(faceNet, frame)   # 将人脸检测模型与读取到的视频帧传入函数,返回绘制人脸框后的图像和人脸框的坐标信息
    if not faceBoxes:  # 没有人脸时检测下一帧图像,后续循坏操作不再继续。
        print("当前镜头中没有人")
        continue
    # 遍历每一个人脸包围框。
    for faceBox in faceBoxes:
        # 处理frame,将其处理为符合DNN输入的格式
        x,y,x1,y1 = faceBox   # 读取边界坐标
        face = frame[y:y1, x:x1]   # 裁剪出来人脸
        blob = cv2.dnn.blobFromImage(face,  1.0, (227,227),mean)   # 将取出的人脸转化为DNN可识别的格式,模型输入格式转化为为227*277
        # 调用模型,预测性别
        genderNet.setInput(blob)   # 将DNN可识别的图像传入性别检测模型
        genderOuts = genderNet.forward()   # 前向传播,返回每个类别的预测得分
        gender = genderList[genderOuts[0].argmax()]  # argmax()返回最大值的索引
        # 调用模型,预测年龄
        ageNet.setInput(blob)
        age0uts = ageNet.forward()
        age = ageList[age0uts[0].argmax()]

        result = "{},{}".format(gender,age)   # 格式化文本(年龄、性别)
        frame = cv2AddChineseText(frame, result, (x,y-30))   # 输出中文性别和年龄
        cv2.imshow("result", frame)

    if cv2.waitKey(1) == 27:
        break
cv2.destroyAllWindows()
cap.release()
        运行结果:


http://www.kler.cn/news/360979.html

相关文章:

  • 传输层协议UDP详解
  • 【OpenGauss源码学习 —— (VecSortAgg)】
  • 集合分类及打印的方式
  • SDUT数据结构与算法第四次机测
  • Prometheus 告警
  • MySQL实现主从同步
  • 一个汉字占几个字节、JS中如何获得一个字符串占用多少字节?
  • 前端性能优化之加载篇
  • ubuntu安装boost、x264、FFMPEG
  • 前端项目中遇到的技术问题
  • 字节流写入文件
  • Java基于SSM微信小程序物流仓库管理系统设计与实现(源码+lw+数据库+讲解等)
  • Linux中安装tesserocr遇到的那些坑
  • go-zero系列-限流(并发控制)及hey压测
  • 【JAVA】第三张_Eclipse下载、安装、汉化
  • ruoyi框架配置多数据源
  • C++11——智能指针
  • 秋招突击——8/6——万得数据面试总结
  • 深度学习 基本函数01
  • Linux-网络命令