来源 | https://towardsdatascience.com/real-time-age-gender-and-emotion-prediction-from-webcam-with-keras-and-opencv-bde6220d60a

作者 | Sun Weiran

翻译 | OpenCV与AI深度学习

导读

本文将介绍如何使用 Keras 和 OpenCV 从网络摄像头实时预测年龄、性别和情绪。(公众号:OpenCV与AI深度学习)

背景介绍

在 Covid-19 时代,我们变得更加依赖虚拟互动,例如 Zoom 会议/团队聊天。这些直播网络摄像头视频已成为可供探索的丰富数据源。本文将探讨年龄、性别和情绪预测的实例,例如,这些应用可以帮助销售人员更好地了解他们的客户。

演示

来自我的网络摄像头的实时预测(作者提供的 gif)

整体架构

整体实现结构(作者供图)

如上图所示,该实现包含 4 个主要步骤:

  1. 从网络摄像头接收输入帧

  2. 识别网络摄像头中的人脸并为 3 个深度学习模型(即年龄、性别和情感模型)准备这些图像

  3. 将处理后的人脸发送到模型并接收预测结果

  4. 将带有边界框的预测结果渲染到屏幕上

在这个实现中,我们将使用最先进的面部识别模型之一,MTCNN 用于第 2 步。它有一个基于 Keras 的稳定 Python 版本,可在此处获得。

对于第 3 步,我们将训练我们自己的定制模型。但是,为了减少工作量和提高准确性,您可能需要考虑迁移学习技术。许多预训练模型,包括VGG-face、FaceNet、GoogLeNet可用。请注意,这些预训练模型可能具有不同的输入大小要求。因此,需要相应地处理从步骤 2 中识别的人脸。

使用 MTCNN 进行人脸识别

人脸识别近年来已经成为深度学习的成熟应用。已经提出了许多算法来快速准确地检测图像/视频中的人脸。MTCNN 就是其中之一,它基于 FaceNet。

在 Python 的实现中,模型已经过预训练和优化,因此我们可以直接使用该模型。尽管如此,了解模型的输出仍然很重要。

[    {        'box': [277, 90, 48, 63],        'keypoints':        {            'nose': (303, 131),            'mouth_right': (313, 141),            'right_eye': (314, 114),            'left_eye': (291, 117),            'mouth_left': (296, 143)        },        'confidence': 0.99851983785629272    }]

对于每张图像,MTCNN 返回一个字典列表,其中每个字典代表在照片中检测到的人脸。每张脸都被表示为一个边界框——一个围绕脸的矩形。

  • box: [x, y, width, height],x和y是边界框左上角的坐标

  • 关键点:检测到的面部标志点字典

  • 置信度:模型对检测到的人脸的置信度得分,1 表示最有信心。

年龄/性别/情感模型训练数据集

情感模型是从CKPlus Facial Emotion 数据集训练而来的。该数据集包含来自 7 个情绪类别的 981 张图像:愤怒、蔑视、厌恶、恐惧、快乐、悲伤和惊讶。每张图像为灰度,固定尺寸为 48*48

年龄和性别模型是从UTKface 数据集训练而来的。该数据集包含超过 2 万张图像。每张图片都标有年龄、性别和种族。完整照片和裁剪的脸部照片都可供下载。在本文中,我们将使用完整的照片并实施我们自己的人脸对齐方法以提高准确性。

图像预处理——UTKface 数据集

我们需要使用 MTCNN 或任何其他面部识别模型从整张照片中裁剪人脸。然而,这些算法中的大多数会根据检测到的人脸的大小和位置给出不同形状的边界框。

深度学习模型要求输入图像具有标准化大小(警告:不适用于全卷积网络,超出本文范围)。因此,有必要调整裁剪面的大小。直接调整大小是最常见和最直接的方法,但也有明显的缺点——面部变形。如下图所示,直接调整大小后脸部明显变宽。这将对我们的模型性能产生负面影响。

一张理想的裁剪人脸照片应该是人脸位于中心,没有失真和所需的大小。如果所需的大小是正方形,则以下方法可以解决问题。

  1. 从 MTCNN 获取面部边界框

  2. 找到边界框的中心点

  3. 找到边界框的高度和宽度之间的最大值

  4. 根据中心和最大边长绘制新的边界框

  5. 将裁剪后的人脸从新边界框调整为所需大小

如果所需的尺寸不是正方形,则需要调整第 3 步和第 4 步,以保持与所需边的比例相同。

对于年龄和性别模型,我们将使用 MTCNN 对完整照片使用居中调整大小的方法。两个模型所需的输入大小都设置为 (224, 224, 3)。

图像预处理——CKPlus Facial Emotion 数据集

由于其图像格式(灰度)和小体积,它不是用于情感预测的最理想数据集。优点是所有图像都被很好地裁剪和对齐,因此有利于快速原型制作。

该数据集的一个注释:对于每个情绪类别,个人面孔重复 3 次。因此,如果随机进行训练/测试拆分,则会发生目标泄漏。建议根据主题拆分或在随机拆分之前删除重复项。

模型结构

在三个目标中,年龄是最艰巨的任务。有时甚至人们在猜测别人的年龄时也会出错。因此,我们需要一个更深层次的模型来进行年龄预测。一般来说,这些是典型的卷积神经网络。请注意,所有这些模型结构都没有经过调整或优化。本文的目的不包括微调深度学习模型。

年龄模型:

input = Input(shape=(224, 224, 3))
cnn1 = Conv2D(128, kernel_size=3, activation='relu')(input)cnn1 = Conv2D(128, kernel_size=3, activation='relu')(cnn1)cnn1 = Conv2D(128, kernel_size=3, activation='relu')(cnn1)cnn1 = MaxPool2D(pool_size=3, strides=2)(cnn1)
cnn2 = Conv2D(128, kernel_size=3, activation='relu')(cnn1)cnn2 = Conv2D(128, kernel_size=3, activation='relu')(cnn2)cnn2 = Conv2D(128, kernel_size=3, activation='relu')(cnn2)cnn2 = MaxPool2D(pool_size=3, strides=2)(cnn2)
cnn3 = Conv2D(256, kernel_size=3, activation='relu')(cnn2)cnn3 = Conv2D(256, kernel_size=3, activation='relu')(cnn3)cnn3 = Conv2D(256, kernel_size=3, activation='relu')(cnn3)cnn3 = MaxPool2D(pool_size=3, strides=2)(cnn3)
cnn4 = Conv2D(512, kernel_size=3, activation='relu')(cnn3)cnn4 = Conv2D(512, kernel_size=3, activation='relu')(cnn4)cnn4 = Conv2D(512, kernel_size=3, activation='relu')(cnn4)cnn4 = MaxPool2D(pool_size=3, strides=2)(cnn4)
dense = Flatten()(cnn4)dense = Dropout(0.2)(dense)dense = Dense(1024, activation='relu')(dense)dense = Dense(1024, activation='relu')(dense)
output = Dense(1, activation='linear', name='age')(dense)
model = Model(input, output)model.compile(optimizer=Adam(0.0001), loss='mse', metrics=['mae'])

性别模型:​​​​​​​​​​​​​​

input = Input(shape=(224, 224, 3))cnn1 = Conv2D(36, kernel_size=3, activation='relu')(input)cnn1 = MaxPool2D(pool_size=3, strides=2)(cnn1)cnn2 = Conv2D(64, kernel_size=3, activation='relu')(cnn1)cnn2 = MaxPool2D(pool_size=3, strides=2)(cnn2)cnn3 = Conv2D(128, kernel_size=3, activation='relu')(cnn2)cnn3 = MaxPool2D(pool_size=3, strides=2)(cnn3)cnn4 = Conv2D(256, kernel_size=3, activation='relu')(cnn3)cnn4 = MaxPool2D(pool_size=3, strides=2)(cnn4)cnn5 = Conv2D(512, kernel_size=3, activation='relu')(cnn4)cnn5 = MaxPool2D(pool_size=3, strides=2)(cnn5)dense = Flatten()(cnn5)dense = Dropout(0.2)(dense)dense = Dense(512, activation='relu')(dense)dense = Dense(512, activation='relu')(dense)output = Dense(1, activation='sigmoid', name='gender')(dense)sex_model = Model(input, output)sex_model.compile(optimizer=Adam(learning_rate=0.0001), loss='binary_crossentropy', metrics=['accuracy'])

情绪模型:​​​​​​​

