MTCNN学习----原理
MTCNN主要包含三个阶段:
1) 利用一个浅层的CNN快速产生候选窗口
2) 利用一个更复杂的CNN排除掉大量非人脸窗口
3) 利用一个更强大的CNN进一步改善结果,并输出人脸关键点位置。
整体框架
测试阶段过程:
首先图像经过金字塔,生成多个尺度的图像,然后输入PNet, PNet由于尺寸很小,所以可以很快的选出候选区域,但是准确率不高,然后采用NMS算法,合并候选框,然后根据候选框提取图像,作为RNet的输入,RNet可以精确的选取边框,一般最后只剩几个边框,最后输入ONet,ONet虽然速度较慢,但是由于经过前两个网络,已经得到了高概率的边框,所以输入ONet的图像较少,然后ONet输出精确的边框和关键点信息.
对于非极大值抑制(NMS),其原理简单的可以理解为:当两个box空间位置非常接近,就以score更高的那个作为基准,看IOU即重合度如何,如果与其重合度超过阈值,就抑制score更小的box,因为没有必要输出两个接近的box,只保留score大的就可以了。
MTCNN的关键参数:
- nms_threshold:非极大值抑制nms筛选人脸框时的IOU阈值,三个网络可单独设定阈值,值设置的过小,nms合并的少,会产生较多冗余计算。示例nms_threshold[3] = { 0.5, 0.7, 0.7 };。
- threshold:人脸框得分阈值,三个网络可单独设定阈值,值设置的太小,会有很多框通过,也就增加了计算量,还有可能导致最后不是人脸的框错认为人脸。示例threshold[3] = {0.8, 0.8, 0.8};
- minsize :最小可检测的人脸图像尺寸,该值大小,可控制图像金字塔的阶层数的参数之一,越小,阶层越多,计算越多。示例minsize = 40;
- 生成图像金字塔时候的缩放系数, 范围(0,1),可控制图像金字塔的阶层数的参数之一,越大,阶层越多,计算越多。示例factor = 0.709;
三个网络结构及处理过程:
-
P-NET
一般Pnet只做检测和人脸框回归两个任务。忽略下图中的Facial landmark。
虽然网络定义的时候input的size是12123,由于Pnet只有卷积层,我们可以直接将resize后的图像喂给网络进行前传,只是得到的结果就不是112和114,而是mm2和mm4了。这样就不用先从resize的图上截取各种12123的图再送入网络了,而是一次性送入,再根据结果回推每个结果对应的12*12的图在输入图片的什么位置。针对金字塔中每张图,网络forward计算后都得到了人脸得分以及人脸框回归的结果。人脸分类得分是两个通道的三维矩阵mm2,其实对应在网络输入图片上mm个12*12的滑框,结合当前图片在金字塔图片中的缩放scale,可以推算出每个滑框在原始图像中的具体坐标。
首先要根据得分进行筛选,得分低于阈值的滑框,排除。
然后利用nms非极大值抑制,对剩下的滑框进行合并。nms具体解释,可以参照我上一篇博客:NMS非极大值抑制:用擂台赛带你从原理到代码脑洞大开恍然大悟
当金字塔中所有图片处理完后,再利用nms对汇总的滑框进行合并,然后利用最后剩余的滑框对应的Bbox结果转换成原始图像中像素坐标,也就是得到了人脸框的坐标。
所以,Pnet最终能够得到了一批人脸框。
-
R-Net
Rnet仍然只做检测和人脸框回归两个任务。忽略下图中的Facial landmark。Rnet的作用是对Pnet得到的人脸框进一步打分筛选,回归人脸框。
将Pnet运算出来的人脸框从原图上截取下来,并且resize到24243,作为Rnet的输入。输出仍然是得分和BBox回归结果。
对得分低于阈值的候选框进行抛弃,剩下的候选框做nms进行合并,然后再将BBox回归结果映射到原始图像的像素坐标上。
所以,Rnet最终得到的是在Pnet结果中精选出来的人脸框。
-
O-Net
Onet将检测,人脸框回归和特征点定位,一起做了。Onet的作用是对Rnet得到的人脸框进一步打分筛选,回归人脸框。同时在每个框上都计算特征点位置。
将Rnet运算出来的人脸框从原图上截取下来,并且resize到48483,作为Onet的输入。输出是得分,BBox回归结果以及landmark位置数据。
分数超过阈值的候选框对应的Bbox回归数据以及landmark数据进行保存。
将Bbox回归数据以及landmark数据映射到原始图像坐标上。
再次实施nms对人脸框进行合并。
经过这层层筛选合并后,最终剩下的Bbox以及其对应的landmark就是我们苦苦追求的结果了。
训练过程: