人脸识别经典网络-mtcnn(含python源码实现)(代码片段)

Moresweet猫甜 Moresweet猫甜     2023-04-10     678

关键词:

人脸检测-mtcnn

本文参加新星计划人工智能赛道:https://bbs.csdn.net/topics/613989052

文章目录

1. 人脸检测

1.1 人脸检测概述

人脸检测或者识别,都是根据人的脸部特征信息进行身份识别的一种生物识别术。用摄像机或摄像头采集含有人脸的图像或视频流,并自动在图像中检测和跟踪人脸,进而对检测到的人脸进行脸部识别的一系列相关技术,通常也叫做人像识别、面部识别。

1.2 人脸检测的难点

人脸识别被认为是生物特征识别领域甚至人工智能领域最困难的研究课题之一。人脸识别的难点是由于人脸作为生物特征的特点而导致的,难点主要包括以下部分:

  • 相似性:从人脸的构造上来看,个体之间的人脸构造区别不大,甚至人脸器官的构造都很相似。这种相似性对于利用人脸进行定位是能偶提供很大的便利的,但同时对于个体的区分确实难的。
  • 易变性:抛去构造仅仅关注外形的话,人脸的外形又是十分多变的,面部表情多变,而在不同观察角度,人脸的视觉图像也相差很大,另外,人脸识别还受光照条件(例如白天和夜晚,室内和室外等)、人脸的很多遮盖物(例如口罩、墨镜、头发、胡须等)、年龄等多方面因素的影响。

在人脸识别中,第一类的变化是应该放大而作为区分个体的标准的,而第二类的变化应该消除,因为它们可以代表同一个个体。通常称第一类变化为类间变化(inter-class difference),而称第二类变化为类内变化(intra-class difference)。对于人脸,类内变化往往大于类间变化,从而使在受类内变化干扰的情况下利用类间变化区分个体变得异常困难。

1.3 人脸检测的应用场景

人脸识别主要用于身份识别。
由于视频监控正在快速普及,众多的视频监控应用迫切需要一种远距离、用户非配合状态下的快速身份识别技术,以求远距离快速确认人员身份,实现智能预警。人脸识别技术无疑是最佳的选择,采用快速人脸检测技术可以从监控视频图象中实时查找人脸,并与人脸数据库进行实时比对,从而实现快速身份识别。
人脸识别产品已广泛应用于金融、司法、军队、公安、边检、政府、航天、电力、工厂、教育、医疗及众多企事业单位等领域。随着技术的进一步成熟和社会认同度的提高,人脸识别技术将应用在更多的领域。
1、企业、住宅安全和管理。如人脸识别门禁考勤系统,人脸识别防盗门等。
2、电子护照及身份证。
3、公安、司法和刑侦。如利用人脸识别系统和网络,在全国范围内搜捕逃犯。
4、自助服务。
5、信息安全。如手机、计算机登录、电子政务和电子商务。

2. mtcnn

2.1 mtcnn概述

MTCNN,英文全称是Multi-task convolutional neural network,中文全称是多任务卷积神经网络,该神经网络将人脸区域检测与人脸关键点检测放在了一起。
从工程实践上,MTCNN是一种检测速度和准确率都很不错的算法,算法的推断流程有一定的启示作用。

2.2 mtcnn的网络结构

mtcnn从整体上划分分为P-Net、R-Net、和O-Net三层网络结构。各层的作用直观上感受如下图所示:

一次mtcnn对于局部信息的运作流程如下描述:

  1. 由原始图片和PNet生成预测的bounding boxes。
  2. 输入原始图片和PNet生成的bounding box,通过RNet,生成校正后的bounding box。
  3. 输入原始图片和RNet生成的bounding box,通过ONet,生成校正后的bounding box和人脸面部轮廓关键点。

当整个图片的局部信息都进行处理之后,就能得到所有的局部人脸信息,或有或无,进行校正处理后就可以得到最后的结果。

P-Net、R-Net、O-Net的网络结构如下图所示:

分析:

MTCNN主要包括三层网络,

  1. 第一层P-Net将经过卷积,池化操作后输出分类(对应像素点是否存在人脸)和回归(回归box)结果。
  2. 第二层网络将第一层输出的结果使用非极大抑制(NMS)来去除高度重合的候选框,并将这些候选框放入R-Net中进行精细的操作,拒绝大量错误框,再对回归框做校正,并使用NMS去除重合框,输出分支同样两个分类和回归。
  3. 最后将R-Net输出认为是人脸的候选框输入到O-Net中再一次进行精细操作,拒绝掉错误的框,此时输出分支包含三个分类:
    a. 是否有人脸:2个输出;
    b. 回归:回归得到的框的起始点(或中心点)的xy坐标和框的长宽,4个输出;
    c. 人脸特征点定位:5个人脸特征点的xy坐标,10个输出。