input = Input(shape=(48, 48, 1))cnn1 = Conv2D(36, kernel_size=3, activation='relu')(input)cnn1 = MaxPool2D(pool_size=3, strides=2)(cnn1)cnn2 = Conv2D(64, kernel_size=3, activation='relu')(cnn1)cnn2 = MaxPool2D(pool_size=3, strides=2)(cnn2)cnn3 = Conv2D(128, kernel_size=3, activation='relu')(cnn2)cnn3 = MaxPool2D(pool_size=3, strides=2)(cnn3)dense = Flatten()(cnn3)dense = Dropout(0.3)(dense)dense = Dense(256, activation='relu')(dense)output = Dense(7, activation='softmax', name='race', kernel_regularizer=l1(1))(dense)emotion_model = Model(input, output)emotion_model.compile(optimizer=Adam(learning_rate=0.0001), loss='categorical_crossentropy', metrics=['categorical_accuracy'])

与 OpenCV 的集成说明

基本上,openCV 从您的网络摄像头捕获视频(第 2 行)。对于每一帧,它都会将其转换为 RGB 格式(第 19 行)。这个 RGB 帧将被发送到 detect_face 函数(第 22 行),该函数首先使用 MTCNN 检测帧中的所有人脸,并且对于每个人脸,使用 3 个经过训练的模型进行预测以生成结果。这些结果与人脸边界框位置(上、右、下、左)一起返回。

然后,OpenCV 利用边界框位置在框架上绘制矩形(第 27 行)并在文本中显示预测结果(第 29 行 - 第 32 行)。

可以在源代码中找到detect_face 函数的实现。请注意,由于情感模型是从灰度图像中训练出来的,因此 RGB 图像在被情感模型预测之前需要进行灰度处理。

OpenCV主脚本:​​​​​​​

# Get a reference to webcam video_capture = cv2.VideoCapture(0)
emotion_dict = {    0: 'Surprise',    1: 'Happy',     2: 'Disgust',    3: 'Anger',    4: 'Sadness',    5: 'Fear',    6: 'Contempt'}
while True:    # Grab a single frame of video    ret, frame = video_capture.read()
    # Convert the image from BGR color (which OpenCV uses) to RGB color     rgb_frame = frame[:, :, ::-1]
    # Find all the faces in the current frame of video    face_locations = detect_face(rgb_frame)
    # Display the results    for top, right, bottom, left, sex_preds, age_preds, emotion_preds in face_locations:        # Draw a box around the face        cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2)                sex_text = 'Female' if sex_preds > 0.5 else 'Male'        cv2.putText(frame, 'Sex: {}({:.3f})'.format(sex_text, sex_preds), (left, top-10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (36,255,12), 1)        cv2.putText(frame, 'Age: {:.3f}'.format(age_preds), (left, top-25), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (36,255,12), 1)        cv2.putText(frame, 'Emotion: {}({:.3f})'.format(emotion_dict[np.argmax(emotion_preds)], np.max(emotion_preds)), (left, top-40), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (36,255,12), 1)            # Display the resulting image    cv2.imshow('Video', frame)
    # Hit 'q' on the keyboard to quit!    if cv2.waitKey(1) & 0xFF == ord('q'):        break
# Release handle to the webcamvideo_capture.release()cv2.destroyAllWindows()

待优化内容

  • 更好的情绪预测数据集

  • 由于计算资源的限制,只有来自 UTKface 数据集的 5k 图像用于年龄/性别模型训练。使用更多图像可以提高模型性能

  • 图像增强

  • 迁移学习/调优模型架构

    源码与模型文件下载:

  • https://github.com/ianforme/face-prediction

