使用MTCNN进行人脸检测

人脸检测是人脸识别中重要的一环,MTCNN是比较常用的人脸检测算法,这里主要介绍测试过程。
论文地址

主要流程:

使用MTCNN进行人脸检测_第1张图片
1.做图片金字塔,即将图片resize成不同大小
2.将不同大小的图片输入PNet,得到候选框的偏移值,映射到原图得到许多候选框,做非极大值抑制(nms)去掉部分候选框
3.去原图截取候选框的图像(要截取覆盖这个候选框的最大正方形框),resize成24x24,输入RNet,得到候选框偏移值和分数,继续nms筛选
4.同样方法截取剩余的候选框,resize成48x48,输入ONet,经过nms筛选后得到最终人脸框,同时输出人脸特征点位置

实现细节:

参考代码:https://github.com/TreB1eN/InsightFace_Pytorch 中的mtcnn-pytorch版本,里面有手把手教你怎么做。
不过网络有个bug,PNet中forward函数里“a = F.softmax(a, dim=-1)”,dim应该改为1。也不知道为啥他们运行都没问题。。。

首先关于PNet的输入输出,网络结构如图:
使用MTCNN进行人脸检测_第2张图片
输入:图中输入的宽和高为12X12,这是最小的输入单元,也就是检测到的最小人脸大小。如果要检测大于12X12的人脸,需要将原图像缩小,如缩小一倍就能检测24X24的人脸,因此最开始要生成图像金字塔,将图像resize成不同大小,一般按照0.7的比例缩放,直到最小图片刚好不小于12。如果设定检测最小人脸为15,那么图片金字塔最大图像为原图像的12/15=0.8倍。

输出:输出两个三维数组(landmark的输出不需要,只需要在ONet输出即可),一个表示得分,另一个为候选框的偏移位置,前两维都相当于坐标,每个坐标表示12X12图像单元,代码中stride为2,也就是对于 14X14图像,输出为2X2X(2+4)。
对于每张图的输出先根据得分筛选一部分的候选单元,映射到原图获得候选框坐标,做一遍nms。
每张不同大小的图都输出之后再做一遍nms,之后根据得到的偏移(就是bounding box regression)对候选框进行校准(calibration),论文中是先calibration再nms的,不过对结果貌似没什么影响。
关于偏移,做bounding box regression时得到的是候选框坐标相对于原来的位置,例如原坐标(x1, y1, x2, y2)分别表示左上右下坐标,得到偏移[0.1, 0.2, 0, -0.3],校准后为(x1 + 0.1 * w, y1 + 0.2 * h, x2, y2 - 0.3 * h),w = x2 - x1, h = y2 - y1, 即宽和高,偏移就是改变的坐标与宽或高的比值,这样的一个好处就是图像放大或者缩小时偏移不变。

之后是RNet:
使用MTCNN进行人脸检测_第3张图片
输入:输入图像大小为24X24,因此将上一步得到的候选框从原图中截取后resize到24X24,在这之前需要将候选框按照最长的边改成正方形,这样使图像不被拉长或压缩。

输出:输出同样忽略landmark,得到两个向量(与PNet输出不同,因此RNet输入图像只能为24X24),一个表示得分,用于筛选;另一个是相对偏移量,可直接用于校准resize前的候选框。之后同PNet类似,阈值筛选、nms、校准。

最后ONet:
使用MTCNN进行人脸检测_第4张图片
输入:48X48的图像,所以像RNet的输入一样,先截取正方形再resize
输出:与RNet输出相同,landmarks也要输出,先进行阈值筛选,再根据偏移值对boxes和landmarks校准,最后nms得到最终筛选出来的人脸框以及人脸5个关键点。
以上

你可能感兴趣的:(算法,计算机视觉,人脸识别,人脸检测,MTCNN)