三段网络都有NMS,但是所设阈值不同。

2.3 图像金字塔

mtcnn的输入尺度是任意大小的,那么输入是如何处理的呢?

首先对图片进行Resize操作,将原始图像缩放成不同的尺度,生成图像金字塔。然后将不同尺度的图像送入到这三个子网络中进行训练,目的是为了可以检测到不同大小的人脸,从而实现多尺度目标检测。
构建方式是通过不同的缩放系数factor分别对图片的h和w进行缩放,每次缩小为原来的factor大小。

缩小后的长宽最小不可以小于12。

图片中的人脸的尺度有大有小,让识别算法不被目标尺度影响一直是个挑战。

MTCNN使用了图像金字塔来解决目标多尺度问题,即把原图按照一定的比例(如0.709),多次等比缩放得到多尺度的图片,很像个金字塔。

为什么这里的缩放因子是0.709,因为缩放的时候若宽高都缩放 1 2 \\frac12 21,那么缩放后的面积就变为了原本面积的 1 4 \\frac14 41,如果考虑总面积缩放为原本的 1 2 \\frac12 21,那么就取 2 2 ≈ 0.709 \\frac\\sqrt22\\approx 0.709 22 0.709,这样就达到了将总面积缩放为原本的 1 2 \\frac12 21的目的。

P-NET的模型是用单尺度(12*12)的图片训练出来的。推理的时候,缩小后的长宽最小不可以小于12。
对多个尺度的输入图像做训练,训练是非常耗时的。因此通常只在推理阶段使用图像金字塔,提高算法的精度。

图像金字塔是有生成标准的,每次缩放的程度(factor)以及最小的兜底标准(minsize)都是需要合适的设置的,那么能够优化计算效率的合适的最小人脸尺寸(minsize)和缩放因子(factor)具有什么样的依据?

  • 第一阶段会多次缩放原图得到图片金字塔,目的是为了让缩放后图片中的人脸与P-NET训练时候的图片尺度( 12 p x × 12 p x 12px\\times 12px 12px×12px)接近。
  • 引申优化项:先把图像缩放到一定大小,再通过factor对这个大小进行缩放。可以减少计算量。

minsize的单位为px

例:输入图片为 1200 p x × 1200 p x 1200px\\times 1200px 1200px×1200px,设置缩放后的尺寸接近训练图片的尺度( 12 p x × 12 p x 12px\\times 12px 12px×12px)

图像金字塔也有其局限性

  • 生成图像金字塔的过程比较慢。
  • 每种尺度的图片都需要输入进模型,相当于执行了多次的模型推理流程。

2.4 P-Net

P-Net(Proposal Network)的网络结构

网络的输入为预处理中得到的图像金字塔,P-Net中设计了一个全卷积网络(FCN)对输入的图像金字塔进行特征提取和边框回归。

全卷积神经网络没有FC全连接层,这就突破了输入维度的限制,那么其接受的输入尺寸是任意的。

在P-Net中,经过了三次卷积和一次池化(MP:Max Pooling),输入 12 × 12 × 3 12\\times 12 \\times 3 12×12×3的尺寸变为了 1 × 1 × 32 1\\times 1\\times 32 1×1×32 1 × 1 × 32 1\\times 1\\times 32 1×1×32的向量通过卷积得到了 1 × 1 × 2 1\\times 1\\times 2 1×1×2到了人脸的分类结果,相当于图像中的每个 12 × 12 12\\times 12 12×12的区域都会判断一下是否存在人脸,通道数为2,即得到两个值;第二个部分得到(bounding box regrssion)边框回归的结果,因为 12 × 12 12\\times 12 12×12的图像并不能保证,方形框能够完美的框住人脸,所以输出包含的信息都是误差信息,通道数为4,有4个方面的信息,边框左上角的横坐标的相对偏移信息、边框左上角纵坐标的相对偏移信息、标定框宽度的误差、标定框高度的误差;第三个部分给出了人脸的5个关键点的位置,分别是左眼位置、右眼位置、鼻子位置、嘴巴左位置、嘴巴右位置,每个关键位置使用两个维度表示,故而输出是 1 × 1 × 10 1\\times 1\\times 10 1×1×10

