人脸检测MTCNN进行人脸检测的过程

MTCNN是比较经典快速的人脸检测技术,Github:https://github.com/kpzhang93/MTCNN_face_detection_alignment

MTCNN可实现两个任务——人脸检测与人脸关键点检测——由三个级联的轻量级CNN完成:PNet,RNet和Onet。图像数据先后经这三个网络的处理,最终输出人脸检测和关键点检测结果。

检测的过程可见于detect_face函数,以下做简单整理。

一、第一阶段:PNet

  • 输入:待检测的图像,如图:

test.jpg

  • 输出:m*n(最终特征图的尺度)个box坐标回归值以及对应的是否为人脸的得分。经过进一步的计算,得到可能为人脸的box集合,如图红色框:


  • 中间过程简述:将原图重采样(resample),得到一系列尺寸的待检测图。对于每一张待检测图,输入到PNet,会输出一系列box,去掉那些得分(score)不达标的box,并用非极大值抑制(nms)再去掉一部分box。对于所有尺寸的待检测图,都得到类似的box集合。将所有box集合合并,再用nms去除一部分box,余下的就是第一阶段最终的输出。

二、第二阶段:RNet

  • 输入:第一阶段生成的box,在原图中截取对应的区域,将所有截取得到的图像合并到一个四维矩阵中,作为RNet的输入。
  • 输出:对于输入的每个box,输出其对应的坐标回归值以及对应的是否为人脸的得分。将得分不达标的box去掉,得到第二阶段的box集合。也就是说,第二阶段是在第一阶段的基础上对box实现进一步分筛选,同时也会以通过回归将box坐标进行更新,使得其精度更高。如图:

  • 中间过程简述:略。

三、第三阶段:ONet

3.1 人脸检测

  • 输入:类似于RNet,但以第二阶段的输出为输入。
  • 输出:类似于RNet。如图:


  • 中间过程简述:略。

3.2 人脸关键点检测

  • 输入:3.1中最终得到的人脸图像。
  • 输出:N*(2*5)个坐标值。其中N是人脸的数目,每个人脸检测5个关键点。
  • 中间过程简述:略。

四、注意点

  • CNN输出的不是坐标,而是坐标的回归量(这么称不知准确与否),实际的坐标是要通过进一步计算得到的。可以参考bbreg.m文件
  • 第一阶段生成box的时候,用到了generateBoundingBox函数,是从特征图上映射到原图得到box的。如下:
function [boundingbox reg] = generateBoundingBox(map,reg,scale,t)
	%use heatmap to generate bounding boxes
    stride=2;
    cellsize=12;
    boundingbox=[];
	map=map';
	dx1=reg(:,:,1)';
	dy1=reg(:,:,2)';
	dx2=reg(:,:,3)';
	dy2=reg(:,:,4)';
    [y x]=find(map>=t);
	a=find(map>=t); 
    if size(y,1)==1
		y=y';x=x';score=map(a)';dx1=dx1';dy1=dy1';dx2=dx2';dy2=dy2';
	else
		score=map(a);
    end   
	reg=[dx1(a) dy1(a) dx2(a) dy2(a)];
	if isempty(reg)
		reg=reshape([],[0 3]);
	end
    boundingbox=[y x];
    %reg是网络输出的一部分,是坐标的回归值;score也是网络的输出,是“为目标”的得分;
    %fix((stride*(boundingbox-1)+1)/scale)是通过在最终特征图上的坐标,反求对应的原图中的感受野?
   
    boundingbox=[fix((stride*(boundingbox-1)+1)/scale) fix((stride*(boundingbox-1)+cellsize-1+1)/scale) score reg];
end
  • 将一张图像输入到PNet,可以输出m*n组box回归值(每组4个数)及其对应的score;而一张图像输入到RNet,仅会得到1组box回归值及其score;ONet与RNet类似。下图分别是PNet的conv4-2和RNet的conv5-2的参数,红色框出来的地方,显示后者将kernel_size和stride参数注释了,这应该是上述二者输出blob维度不一致的原因吧!
阅读更多

没有更多推荐了,返回首页