MTCNN算法

本文章主要介绍MTCNN算法的流程,复现的是此版本(https://github.com/AITTSMD/MTCNN-Tensorflow),MTCNN主要由三个框架组成,分别是PNet,RNet,ONet。下面将分别介绍这三个部分。

文章目录

PNet

因为实际的图片大小不一,所以PNet是一个全卷积网络,对于输入的图片大小可以是任意值;将将图片输入PNet之前,有一个循环,每一次循环会将图片进行缩放,再输入PNet;这样形成一个图片金字塔,图片每次缩放因子在我复现的版本里给的是0.79(论文的初始值应该是0.709),当宽高小于12时候这张图片对应的循环结束,12是PNet的最小图片输入尺寸。下图表示的是PNet的结构:PNet
由上面这张图可以得到,一张12x12x3的图片最终的输出的结果是1x1x32的特征图,再分成三条支路,用于人脸分类、边框回归、人脸特征点定位。

这三条支路的损失函数分别是交叉熵(二分类问题常用)、平方和损失函数、5个特征点与标定好的数据的平方和损失。最后的总损失是三个损失乘上各自的权重比之和,在PNet里面三种损失的权重是1:0.5:0.5。将图片输入PNet后,得到了cls_cls_map, reg这两个数组,其中cls_cls_map是(H,W,2)的二维数组,就是非人脸和人脸的概率。PNet直接输出的边界框并不是传统回归中的边界坐标,而是预测人脸位置相对于输入图片的位置差,即为reg。

将cls_cls_map里面人脸的概率和一个事先设定的阈值相比较,如果大于这个阈值,就将这张图片对应的reg数组里面的预测值提取出来,通过逆运算得到原始像素坐标。对于 x * y 的输入,将产生大小为[(x−12)/2+1][(y−12)2+1]的输出。因为池化层的步长是2,所以上述式子的分母为2。将reg的坐标通过此方法可还原预测边框值在原始图片的像素坐标。最后返回的数组是(x1,y1,x2,y2,score,reg),其中(x1,y1,x2,y2)是bbox在原始图片中的像素坐标。score是cls_cls_map对应的人脸概率。

完成这一步后,将使用非极大值抑制法(NMS)去掉一些重复框,这个算法的原理是将上一步返回的数组的score值最大的那一行元素提取出来,将剩下的所有的元素的score和一个设定好的阈值相比较,将score值大于阈值(0.5)的元素抛弃,再将剩下的元素重复之前的提取最大值并进行比较的操作。直到最后,这样就初步抛弃了那些重合度较高的人脸框。

因为(x1,y1,x2,y2)是在原图像中的像素坐标,reg是候选框区域相对于像素坐标的偏差,这样讲将原像素坐标加上偏差值,即可得到候选框的坐标。将初步筛选后的的bbox按照上面的方法refine,到此为止,PNet这一部分就结束了。输出的是候选框的4个坐标加上对应的score值。

RNet

首先将PNet的输出resize成正方形,这主要是基于人脸一般都是正方形的。

再将PNet生成的bbox里的元素调整一下,生成(dy, edy, dx, edx, y, ey, x, ex, tmpw, tmph)这样的数组;生成的元素的意义如下:

     dx,dy:bbox的相对本身起点坐标(0,0)
     edx,edy:bbox的相对本身终点坐标(tmpw-1, tmph-1)
     x,y : 原始图片的bbox起点
     ex,ey:原始图片的bbox结束点
     tmpw, tmph:原始图片中bbox的宽高

在生成的过程还会有检测,避免bbox的坐标超出原始图片或者为负值;接下来遍历这个数组,将里面的bbox从原始图片里面抠出来,resize成24x24同时进行归一化。

完成了前面的操作后就是将24x24的图片喂入RNet了,下图表示的是RNet的结构:

RNet
可以看出RNet最后是采用的全连接层,这也是为什么喂入的图片统一成24x24大小。

由上面这张图可以得到,一张24x24x3的图片最终的输出的结果是3x3x64的特征图,再经历全连接层后分成三条支路,用于人脸分类、边框回归、人脸特征点定位。这三条支路的损失函数和PNet的一样,各损失的权重比也为1:0.5:0.5。

将图片输入PNet后,得到了cls_scores, reg这两个数组,cls_scores表示非人脸和人脸的概率,reg表示bbox的回归信息。同样将cls_scores中人脸的概率与实现设定的阈值比较,将大于阈值的图片对应的bbox提取出来,过滤掉一部分非人脸的bbox。

接着再次调用NMS,抛弃掉大量的重叠率高的人脸框,经过两次的筛选,剩下的bbox的数量就少了很多。最后进行RNet的最后一步操作,就是回归信息reg来调整bbox的坐标,大致就是将bbox的4个坐标乘上bbox的宽或者高,其中x和宽相乘,y和高相乘。最后就是返回调整后的四个坐标。

ONet

首先将RNet的输出resize成正方形,接下来的操作和对应的RNet部分相似,只是再喂入ONet之前图片是resize乘48x48。

下图表示的是ONet的结构:

ONet

将48x48x3的图片喂入ONet后输出的是3x3x128的特征图,经过全连接层后同样是有着三条支路。三条支路的损失函数与PNet、RNet一样,但是三个损失函数的权重比为1:0.5:1。

这次从ONet的输出接受cls_scores, reg, landmark这三个数组,同样先根据cls_scores的人脸概率是否大于设定的阈值来抛弃一部分非人脸框。接下来就是确定landmark的值,因为前面直接得到的关键点的x、y坐标相关信息并不是x、y的值,而是一个相对于宽高的偏置值,最终的关键点的x、y值可以通过这个偏置值和bbox的宽或者高(x与宽,y与高)相乘再与bbox的坐标相加得到。

接下来就是回归信息reg来调整bbox的坐标,与RNet输出前的操作一样。完成之后经历两次的NMS操作,但是这次的NMS操作与之前的略有不用,大家可以看详细的代码解释。最后就可以输出bbox和landmark了,至此算法就结束了。

这是我的跑了一遍的结果:
在这里插入图片描述

但是我发现关键点定位还是有点不准确,不知道训练过程中哪里出了问题,还在排查中。

这里(生成PNet的人脸数据样本生成P_Net人脸关键点的训练数据训练数据进行合并为PNet生成tfrecord文件PNet的训练生成ONet训练数据生成ONet训练数据RNet的训练)是一些训练过程中的代码的解释。

  • 6
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值