P-Net应用举例

一张 70 × 70 70\\times 70 70×70的图,经过P网络全卷积后,输出为 70 − 2 2 − 2 − 2 = 30 \\frac70-22 -2 -2 =30 270222=30,即一个5通道的 30 × 30 30\\times 30 30×30的特征图。这就意味着该图经过p的一次滑窗操作,得到 30 × 30 = 900 30\\times 30=900 30×30=900个建议框,而每个建议框对应1个置信度与4个偏移量。再经nms把置信度分数大于设定的阈值0.6对应的建议框保留下来,将其对应的边框偏移量经边框回归操作,得到在原图中的坐标信息,即得到符合P-Net的这些建议框了。之后传给R-Net。

2.5 R-Net

R-Net(Refine Network),从网络图可以看到,该网络结构只是和P-Net网络结构多了一个全连接层。图片在输入R-Net之前,都需要缩放到24x24x3。网络的输出与P-Net是相同的,R-Net的目的是为了去除大量的非人脸框。

2.6 O-Net

O-Net(Output Network),该层比R-Net层又多了一层卷积层,所以处理的结果会更加精细。输入的图像大小48x48x3,输出包括N个边界框的坐标信息,score以及关键点位置。

从P-Net到R-Net,再到最后的O-Net,网络输入的图像越来越大,卷积层的通道数越来越多,网络的深度(层数)也越来越深,因此识别人脸的准确率应该也是越来越高的。

3. 工程实践(基于Keras)

点击此处下载人脸数据集。该数据集有32,203张图片,共有93,703张脸被标记。

MTCNN网络定义,按照上述网络结构完成定义,代码按照P-Net、R-Net、O-Net进行模块化设计,在mtcnn的网络构建过程中将其整合。mtcnn.py代码如下:

from keras.layers import Conv2D, Input,MaxPool2D, Reshape,Activation,Flatten, Dense, Permute
from keras.layers.advanced_activations import PReLU
from keras.models import Model, Sequential
import tensorflow as tf
import numpy as np
import utils
import cv2
#-----------------------------#
#   粗略获取人脸框
#   输出bbox位置和是否有人脸
#-----------------------------#
def create_Pnet(weight_path):
    input = Input(shape=[None, None, 3])

    x = Conv2D(10, (3, 3), strides=1, padding='valid', name='conv1')(input)
    x = PReLU(shared_axes=[1,2],name='PReLU1')(x)
    x = MaxPool2D(pool_size=2)(x)

    x = Conv2D(16, (3, 3), strides=1, padding='valid', name='conv2')(x)
    x = PReLU(shared_axes=[1,2],name='PReLU2')(x)

    x = Conv2D(32, (3, 3), strides=1, padding='valid', name='conv3')(x)
    x = PReLU(shared_axes=[1,2],name='PReLU3')(x)

    classifier = Conv2D(2, (1, 1), activation='softmax', name='conv4-1')(x)
    # 无激活函数,线性。
    bbox_regress = Conv2D(4, (1, 1), name='conv4-2')(x)

    model = Model([input], [classifier, bbox_regress])
    model.load_weights(weight_path, by_name=True)
    return model

#-----------------------------#
#   mtcnn的第二段
#   精修框
#-----------------------------#
def create_Rnet(weight_path):
    input = Input(shape=[24, 24, 3])
    # 24,24,3 -> 11,11,28
    x = Conv2D(28, (3, 3), strides=1, padding='valid', name='conv1')(input)
    x = PReLU(shared_axes=[1, 2], name='prelu1')(x)
    x = MaxPool2D(pool_size=3,strides=2, padding='same')(x)

    # 11,11,28 -> 4,4,48
    x = Conv2D(48, (3, 3), strides=1, padding='valid', name='conv2')(x)
    x = PReLU(shared_axes=[1, 2], name='prelu2')(x)
    x = MaxPool2D(pool_size=3, strides=2)(x)

    # 4,4,48 -> 3,3,64
    x = Conv2D(64, (2, 2), strides=1, padding='valid', name='conv3')(x)
    x = PReLU(shared_axes=[1, 2], name='prelu3')(x)
    # 3,3,64 -> 64,3,3
    x = Permute((3, 2, 1))(x)
    x = Flatten()(x)
    # 576 -> 128
    x = Dense(128, name='conv4')(x)
    x = PReLU( name='prelu4')(x)
    # 128 -> 2 128 -> 4
    classifier = Dense(2, activation='softmax', name='conv5-1')(x)
    bbox_regress = Dense(4, name='conv5-2')(x)
    model = Model([input], [classifier, bbox_regress])
    model.load_weights(weight_path, by_name=True)
    return model