使用Keras和OpenCV实时预测年龄、性别和情绪 (详细步骤+源码)相关推荐

  1. 实战 | 基于OpenCV的停车场空余车位实时监测系统(详细步骤 + 源码)

    导  读 本文主要介绍如何使用Python和OpenCV实现一个停车场空余车位实时监测系统,并包含详细步骤和源码. 背景介绍 介绍实现步骤之前,先来看看测试视频(小型停车场实时监控画面): ,时长00 ...

  2. 【Android App】人脸识别中借助摄像头和OpenCV实时检测人脸讲解及实战(附源码和演示 超详细)

    需要全部代码请点赞关注收藏后评论区留言私信~~~ 一.借助摄像头实时检测人脸 与Android自带的人脸检测器相比,OpenCV具备更强劲的人脸识别功能,它可以通过摄像头实时检测人脸,实时检测的预览空 ...

  3. 基于OpenCV实现简单人脸面具、眼镜、胡须、鼻子特效(详细步骤 + 源码)

    点击下方卡片,关注"OpenCV与AI深度学习"公众号! 视觉/图像重磅干货,第一时间送达! 导读 本文给大家分享一个基于OpenCV实现简单人脸面具.眼镜.胡须.鼻子特效的实例, ...

  4. OpenCvSharp (C# OpenCV)实现纺织物缺陷检测->脏污、油渍、线条破损(详细步骤 + 源码)

    点击下方卡片,关注" OpenCV与AI深度学习" 视觉/图像重磅干货,第一时间送达! 导读 本文将介绍使用OpenCV实现纺织物缺陷检测(脏污.油渍.线条破损缺陷)的详细步骤 + ...

  5. Opencv基于改进VGG19的表情识别系统(源码&Fer2013&教程)

    1.研究背景 在深度学习中,传统的卷积神经网络对面部表情特征的提取不充分以及计算参数量较大的问题,导致分类准确率偏低.因此,提出了一种基于改进的VGG19网络的人脸表情识别算法.首先,对数据进行增强如 ...

  6. Python基于OpenCV的指针式表盘检测系统(附带源码&技术文档)

    1.背景 指针式机械表盘具有安装维护方便.结构简单.防电磁干扰等诸多优点, 目前广泛应用于工矿企业.能源及计量等部门.随着仪表数量的增加及精密仪表技术的发展,人工判读已经不能满足实际应用需求.随着计算 ...

  7. Opencv多语言自然场景文本识别系统(源码&教程)

    1. 研究背景 人类在自然场景中可以快速定位并识别看到的文字信息,但是想要计算机做到和人类一样是比较困难的.开发人员一直想要让机器也能识别图像中的文字信息.当然,对于自然场景来说,图像中的信息复杂甚至 ...

  8. Android音频实时传输与播放(四):源码下载(问题更新)【转】

    Android音频实时传输与播放(四):源码下载(问题更新) 激动人心的时刻到了有木有 ^_^ 服务端下载请点击这里,客户端下载请点击这里! 最近有朋友在下载源码使用之后,说播放出来的声音噪声很大.其 ...

  9. 基于OpenCV的电影视频人像景别分类算法(源码&教程)

    1.研究背景 近年来,随着多媒体技术的高速发展,视频数据也呈现出爆炸性的增长.基于内容的视频检索已成为当前的迫切需求.特别在电影视频领域,单纯的播放已经无法满足用户日益增长的需要.如何准确快速地按照用 ...

最新文章

  1. 【快速入门系列】简述 for...in 和 for...of 区别
  2. 基于NHibernate的三层结构应用程序开发初步
  3. 数据结构-顺序栈、链栈
  4. 学校不用考直接过计算机一级,全国计算机等级考试1级是不是必须要考的啊
  5. TouchJSON的简单使用
  6. Java protected 关键字详解
  7. Xgboost和lightgbm的区别
  8. QEMU模拟mini2440开发环境
  9. 计算机主机的税收,税控电脑
  10. OCLint + Infer + Jenkins + SonarQube 搭建iOS代码静态分析系统
  11. mysql latch和缓存关系_latch:cachebufferschains等待事件导致的latch争用的原理原因与...
  12. 现有大语言模型(ChatGPT)的上下文理解能力还是假象吗?
  13. python数据分析学生成绩查询系统_python数据分析-学生成绩分析
  14. 用js进行日期的加减
  15. HDU 2448 Mining Station on the Sea 最短路+KM
  16. 企业邮箱和普通邮箱有什么区别
  17. 2022-2027年中国烟用香精香料行业发展前景及投资战略咨询报告
  18. Emacs Stardict
  19. 【采用】信贷业务的25个风险点
  20. 【尚筹网项目】 三、【后台】 管理员信息维护

热门文章

  1. TOF传感器、摄像头传感器、超声波传感器、激光雷达、毫米波雷达
  2. 行式数据库评测:Oracle 11g R2企业版
  3. 解决流氓软件布丁桌面、布丁压缩、值购助手、智能云输入法、蒲公英wifi、柚子壁纸、麦家购物助手反复安装
  4. 【IoT】产品设计之行业动态:社区团购:巨头们会放弃卖菜这门生意吗?
  5. 小程序使用彩色字体图标
  6. python 火车票查询,Python3实现火车票查询工具
  7. PDF文件可以修改吗,PDF怎么删除页眉页脚
  8. 淘宝手机所在地查询接口
  9. Tomcat注册为Windows服务
  10. 分布式环境Raft一致性共识算法解读