MTCNN----人脸识别(附代码)

本文介绍了MTCNN(Multi-task convolution network)在人脸识别中的应用,详细讲解了图像金字塔、PNet、RNet、ONet四个主要部分的网络结构和解码过程,并提供了相关代码资源链接。通过MTCNN,可以实现从不同尺度的人脸检测到关键点定位的全过程。
摘要由CSDN通过智能技术生成

MTCNN(Multi-task convolution network)

多任务卷积神经网络

https://www.bilibili.com/video/BV1i741177hd?p=2
https://www.bilibili.com/video/BV1fJ411C7AJ
https://github.com/bubbliiiing/mask-recognize
https://blog.csdn.net/weixin_44791964/article/details/103530206

用MTCNN网络识别人脸,结合代码记一篇学习笔记

1、MTCNN网络结构

MTCNN包含4个主要部分:图像金字塔、PNet、RNet、ONet

(1) 图像金字塔

首先,对于一张输入到网络中的图像, 利用图像金字塔得到不同尺度的图像,目的是检测到图像中不同大小的人脸。
构建图像金字塔代码如下:

def calculateScales(img):
    # 把原图像的一条边按比例变为500,另一个按照相同比例缩放(对原图像进行标准化)
    copy_img = img.copy()
    pr_scale = 1.0
    h,w,_ = copy_img.shape
    if min(w,h) > 500:
        # 如果宽高的较小值>500,宽和高都>500,
        pr_scale = 500.0/min(h,w)
        # 较短的边 缩小为500,另一个边按照相同的比例缩小
        w = int(w*pr_scale)
        h = int(h*pr_scale)
    elif max(w,h) < 500:
        # 如果宽高较大值<500,那么说明宽和高都小于500
        pr_scale = 500.0/max(h,w)
        # 较长的边 放大为500,另一边也按照相同的比例放大
        w = int(w*pr_scale)
        h = int(h*pr_scale)

    scales = []
    # 图像金字塔为了得到不同大小的图片,将标准化后的图像乘以factor这个缩放因子
    # factor表示缩放因子
    # 截止的条件就是:宽或高其中的一个值小于12
    factor = 0.709
    factor_count = 0
    minl = min(h,w)
    while minl >= 12:
        # pow(x,y)表示x的y次方
        # 只要宽和高中最小的值>=12,则乘以0.709
        scales.append(pr_scale*pow(factor, factor_count))
        minl *= factor
        factor_count += 1
    return scales

将输入的图片大小进行标准化:resize到500左右,把图片宽高中接近500的那条边转化为500,另一条边按照相同的比例进行缩放。那么另一种情况呢?宽和高一个大于500,一个小于500,那就不变,通常在这种情况下一张图片的宽高就与500接近。
scales中存放的是图片缩小的尺度值。保留一张原图大小的图片,接着以0.709的缩放因子来缩小图片,到什么时候停止呢?缩小后的图片宽、高其中一个小于12,则停止。
这一步,得到了不同尺度的图片。称为图像金字塔。

(2)PNet(Proposal Network)

构建PNet网络结构的代码如下

def create_Pnet(weight_path):
    # h, w, 3
    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)
    # h/2,w/2,10
    x = Conv2D(16, (3, 3), strides=1, padding='valid', name='conv2')(x)
    x = PReLU(shared_axes=[1,2],name='PReLU2')(x)
    # h/2,w/2,32
    x = Conv2D(32, (3, 3), strides=1, padding='valid', name='conv3')(x)
    x = PReLU(shared_axes=[1,2],name='PReLU3')(x)
    # 将h/2,w/2,32 分别进行通道数为2和通道数为4的卷积操作
    # 可以看做将原图片划分成h/2,w/2,32的网格,
    classifier = Conv2D(2, (1, 1), activation='softmax', name='conv4-1')(x) # 框中有人脸的置信度
    # 无激活函数,线性。
    bbox_regress = Conv2D(4, (1, 1), name='conv4-2')(x)# 有人脸的框的左上角和右下角的坐标
    # Pnet输出的结果是很多人脸的候选框和框中存在人脸的置信度
    model = Model([input], [classifier, bbox_regress])
    model.load_weights(weight_path, by_name=True)
    return model

PNet的输入是一张3通道的图片(h,w,3),
输出:classifier框中有人脸的置信度
bbox_regress有人脸的框对应的左上角和右下角的坐标

PNet的网络结构:


Conv2D 卷积核大小为3×3,输出通道数为10
激活函数PReLU
最大池化层MaxPool2D,宽高减半
输出(h/2,w/2,10)


Conv2D 卷积核大小为3×3,输出通道数为16
激活函数PReLU
输出(h/2,w/2,16)


Conv2D 卷积核大小为3×3,输出通道数为32
激活函数PReLU
输出(h/2,w/2,32)


classifier:Conv2D卷积核大小为1×1,输出通道数为2,表示框中存在人脸的置信度
bbox_regressConv2D卷积核大小为1×1,输出通道数为4,表示存在人脸的框左上角和右下角的坐标。

(3)RNet(Refine Network)

RNet网络代码如下:

def create_Rnet(weight_path):
    # resize成24,24,3
    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
  • 2
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值