#-----------------------------#
#   mtcnn的第三段
#   精修框并获得五个点
#-----------------------------#
def create_Onet(weight_path):
    input = Input(shape = [48,48,3])
    # 48,48,3 -> 23,23,32
    x = Conv2D(32, (3, 3), strides=1, padding='valid', name='conv1')(input)
    x = PReLU(shared_axes=[1,2],name='prelu1')(x)
    x = MaxPool2D(pool_size=3, strides=2, padding='same')(x)
    # 23,23,32 -> 10,10,64
    x = Conv2D(64, (3, 3), strides=1, padding='valid', name='conv2')(x)
    x = PReLU(shared_axes=[1,2],name='prelu2')(x)
    x = MaxPool2D(pool_size=3, strides=2)(x)
    # 8,8,64 -> 4,4,64
    x = Conv2D(64, (3, 3), strides=1, padding='valid', name='conv3')(x)
    x = PReLU(shared_axes=[1,2],name='prelu3')(x)
    x = MaxPool2D(pool_size=2)(x)
    # 4,4,64 -> 3,3,128
    x = Conv2D(128, (2, 2), strides=1, padding='valid', name='conv4')(x)
    x = PReLU(shared_axes=[1,2],name='prelu4')(x)
    # 3,3,128 -> 128,12,12
    x = Permute((3,2,1))(x)

    # 1152 -> 256
    x = Flatten()(x)
    x = Dense(256, name='conv5') (x)
    x = PReLU(n

人脸识别基于matlabguibp神经网络人脸识别(含识别率)含matlab源码891期(代码片段)

一、简介1概述BP(BackPropagation)神经网络是1986年由Rumelhart和McCelland为首的科研小组提出,参见他们发表在Nature上的论文Learningrepresentationsbyback-propagatingerrors。BP神经网络是一种按误差逆传播算法训练的多层前馈网络,是目前应用... 查看详情

什么是mtcnn人脸识别能力?

】什么是mtcnn人脸识别能力?【英文标题】:Whatismtcnnfacerecognitionpower?【发布时间】:2021-07-2422:55:50【问题描述】:我正在研究人脸识别的oneshot学习首先我必须在帧中检测人脸,我将它与mtcnn一起使用,但它不能正常工作......我... 查看详情

使用 MTCNN 进行人脸识别

】使用MTCNN进行人脸识别【英文标题】:FaceRecognitionusingMTCNN【发布时间】:2021-07-2711:28:44【问题描述】:我在尝试运行的代码中遇到错误。AttributeError:模块\'facedetector_m\'没有属性FaceDetectorClassfromfacenet_pytorchimportMTCNNimportfacedetector_... 查看详情

人脸识别基于matlabguibp神经网络双人脸识别(含识别率)含matlab源码2383期

⛄一、BP神经网络简介1BP神经网络概述1.1BP神经网络的内涵BP神经网络是神经网络的一种经典结构,其结构简单、训练简单,是学习神经网络的一种输入算法,包含一个特定的模型(神经网络)和一个特定的训练算法[1ÿ... 查看详情

人脸识别基于mctnn人脸检测(pytorch)(代码片段)

...aster·faciallab/FaceDetector·GitHub中文翻译:从零开始搭建人脸识别系统(一)MTCNN-知乎1、网络结构mtcnn算法人脸检测过程分为三个独立的stage,每一个stage对应一个卷积网络,分别 查看详情

戴口罩人脸检测和戴口罩识别(含pythonandroid源码)(代码片段)

戴口罩人脸检测和戴口罩识别(含PythonAndroid源码)目录戴口罩人脸检测和戴口罩识别(含PythonAndroid源码)1.戴口罩识别的方法(1)基于多类别目标检测的戴口罩识别方法(2)基于人脸检测+戴口罩分类识别方法2.戴... 查看详情

戴口罩人脸检测和戴口罩识别(含pythonandroid源码)(代码片段)

戴口罩人脸检测和戴口罩识别(含PythonAndroid源码)目录戴口罩人脸检测和戴口罩识别(含PythonAndroid源码)1.戴口罩识别的方法(1)基于多类别目标检测的戴口罩识别方法(2)基于人脸检测+戴口罩分类识别方法2.戴... 查看详情

使用tensorrt对人脸检测网络mtcnn进行加速(代码片段)

前言最近在做人脸比对的工作,需要用到人脸关键点检测的算法,比较成熟和通用的一种算法是MTCNN,可以同时进行人脸框选和关键点检测,对于每张脸输出5个关键点,可以用来进行人脸对齐。问题刚开始准备对齐人脸图片用于... 查看详情

人脸检测和对齐算法mtcnn(代码片段)

1.概述人脸识别在实际的生活中有着广泛的应用,得益于深度学习的发展,使得人脸识别的准确率得到大幅度提升。然而,为了做好人脸识别,第一步需要做的是对人脸检测,主要是通过对图片分析,定位... 查看详情

人脸检测和对齐算法mtcnn(代码片段)

1.概述人脸识别在实际的生活中有着广泛的应用,得益于深度学习的发展,使得人脸识别的准确率得到大幅度提升。然而,为了做好人脸识别,第一步需要做的是对人脸检测,主要是通过对图片分析,定位... 查看详情

人脸识别基于matlab小波不变矩人脸识别含matlab源码1355期

一、小波不变矩简介1引言人脸识别是目前模式识别与计算机视觉非常活跃的一个研究方向,它可以广泛应用于公安、交通、银行、商业和海关等部门。人脸识别技术在90年代以来取得了很大的进展,人们从不同的角度加以研究,提出... 查看详情

人脸识别基于matlab小波不变矩人脸识别含matlab源码1355期

一、小波不变矩简介1引言人脸识别是目前模式识别与计算机视觉非常活跃的一个研究方向,它可以广泛应用于公安、交通、银行、商业和海关等部门。人脸识别技术在90年代以来取得了很大的进展,人们从不同的角度加以研究,提出... 查看详情

人脸识别基于matlabguilbp人脸识别含matlab源码1282期

一、LBP简介LBP(LocalBinaryPattern,局部二值模式)是一种用来描述图像局部纹理特征的算子;它具有旋转不变性和灰度不变性等显著的优点。它是首先由T.Ojala,M.Pietikäinen,和D.Harwood在1994年提出,用于纹理特征提取。而且,提取的特... 查看详情

21个项目玩转深度学习:基于tensorflow的实践详解06—人脸检测和识别——mtcnn人脸检测(代码片段)

本篇主要讲述利用MTCNN的预训练模型得到原图中人脸的分割,代码如下:https://github.com/davidsandberg/facenet结合博客https://blog.csdn.net/FortiLZ/article/details/81396566?tdsourcetag=s_pctim_aiomsg看起来省力些要是对MTCNN的训练过程感兴趣的,可以看h... 查看详情

mtcnn实时人脸检测网络详解与opencv+tensorflow代码演示(代码片段)

MTCNN模型概述多任务卷积神经网络(MTCNN)实现人脸检测与对齐是在一个网络里实现了人脸检测与五点标定的模型,主要是通过CNN模型级联实现了多任务学习网络。整个模型分为三个阶段,第一阶段通过一个浅层的CNN网络快速产生一... 查看详情

人脸表情识别系统介绍——上篇(python实现,含ui界面及完整代码)

摘要:这篇博文介绍基于深度卷积神经网络实现的人脸表情识别系统,系统程序由Keras,OpenCv,PyQt5的库实现,训练测试集采用fer2013表情库。如图系统可通过摄像头获取实时画面并识别其中的人脸表情,也可以通过读取图片识别,... 查看详情

人脸表情识别基于matlabguilbp+svm脸部动态特征人脸表情识别含matlab源码1369期

一、LBP+SVM简介人的脸部是非常值得关注的外部特征。人与人交流不需要接触对方就可以识别对象的一些心里活动,丰富多样的表情能够在很多情况下代替语言表达自己的内心情感。人与人不但可以通过表情来表达情绪,还能分辨出... 查看详情

人脸表情识别基于matlabguilbp+svm脸部动态特征人脸表情识别含matlab源码1369期

一、LBP+SVM简介人的脸部是非常值得关注的外部特征。人与人交流不需要接触对方就可以识别对象的一些心里活动,丰富多样的表情能够在很多情况下代替语言表达自己的内心情感。人与人不但可以通过表情来表达情绪,还能分辨出... 查看详情