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

zhiyong_will zhiyong_will     2023-03-27     415

关键词:

1. 概述

人脸识别在实际的生活中有着广泛的应用,得益于深度学习的发展,使得人脸识别的准确率得到大幅度提升。然而,为了做好人脸识别,第一步需要做的是对人脸检测,主要是通过对图片分析,定位出图片中的人脸。近年来,深度学习在人脸检测方面也得到了大力发展,在2016年Kaipeng Zhang, Zhanpeng Zhang等人提出了人脸检测算法MTCNN(Multi-task Cascaded Convolutional Networks)模型[1],MTCNN算法的效果也是得到了很多实际项目的验证,在工业界得到了广泛的应用,在我个人的实际项目中也得到了较多应用。在MTCNN算法中,主要有三点的创新:

  • MTCNN的整体框架是一个多任务的级联框架,同步对人脸检测和人脸对齐两个项目学习;
  • 在级联的框架中使用了三个卷积网络,并将这三个网络级联起来;
  • 在训练的过程中使用到了在线困难样本挖掘的方法;

这三个方面的设计都是为了能够提升最终的检测和对齐的效果。

2. 算法原理

2.1. MTCNN的基本原理

MTCNN是多任务级联CNN的人脸检测深度学习模型,在MTCNN中是通过三个卷积网络的级联:

  • 第一阶段的网络产出人脸的候选窗口
  • 第二阶段的第一阶段产出的候选串口修正,去除掉不符合要求的候选窗口
  • 第三阶段在第二阶段的基础上进一步修正,并给出最终的五个脸部的landmark

在网络的训练过程中综合考虑人脸边框回归和面部关键点检测。MTCNN的网络整体架构如下图所示:

由上图中可以看到,MTCNN主要由四个模块:

  • 图像金字塔(Image Pyramid):通过对原始图像进行不同尺度的变换,得到图像金字塔,以适应不同大小的人脸的进行检测,在MTCNN中,是将图像resize成了三种大小,分别为 12 × 12 × 3 12\\times 12\\times 3 12×12×3 24 × 24 × 3 24\\times 24\\times 3 24×24×3 48 × 48 × 3 48\\times 48\\times3 48×48×3,这三种大小分别对应了以下三个阶段模型的输入
  • 阶段1(Proposal Network): 对上述的图像金字塔中 12 × 12 × 3 12\\times 12\\times 3 12×12×3的图像提取Bounding-Box,并利用NMS过滤掉大部分的窗口
  • 阶段2(Refine Network): 对上述的图像金字塔中 24 × 24 × 3 24\\times 24\\times 3 24×24×3的图像,根据阶段1中提取出的Bounding-Box进一步修正,去除掉不符合要求的bounding box
  • 阶段3(Output Network): 对上述的图像金字塔中 48 × 48 × 3 48\\times 48\\times 3 48×48×3的图像,根据阶段2中提取出的Bounding-Box进行最终的分析,以得到最终的结果

2.2. 三个阶段的网络

2.2.1. 第一阶段P-Net

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

