基于TensorFlow和MTCNN实现人脸检测

一、MTCNN原理

MTCNN提出了一种Multi-task的人脸检测框架,将人脸检测和人脸特征点检测同时进行。论文使用3个CNN级联的方式。

算法流程


当给定一张照片的时候,将其缩放到不同尺度形成图像金字塔,以达到尺度不变。

Stage 1:使用P-Net是一个全卷积网络,用来生成候选窗和边框回归向量(bounding box regression vectors)。使用Bounding box regression的方法来校正这些候选窗,使用非极大值抑制(NMS)合并重叠的候选框。全卷积网络和Faster R-CNN中的RPN一脉相承。

Stage 2:使用N-Net改善候选窗。将通过P-Net的候选窗输入R-Net中,拒绝掉大部分false的窗口,继续使用Bounding box regression和NMS合并。

Stage 3:最后使用O-Net输出最终的人脸框和特征点位置。和第二步类似,但是不同的是生成5个特征点位置。

CNN结构

本文使用三个CNN,结构如图:

MTCNN由三个神经网络组成,P-NET R-NET O-NET 在使用这些网络之前,首先将图片所放到不同的尺度,形成一个图像金字塔。对于第一个P-NET网络输入为12*12*3的RGB图像,该网络要判断这个12*12的图像中(1)是否有人脸,(2)人脸框位置,(3)关键点位置。

同理,R-NET是在24*24*3的范围内寻找,O-NET是在48*48*3的范围内寻找。

每一层的输出都有三部分(1)是否有人脸,(2)人脸框位置,(3)关键点位置 三者对应三个损失。人脸判别部分,使用交叉熵损失;人脸框以及关键点判定,使用L2损失。最后三部分乘以自身的权重相加。

训练
这个算法需要实现三个任务的学习:人脸非人脸的分类,bounding box regression和人脸特征点定位。

(1)人脸检测

这就是一个分类任务,使用交叉熵损失函数即可:

                                         

(2)Bounding box regression

这是一个回归问题,使用平方和损失函数:

                                                        

(3)人脸特征点定位

这也是一个回归问题,目标是5个特征点与标定好的数据的平方和损失:

                                           

二、使用方法

detect_face.py是MTCNN开源的代码,我们这里直接使用即可,det1.npy  det2.npy  det3.npy中储存着训练好的人脸参数,我们主要是想利用这些现有的开源程序来完成我们的功能。

2.1 创建MTCNN结构

pnet, rnet, onet = detect_face.create_mtcnn(sess, None)

2.2 读入图片,识别人脸

image_path = 'b.jpg'

img = misc.imread(image_path)
bounding_boxes, _ = detect_face.detect_face(img, minsize, pnet, rnet, onet, threshold, factor)
nrof_faces = bounding_boxes.shape[0]#人脸数目

2.3 画框

for face_position in bounding_boxes:
    
	face_position=face_position.astype(int)
	
	#print(face_position[0:4])
	
	cv2.rectangle(img, (face_position[0]-10, face_position[1]-10), (face_position[2]+10, face_position[3]+10), (0, 255, 0),5)

使用MTCNN的完整代码如下

from scipy import misc
import tensorflow as tf
import detect_face
import cv2
import matplotlib.pyplot as plt
#%pylab inline

minsize = 20 # minimum size of face
threshold = [ 0.6, 0.7, 0.7 ]  # three steps's threshold
factor = 0.709 # scale factor
gpu_memory_fraction=1.0


with tf.Graph().as_default():
        gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=gpu_memory_fraction)
        sess = tf.Session(config=tf.ConfigProto(gpu_options=gpu_options, log_device_placement=False))
        with sess.as_default():
            pnet, rnet, onet = detect_face.create_mtcnn(sess, None)

image_path = 'b.jpg'

img = misc.imread(image_path)
bounding_boxes, _ = detect_face.detect_face(img, minsize, pnet, rnet, onet, threshold, factor)
nrof_faces = bounding_boxes.shape[0]#人脸数目
print('找到人脸数目为:{}'.format(nrof_faces))


for face_position in bounding_boxes:
    
	face_position=face_position.astype(int)
	
	#print(face_position[0:4])
	
	cv2.rectangle(img, (face_position[0]-10, face_position[1]-10), (face_position[2]+10, face_position[3]+10), (0, 255, 0),5)


plt.imshow(img)
plt.show()

=======================================================================

最近新开的公众号,文章正在一篇篇的更新,

公众号名称:玩转电子世界

各位朋友有什么问题了可以直接在上面提问,我会一一进行解答的。

跟着阳光非宅男,一步步走进电子的世界。

关注之后回复 资料下载 关键词可以获得免费海量视频学习资料下载~~!

已共享的学习视频资料,共享资料正在不断更新中。

共享机器学习/tensorflow视频学习资料:

=======================================================================

发布了70 篇原创文章 · 获赞 73 · 访问量 13万+

猜你喜欢

转载自blog.csdn.net/yunge812/article/details/85706885