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

【进阶OpenCV】 (22) --年龄性别预测

文章目录

  • 年龄性别预测
    • 1. 模型初始化
    • 2. 初始化变量
    • 3. 获取人脸包围框
    • 4. 调用中文
    • 5. 主循环
    • 6. 完整代码
  • 总结

年龄性别预测

  • 任务:使用OpenCV和Caffe深度学习框架(通过OpenCV的dnn模块接口)来实现实时的人脸检测、年龄估计和性别识别,并在检测到的人脸旁边绘制中文的年龄和性别信息。

  • 流程

    • 模型初始化
    • 变量初始化
    • 获取人脸包围框
    • 调用模型预测
    • 添加中文

1. 模型初始化

代码初始化了三个Caffe模型:一个人脸检测模型、一个年龄估计模型和一个性别识别模型

将这些模型同它们的参数权重文件加载到一起:这些模型的配置文件(.prototxt)和权重文件(.caffemodel.pb对于OpenCV dnn模块)的路径被指定。

"""-----模型初始化-----"""
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岁','28-43岁','48-53岁','60-100岁']
genderList = ['男性','女性']
mean = (78.4263377603,87.7689143744,114.895847746) # 模型均值

3. 获取人脸包围框

将图片转化为深度学习模型所需的输入格式,然后调用模型训练,将置信度大于0.7的保存下来,认定它们属于人脸,画出人脸框:

def getBoxes(net,frame):
    frameHeight,frameWidth = frame.shape[:2]
    # 将图像转换为深度学习模型所需的输入格式,即blob(二进制对象)。
    blob = cv2.dnn.blobFromImage(frame,1.0,(300,300),
                                 [104,117,123],True,False)
    net.setInput(blob) # 调用网络模型,输入图片进行人脸检测
    detections = net.forward()

    faceBoxes = [] # 存储检测到的人脸
    xx = detections.shape[2]
    for i in range(detections.shape[2]):
        # confidence中每一行保存7个数据,第三个表示置信度,第4,5,6,7分别表示人脸归一化后的坐标位置
        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,y1,x2,y2]) # 人脸框的坐标
            # 绘制人脸框
            cv2.rectangle(frame,(x1,y1),(x2,y2),
                          (0,255,0),int(round(frameHeight/150)),6)
    # 返回绘制了人脸框的帧frame、人脸包围框faceBoxes
    return frame,faceBoxes

4. 调用中文

将测试识别结果用中文形式显示在结果上:

def cv2ADDChineseText(img,text,position,textColor=(0,255,0),textSize=30):
    """向图片中添加中文"""
    if (isinstance(img,np.ndarray)): # 判断是否OpenCV图片类型
        img = Image.fromarray(cv2.cvtColor(img,cv2.COLOR_BGR2RGB)) # 实现array到image的转换
    draw = ImageDraw.Draw(img) # 在img图片上创建一个绘图的对象

    fontStyle = ImageFont.truetype("simfang.ttf",textSize,encoding="Utf-8")
    draw.text(position,text,textColor,font=fontStyle) # 绘制文本
    return cv2.cvtColor(np.asarray(img),cv2.COLOR_BGR2RGB) # 转换回OpenCV格式

5. 主循环

调用函数和模型,对视频进行预测:

"""-----打开摄像头,将每一帧画面传入神经网络中-----"""
cap = cv2.VideoCapture(0)
while True:
    _, frame = cap.read()  # 如果正确读取,ret为True
    # 获取人脸包围框、绘制人脸包围框
    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) # 模型输入为227*277
        # 调用模型,预测性别
        genderNet.setInput(blob)
        genderOuts = genderNet.forward()
        gender = genderList[genderOuts[0].argmax()]
        # 调用模型,预测年龄
        ageNet.setInput(blob)
        ageOuts = ageNet.forward()
        age = ageList[ageOuts[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()

6. 完整代码

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) # 人脸

"""-----变量初始化-----"""
ageList = ['0-2岁','4-6岁','8-12岁','15-20岁','25-32岁','28-43岁','48-53岁','60-100岁']
genderList = ['男性','女性']
mean = (78.4263377603,87.7689143744,114.895847746) # 模型均值

"""-----自定义函数,获取人脸包围框-----"""
def getBoxes(net,frame):
    frameHeight,frameWidth = frame.shape[:2]
    # 将图像转换为深度学习模型所需的输入格式,即blob(二进制对象)。
    blob = cv2.dnn.blobFromImage(frame,1.0,(300,300),
                                 [104,117,123],True,False)
    net.setInput(blob) # 调用网络模型,输入图片进行人脸检测
    detections = net.forward()

    faceBoxes = [] # 存储检测到的人脸
    xx = detections.shape[2]
    for i in range(detections.shape[2]):
        # confidence中每一行保存7个数据,第三个表示置信度,第4,5,6,7分别表示人脸归一化后的坐标位置
        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,y1,x2,y2]) # 人脸框的坐标
            # 绘制人脸框
            cv2.rectangle(frame,(x1,y1),(x2,y2),
                          (0,255,0),int(round(frameHeight/150)),6)
    # 返回绘制了人脸框的帧frame、人脸包围框faceBoxes
    return frame,faceBoxes

def cv2ADDChineseText(img,text,position,textColor=(0,255,0),textSize=30):
    """向图片中添加中文"""
    if (isinstance(img,np.ndarray)): # 判断是否OpenCV图片类型
        img = Image.fromarray(cv2.cvtColor(img,cv2.COLOR_BGR2RGB)) # 实现array到image的转换
    draw = ImageDraw.Draw(img) # 在img图片上创建一个绘图的对象

    fontStyle = ImageFont.truetype("simfang.ttf",textSize,encoding="Utf-8")
    draw.text(position,text,textColor,font=fontStyle) # 绘制文本
    return cv2.cvtColor(np.asarray(img),cv2.COLOR_BGR2RGB) # 转换回OpenCV格式

"""-----打开摄像头,将每一帧画面传入神经网络中-----"""
cap = cv2.VideoCapture(0)
while True:
    _, frame = cap.read()  # 如果正确读取,ret为True
    # 获取人脸包围框、绘制人脸包围框
    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) # 模型输入为227*277
        # 调用模型,预测性别
        genderNet.setInput(blob)
        genderOuts = genderNet.forward()
        gender = genderList[genderOuts[0].argmax()]
        # 调用模型,预测年龄
        ageNet.setInput(blob)
        ageOuts = ageNet.forward()
        age = ageList[ageOuts[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()

总结

本篇介绍了,如何使用已有的OpenCV和Caffe深度学习框架(通过OpenCV的dnn模块接口)来实现实时的人脸检测、年龄估计和性别识别,并在检测到的人脸旁边绘制中文的年龄和性别信息。


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

相关文章:

  • LeetCode Hot 100:滑动窗口
  • Self-Operating Computer Framework项目部署日记
  • idea(2017版)创建项目的搭建方式
  • 第23章 - Elasticsearch 洞悉你的查询:如何在上线前发现潜在问题!
  • C#第6讲:集合字典
  • 【JPCS独立出版 | 福州大学主办 | 有确定的ISSN号】第三届可再生能源与电气科技国际学术会议(ICREET 2024)
  • 第十四章_File类与IO流
  • Python爬虫:API接口数据的“美食侦探”
  • 如何将markdown文件转换为pdf
  • flutter camera 插件相机不占满屏幕的问题
  • HDU The Boss on Mars(容斥原理)
  • DevExpress WPF v24.1新版亮点:PDF查看器、富文本编辑器功能升级
  • HTTP: GET vs POST
  • git安装与使用的史诗级教程【git推送文件到远程仓库(GitHub)教程】
  • 基于知识图的电影推荐系统
  • 记录一下乐鑫官方仓库ESP32-CAMERA,在使用esp32s3 wroom n16r8 CAM开发板时遇到的问题。
  • 刷题小记9:回溯
  • to_sql报错not all arguments converted during string formatting
  • 5.redis安装【Docker】
  • vscode 预览markdown 文件