在P-Net中,包含了三个卷积+Max-Pooling操作,其中,卷积核的大小统一为 3 × 3 3\\times 3 3×3,对于上述的网络结果,具体的参数分析如下:

  • data:大小为 12 × 12 × 3 12\\times 12\\times 3 12×12×3
  • 第一组卷积(包括conv,PReLU,Max-Pooling)
    • conv:输入( 12 × 12 × 3 12\\times 12\\times 3 12×12×3),输出( 10 × 10 × 10 10\\times 10\\times 10 10×10×10,卷积核大小为 3 × 3 3\\times 3 3×3,padding为 0 0 0,步长为 1 1 1,卷积核的个数为 10 10 10
    • PReLU:输入( 10 × 10 × 10 10\\times 10\\times 10 10×10×10),输出( 10 × 10 × 10 10\\times 10\\times 10 10×10×10
    • Max-Pooling:输入( 10 × 10 × 10 10\\times 10\\times 10 10×10×10),输出( 5 × 5 × 10 5\\times 5\\times 10 5×5×10,核的大小为 2 × 2 2\\times 2 2×2,padding为 0 0 0,步长为 2 2 2
  • 第二组卷积(包括conv,PReLU)
    • conv:输入( 5 × 5 × 10 5\\times 5\\times 10 5×5×10),输出( 3 × 3 × 16 3\\times 3\\times 16 3×3×16,卷积核大小为 3 × 3 3\\times 3 3×3,padding为 0 0 0,步长为 1 1 1,卷积核的个数为 16 16 16
    • PReLU:输入( 3 × 3 × 16 3\\times 3\\times 16 3×3×16),输出( 3 × 3 × 16 3\\times 3\\times 16 3×3×16
  • 第三组卷积(包括conv,PReLU)
    • conv:输入( 3 × 3 × 16 3\\times 3\\times 16 3×3×16),输出( 1 × 1 × 32 1\\times 1\\times 32 1×1×32,卷积核大小为 3 × 3 3\\times 3 3×3,padding为 0 0 0,步长为 1 1 1,卷积核的个数为 32 32 32
    • PReLU:输入( 1 × 1 × 32 1\\times 1\\times 32 1×1×32),输出( 1 × 1 × 32 1\\times 1\\times 32 1×1×32

最终得到 32 32 32个大小为 1 × 1 1\\times 1 1×1的特征图,下面分为三个任务分别描述:

  • face classification:输入( 1 × 1 × 32 1\\times 1\\times 32 1×1×32),输出( 1 × 1 × 2 1\\times 1\\times 2 1×1×2,卷积核大小为 1 × 1 1\\times 1 1×1,padding为 0 0 0,步长为 1 1 1,卷积核的个数为 2 2 2
  • bounding box regression:输入( 1 × 1 × 32 1\\times 1\\times 32 1×1×32),输出( 1 × 1 × 4 1\\times 1\\times 4 1×1×4,卷积核大小为 1 × 1 1\\times 1 1×1,padding为 0 0 0,步长为 1 1 1,卷积核的个数为 4 4 4
  • facial landmark localization:输入( 1 × 1 × 32 1\\times 1\\times 32 1×1×32),输出( 1 × 1 × 10 1\\times 1\\times 10 1×1×10,卷积核大小为 1 × 1 1\\times 1 1×1,padding为 0 0 0,步长为 1 1 1,卷积核的个数为 10 10 10

注:三个任务的输出都是直接在最后一层的特征图上使用卷积操作。

参考[2]的代码实现,P-Net的代码如下:

class PNet(NetWork):

    def setup(self, task='data', reuse=False):

        with tf.variable_scope('pnet', reuse=reuse):
            (
                self.feed(task) .conv( # 第一组卷积
                    3,
                    3,
                    10,
                    1,
                    1,
                    padding='VALID',
                    relu=False,
                    name='conv1') .prelu(
                    name='PReLU1') .max_pool(
                    2,
                    2,
                    2,
                    2,
                    name='pool1') .conv( # 第二组卷积
                    3,
                    3,
                    16,
                    1,
                    1,
                    padding='VALID',
                    relu=False,
                    name='conv2') .prelu(
                        name='PReLU2') .conv( # 第三组卷积
                            3,
                            3,
                            32,
                            1,
                            1,
                            task=task,
                            padding='VALID',
                            relu=False,
                            name='conv3',
                            wd=self.weight_decay_coeff) .prelu(
                                name='PReLU3'))

        if self.mode == 'train':
            if task == 'cls': # face classification
                (self.feed('PReLU3')
                     .conv(1, 1, 2, 1, 1, task=task, relu=False,
                           name='pnet/conv4-1', wd=self.weight_decay_coeff))
            elif task == 'bbx': # bounding box regression
                (self.feed('PReLU3')
                     .conv(1, 1, 4, 1, 1, task=task, relu=False,
                           name='pnet/conv4-2', wd=self.weight_decay_coeff))
            elif task == 'pts': # facial landmark localization
                (self.feed('PReLU3')
                     .conv(1, 1, 10, 1, 1, task=task, relu=False,
                           name='pnet/conv4-3', wd=self.weight_decay_coeff))
            self.out_put.append(self.get_output())
        else:
            (self.feed('PReLU3')
                 .conv(1, 1, 2, 1, 1, relu=False, name='pnet/conv4-1')
                 .softmax(name='softmax'))
            self.out_put.append(self.get_output())
            (self.feed('PReLU3')
                 .conv(1, 1, 4, 1, 1, relu=False, name='pnet/conv4-2'))
            self.out_put.append(self.get_output())

2.2.2. 第二阶段R-Net

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

第二阶段的模型与第一阶段基本一致,只是在最后一层的特征图后接上了一个全连接层,同时在连接三个不同任务时也是使用了全连接的操作,参考[2]的代码如下:

class RNet(NetWork):

    def setup(self, task='data', reuse=False):

        with tf.variable_scope('rnet', reuse=reuse):
            (
                self.feed(task) .conv( # 第一个卷积
                    3,
                    3,
                    28,
                    1,
                    1,
                    padding='VALID',
                    relu=False,
                    name='conv1') .prelu(
                    name='prelu1') .max_pool(
                    3,
                    3,
                    2,
                    2使用tensorrt对人脸检测网络mtcnn进行加速(代码片段)

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

mtcnn人脸识别(代码片段)

最近看了一些人脸识别的综述及几篇经典论文。这里简单记录下MTCNN论文及Tensorflow的复现过程。感觉人脸检测属于目标检测下的一个方向,不过由通用目标检测改为人脸检测,即多分类改为2分类,且为小目标检测。而且人脸检... 查看详情

基于yolo的人脸检测与人脸对齐(代码片段)

...同时可以对对象的特征点进行回归,最常见的用例是人脸检测与人脸对齐同步完成。将人脸检测和人脸对齐同步完成,mtcnn已经做了类型的事情:由图可见,mtcnn使用了三个卷积神经网络实现了人脸检测和人脸对齐,... 查看详情

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

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

C ++中的Mtcnn人脸对齐

】C++中的Mtcnn人脸对齐【英文标题】:MtcnnfacealignmentinC++【发布时间】:2019-07-1802:21:28【问题描述】:我可以在mtcnn中检测人脸并拥有对齐所需的人脸点。我找不到一个很好的例子,如何将mtcnn中的面与c++对齐?如何在opencv中对齐... 查看详情

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移植安卓并检测视频中人脸(代码片段)

...xff0c;使用vlc播放了rtsp流媒体视频后,想检测视频中的人脸,之前采用了opencv但是遇到低头、抬头和侧脸时候,效果就不太好。所以本篇介绍如何使用mtcnn来检测视频中的人脸。在这里也免费发布了一个chat希望朋友能... 查看详情

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

人脸检测-mtcnn本文参加新星计划人工智能赛道:https://bbs.csdn.net/topics/613989052文章目录人脸检测-mtcnn1.人脸检测1.1人脸检测概述1.2人脸检测的难点1.3人脸检测的应用场景2.mtcnn2.1mtcnn概述2.2mtcnn的网络结构2.3图像金字塔2.4P-Net2.5R-N... 查看详情

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

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

mtcnn进行人脸剪裁和对齐b

1fromscipyimportmisc2importtensorflowastf3importdetect_face4importcv25#importmatplotlib.pyplotasplt6fromPILimportImage7importos8#importscipy.misc9#%pylabinline10fin=‘D:datamale‘11fout=‘D:data\rain 查看详情

人脸检测——mtcnn

本次介绍一篇速度还不错的人脸检测文章:《2016JointFaceDetectionandAlignmentusingMulti-taskCascadedConvolutionalNetworks》.源代码作者刚刚公布,效果相当不错(只有测试代码):https://kpzhang93.github.io/MTCNN_face_d 查看详情

基于yolo的人脸检测与人脸对齐(代码片段)

前言YOLO(YouOnlyLookOnce)是一种基于深度神经网络的对象识别和定位算法,yolo将对象定位作为回归问题求解,在one-stage中实现对象定位与识别,其最大的特点就是快!快!快!既然yolo本来就是通过... 查看详情

MTCNN 与 DLIB 相比如何进行人脸检测?

】MTCNN与DLIB相比如何进行人脸检测?【英文标题】:HowdoesMTCNNperformvsDLIBforfacedetection?【发布时间】:2018-06-0910:18:46【问题描述】:我看到MTCNN被推荐,但没有看到DLIB和MTCNN的直接比较。我认为既然MTCNN使用神经网络,它可能更适... 查看详情

人脸检测实战终极:使用opencv和python进行人脸对齐(代码片段)

使用OpenCV和Python进行人脸对齐这篇博文的目的是演示如何使用OpenCV、Python和面部标志对齐人脸。给定一组面部标志(输入坐标),我们的目标是将图像扭曲并转换为输出坐标空间。在这个输出坐标空间中,整个数... 查看详情

tensorflow 2.0中是不是有mtcnn人脸检测的实现?

】tensorflow2.0中是不是有mtcnn人脸检测的实现?【英文标题】:Isthereanyimplementationofmtcnnfacedetectionintensorflow2.0?tensorflow2.0中是否有mtcnn人脸检测的实现?【发布时间】:2020-01-0512:35:34【问题描述】:最近我搬到了tensorflow==2.0.0-rc0,现... 查看详情

什么是mtcnn人脸识别能力?

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

人脸检测5种方法(代码片段)

众所周知,人脸识别是计算机视觉应用的一个重大领域,在学习人脸识别之前,我们先来简单学习下人脸检测的几种用法。常见的人脸检测方法大致有5种,Haar、Hog、CNN、SSD、MTCNN:注:本文章图片来源于... 查看详情

如何保存 mtcnn 检测到的带有红色边界框的图像?

...8:12【问题描述】:我有这段代码,其中mtcnn检测图像上的人脸,在每个人脸周围绘制一个红色矩形并在屏幕上打印。代码取自:https://machinelearningmastery.com/how-to-per 查看详情