├── README.md ├── result ├── 0.jpg ├── 1.jpg ├── 2.jpg ├── MTCNN_test_0.jpg ├── MTCNN_test_1.jpg └── MTCNN_test_2.jpg ├── version 1.0 ├── MTCNN code │ ├── .ipynb_checkpoints │ │ ├── MTCNN-checkpoint.ipynb │ │ ├── detect face-checkpoint.ipynb │ │ ├── gen_hard_sample-checkpoint.ipynb │ │ ├── test_TFRecord-checkpoint.ipynb │ │ └── train_model-checkpoint.ipynb │ ├── MTCNN.ipynb │ ├── core │ │ ├── MTCNN_model.py │ │ ├── __pycache__ │ │ │ ├── MTCNN_model.cpython-36.pyc │ │ │ └── tool.cpython-36.pyc │ │ └── tool.py │ ├── detect face.ipynb │ ├── detection │ │ ├── __pycache__ │ │ │ ├── detector.cpython-36.pyc │ │ │ └── mtcnn_detector.cpython-36.pyc │ │ ├── detector.py │ │ └── mtcnn_detector.py │ ├── prepare_data │ │ ├── gen_classify_regression_data.py │ │ ├── gen_hard_sample.ipynb │ │ ├── gen_hard_sample_O48.py │ │ ├── gen_hard_sample_R24.py │ │ ├── gen_landmark_data.py │ │ ├── gen_tfrecord.py │ │ ├── test_TFRecord.ipynb │ │ └── test_TFRecord.py │ └── train │ │ ├── .ipynb_checkpoints │ │ └── train_model-checkpoint.ipynb │ │ ├── train.py │ │ ├── train_model.ipynb │ │ └── train_tool.py ├── model │ ├── Onet_model │ │ ├── Onet_model_100000.ckpt.data-00000-of-00001 │ │ ├── Onet_model_100000.ckpt.index │ │ ├── Onet_model_100000.ckpt.meta │ │ ├── Onet_model_60000.ckpt.data-00000-of-00001 │ │ ├── Onet_model_60000.ckpt.index │ │ ├── Onet_model_60000.ckpt.meta │ │ ├── Onet_model_70000.ckpt.data-00000-of-00001 │ │ ├── Onet_model_70000.ckpt.index │ │ ├── Onet_model_70000.ckpt.meta │ │ ├── Onet_model_80000.ckpt.data-00000-of-00001 │ │ ├── Onet_model_80000.ckpt.index │ │ ├── Onet_model_80000.ckpt.meta │ │ ├── Onet_model_90000.ckpt.data-00000-of-00001 │ │ ├── Onet_model_90000.ckpt.index │ │ ├── Onet_model_90000.ckpt.meta │ │ ├── checkpoint │ │ ├── events.out.tfevents.1551514455.DESKTOP-FFN3HIC │ │ └── 训练曲线.png │ ├── Pnet_model │ │ ├── Pnet_model.ckpt-100000.data-00000-of-00001 │ │ ├── Pnet_model.ckpt-100000.index │ │ ├── Pnet_model.ckpt-100000.meta │ │ ├── Pnet_model.ckpt-60000.data-00000-of-00001 │ │ ├── Pnet_model.ckpt-60000.index │ │ ├── Pnet_model.ckpt-60000.meta │ │ ├── Pnet_model.ckpt-70000.data-00000-of-00001 │ │ ├── Pnet_model.ckpt-70000.index │ │ ├── Pnet_model.ckpt-70000.meta │ │ ├── Pnet_model.ckpt-80000.data-00000-of-00001 │ │ ├── Pnet_model.ckpt-80000.index │ │ ├── Pnet_model.ckpt-80000.meta │ │ ├── Pnet_model.ckpt-90000.data-00000-of-00001 │ │ ├── Pnet_model.ckpt-90000.index │ │ ├── Pnet_model.ckpt-90000.meta │ │ ├── checkpoint │ │ ├── events.out.tfevents.1551238146.DESKTOP-FFN3HIC │ │ └── 训练曲线.png │ └── Rnet_model │ │ ├── Rnet_model.ckpt-10000.data-00000-of-00001 │ │ ├── Rnet_model.ckpt-10000.index │ │ ├── Rnet_model.ckpt-10000.meta │ │ ├── Rnet_model.ckpt-100000.data-00000-of-00001 │ │ ├── Rnet_model.ckpt-100000.index │ │ ├── Rnet_model.ckpt-100000.meta │ │ ├── Rnet_model.ckpt-20000.data-00000-of-00001 │ │ ├── Rnet_model.ckpt-20000.index │ │ ├── Rnet_model.ckpt-20000.meta │ │ ├── Rnet_model.ckpt-30000.data-00000-of-00001 │ │ ├── Rnet_model.ckpt-30000.index │ │ ├── Rnet_model.ckpt-30000.meta │ │ ├── Rnet_model.ckpt-40000.data-00000-of-00001 │ │ ├── Rnet_model.ckpt-40000.index │ │ ├── Rnet_model.ckpt-40000.meta │ │ ├── Rnet_model.ckpt-50000.data-00000-of-00001 │ │ ├── Rnet_model.ckpt-50000.index │ │ ├── Rnet_model.ckpt-50000.meta │ │ ├── Rnet_model.ckpt-60000.data-00000-of-00001 │ │ ├── Rnet_model.ckpt-60000.index │ │ ├── Rnet_model.ckpt-60000.meta │ │ ├── Rnet_model.ckpt-70000.data-00000-of-00001 │ │ ├── Rnet_model.ckpt-70000.index │ │ ├── Rnet_model.ckpt-70000.meta │ │ ├── Rnet_model.ckpt-80000.data-00000-of-00001 │ │ ├── Rnet_model.ckpt-80000.index │ │ ├── Rnet_model.ckpt-80000.meta │ │ ├── Rnet_model.ckpt-90000.data-00000-of-00001 │ │ ├── Rnet_model.ckpt-90000.index │ │ ├── Rnet_model.ckpt-90000.meta │ │ ├── checkpoint │ │ ├── events.out.tfevents.1551356909.DESKTOP-FFN3HIC │ │ └── 训练曲线.png └── result │ ├── MTCNN_test_1.jpg │ ├── MTCNN_test_2.jpg │ ├── MTCNN_test_3.jpg │ ├── MTCNN_test_4.jpg │ ├── MTCNN_test_5.jpg │ └── MTCNN_test_6.jpg └── version 2.0 ├── MTCNN code ├── .ipynb_checkpoints │ ├── MTCNN_code-checkpoint.ipynb │ ├── detect face-checkpoint.ipynb │ ├── gen_hard_sample-checkpoint.ipynb │ ├── test_TFRecord-checkpoint.ipynb │ └── train_model-checkpoint.ipynb ├── MTCNN_code.ipynb ├── core │ ├── MTCNN_model.py │ ├── __init__.py │ ├── __pycache__ │ │ ├── MTCNN_model.cpython-36.pyc │ │ └── tool.cpython-36.pyc │ └── tool.py ├── detect face.ipynb ├── detection │ ├── __init__.py │ ├── __pycache__ │ │ ├── detector.cpython-36.pyc │ │ └── mtcnn_detector.cpython-36.pyc │ ├── detector.py │ └── mtcnn_detector.py ├── prepare_data │ ├── .ipynb_checkpoints │ │ ├── gen_hard_sample-checkpoint.ipynb │ │ └── test_TFRecord-checkpoint.ipynb │ ├── __init__.py │ ├── gen_classify_regression_data.py │ ├── gen_hard_sample.py │ ├── gen_landmark_data.py │ ├── gen_tfrecord.py │ ├── test_TFRecord.ipynb │ └── test_TFRecord.py └── train │ ├── __init__.py │ ├── __pycache__ │ └── train_tool.cpython-36.pyc │ ├── train.py │ └── train_tool.py ├── README.md ├── model ├── Onet_model │ ├── Onet_model.ckpt-40000.data-00000-of-00001 │ ├── Onet_model.ckpt-40000.index │ ├── Onet_model.ckpt-40000.meta │ ├── checkpoint │ └── events.out.tfevents.1552807428.XABC-T7910 ├── Pnet_model │ ├── Pnet_model.ckpt-20000.data-00000-of-00001 │ ├── Pnet_model.ckpt-20000.index │ ├── Pnet_model.ckpt-20000.meta │ ├── checkpoint │ └── events.out.tfevents.1552552955.XABC-T7910 └── Rnet_model │ ├── Rnet_model.ckpt-40000.data-00000-of-00001 │ ├── Rnet_model.ckpt-40000.index │ ├── Rnet_model.ckpt-40000.meta │ ├── checkpoint │ └── events.out.tfevents.1552708237.XABC-T7910 └── result ├── MTCNN_test_0.jpg ├── MTCNN_test_1.jpg └── MTCNN_test_2.jpg /README.md: -------------------------------------------------------------------------------- 1 | # MTCNN-tensorflow 2 | 3 | * version 1.0稳定,version 2.0稳定,version 2.1更新中; 4 | 5 | 复现[Joint Face Detection and Alignment Using Multitask Cascaded Convolutional Networks](https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=7553523)论文,参考了众多复现代码,在此附上链接并对表示感谢~ 6 | 7 | * https://github.com/kpzhang93/MTCNN_face_detection_alignment 8 | * https://github.com/CongWeilin/mtcnn-caffe 9 | * https://github.com/Seanlinx/mtcnn 10 | * https://github.com/AITTSMD/MTCNN-Tensorflow 11 | 12 | ## 环境依赖 13 | 14 | version1.0: 15 | 16 | * Window10+GTX 1060+Python3.6+Anaconda5.2.0+Spyder+Tensorflow1.9-gpu 17 | 18 | version2.0: 19 | 20 | * ubuntu16.04+GTX 1080ti+Python3.6+Anaconda5.2.0+Tensorflow1.8-gpu 21 | 22 | ## 结果 23 | 24 | >以下图片皆来源于网络,如有侵权,请联系本人删除。 25 | 26 | ![](result/MTCNN_test_0.jpg) 27 | 28 | ![](result/MTCNN_test_1.jpg) 29 | 30 | ![](result/MTCNN_test_2.jpg) 31 | 32 | ## 总结 33 | 34 | * 自己参考复现的MTCNN代码效果个人感觉一般,时间远没有达到论文中实时的地步。 35 | * 测试阶段一张图片消耗时间主要取决于Pnet,Pnet效果一般导致大量的候选框nms消耗时间,Rnet与Onet速度很快。 36 | * 召回率主要取决于threshold与min_face的取值,由于需要很高的召回率所以threshold取值很低,部分小人脸图片还需要调低min_face,导致了部分图片还是有误检,且运行时间偏慢。 37 | 38 | ## 其他 39 | 40 | 我的[CSDN博客](https://blog.csdn.net/Rrui7739/article/details/82084022)上有version 1.0的详细说明,欢迎大家指教~ 41 | -------------------------------------------------------------------------------- /result/0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/result/0.jpg -------------------------------------------------------------------------------- /result/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/result/1.jpg -------------------------------------------------------------------------------- /result/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/result/2.jpg -------------------------------------------------------------------------------- /result/MTCNN_test_0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/result/MTCNN_test_0.jpg -------------------------------------------------------------------------------- /result/MTCNN_test_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/result/MTCNN_test_1.jpg -------------------------------------------------------------------------------- /result/MTCNN_test_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/result/MTCNN_test_2.jpg -------------------------------------------------------------------------------- /version 1.0/MTCNN code/core/MTCNN_model.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | @author: friedhelm 4 | 5 | """ 6 | import tensorflow as tf 7 | 8 | def prelu(inputs): 9 | 10 | with tf.variable_scope('prelu'): 11 | alphas = tf.get_variable("alphas", shape=inputs.get_shape()[-1], dtype=tf.float32, initializer=tf.constant_initializer(0.25)) 12 | pos = tf.nn.relu(inputs) 13 | neg = alphas * (inputs-abs(inputs))*0.5 14 | 15 | return pos + neg 16 | 17 | 18 | def conv2d(_input,name,conv_size,conv_stride,bias_size,pad,activation='prelu'): 19 | 20 | regularizer=tf.contrib.layers.l2_regularizer(0.0005) 21 | with tf.variable_scope(name): 22 | weight=tf.get_variable('weight',conv_size,initializer=tf.truncated_normal_initializer(stddev=0.1)) 23 | bias=tf.get_variable('bias',bias_size,initializer=tf.constant_initializer(0.0)) 24 | weight_loss=regularizer(weight) 25 | tf.add_to_collection('loss',weight_loss) 26 | conv=tf.nn.conv2d(_input,weight,strides=conv_stride,padding=pad) 27 | he=tf.nn.bias_add(conv,bias) 28 | relu=tf.cond(tf.equal(activation,'prelu'),lambda:prelu(he),lambda:tf.cond(tf.equal(activation,'softmax'),lambda:tf.nn.softmax(he),lambda:he),name='output') 29 | 30 | return relu 31 | 32 | 33 | def fc2d(_input,name,fc_size,bias_size,activation='prelu'): 34 | 35 | regularizer=tf.contrib.layers.l2_regularizer(0.0005) 36 | with tf.variable_scope(name): 37 | weight=tf.get_variable('weight',fc_size,initializer=tf.truncated_normal_initializer(stddev=0.1)) 38 | bias=tf.get_variable('bias',bias_size,initializer=tf.constant_initializer(0.0)) 39 | weight_loss=regularizer(weight) 40 | tf.add_to_collection('weight_loss',weight_loss) 41 | he=tf.nn.bias_add(tf.matmul(_input,weight,name='matmul'),bias) 42 | relu=tf.cond(tf.equal(activation,'prelu'),lambda:prelu(he),lambda:tf.cond(tf.equal(activation,'softmax'),lambda:tf.nn.softmax(he),lambda:he)) 43 | 44 | return relu 45 | 46 | 47 | def pool(_input,name,kernal_size,kernal_stride,pad): 48 | 49 | with tf.variable_scope(name): 50 | pool=tf.nn.max_pool(_input,ksize=kernal_size,strides=kernal_stride,padding=pad) 51 | 52 | return pool 53 | 54 | 55 | def Pnet_model(x,batch_size): 56 | 57 | conv_1=conv2d(x,'conv_1',[3,3,3,10],[1,1,1,1],[10],'VALID') 58 | pool_1=pool(conv_1,'pool_1',[1,3,3,1],[1,2,2,1],'SAME') 59 | conv_2=conv2d(pool_1,'conv_2',[3,3,10,16],[1,1,1,1],[16],'VALID') 60 | conv_3=conv2d(conv_2,'conv_3',[3,3,16,32],[1,1,1,1],[32],'VALID') 61 | 62 | face_label=conv2d(conv_3,'face_label',[1,1,32,2],[1,1,1,1],[2],'VALID','softmax') 63 | bounding_box=conv2d(conv_3,'bounding_box',[1,1,32,4],[1,1,1,1],[4],'VALID','None') 64 | landmark_local=conv2d(conv_3,'landmark_local',[1,1,32,10],[1,1,1,1],[10],'VALID','None') 65 | 66 | return face_label, bounding_box ,landmark_local 67 | 68 | 69 | def Rnet_model(x,batch_size): 70 | 71 | conv_1=conv2d(x,'conv_1',[3,3,3,28],[1,1,1,1],[28],'VALID') 72 | pool_1=pool(conv_1,'pool_1',[1,3,3,1],[1,2,2,1],'SAME') 73 | conv_2=conv2d(pool_1,'conv_2',[3,3,28,48],[1,1,1,1],[48],'VALID') 74 | pool_2=pool(conv_2,'pool_2',[1,3,3,1],[1,2,2,1],'VALID') 75 | conv_3=conv2d(pool_2,'conv_3',[2,2,48,64],[1,1,1,1],[64],'VALID') 76 | 77 | resh1 = tf.reshape(conv_3, [batch_size,3*3*64], name='resh1') 78 | 79 | fc_1=fc2d(resh1,'fc_1',[3*3*64,128],[128]) 80 | 81 | face_label=fc2d(fc_1,'face_label',[128,2],[2],'softmax') 82 | bounding_box=fc2d(fc_1,'bounding_box',[128,4],[4],'None') 83 | landmark_local=fc2d(fc_1,'landmark_local',[128,10],[10],'None') 84 | 85 | return face_label, bounding_box ,landmark_local 86 | 87 | 88 | def Onet_model(x,batch_size): 89 | 90 | conv_1=conv2d(x,'conv_1',[3,3,3,32],[1,1,1,1],[32],'VALID') 91 | pool_1=pool(conv_1,'pool_1',[1,3,3,1],[1,2,2,1],'SAME') 92 | conv_2=conv2d(pool_1,'conv_2',[3,3,32,64],[1,1,1,1],[64],'VALID') 93 | pool_2=pool(conv_2,'pool_2',[1,3,3,1],[1,2,2,1],'VALID') 94 | conv_3=conv2d(pool_2,'conv_3',[3,3,64,64],[1,1,1,1],[64],'VALID') 95 | pool_3=pool(conv_3,'pool_3',[1,2,2,1],[1,2,2,1],'SAME') 96 | conv_4=conv2d(pool_3,'conv_4',[2,2,64,128],[1,1,1,1],[128],'VALID') 97 | 98 | resh1 = tf.reshape(conv_4, [batch_size,3*3*128], name='resh1') 99 | 100 | fc_1=fc2d(resh1,'fc_1',[3*3*128,256],[256]) 101 | 102 | face_label=fc2d(fc_1,'face_label',[256,2],[2],'softmax') 103 | bounding_box=fc2d(fc_1,'bounding_box',[256,4],[4],'None') 104 | landmark_local=fc2d(fc_1,'landmark_local',[256,10],[10],'None') 105 | 106 | return face_label, bounding_box ,landmark_local -------------------------------------------------------------------------------- /version 1.0/MTCNN code/core/__pycache__/MTCNN_model.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/MTCNN code/core/__pycache__/MTCNN_model.cpython-36.pyc -------------------------------------------------------------------------------- /version 1.0/MTCNN code/core/__pycache__/tool.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/MTCNN code/core/__pycache__/tool.cpython-36.pyc -------------------------------------------------------------------------------- /version 1.0/MTCNN code/core/tool.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | @author: friedhelm 4 | 5 | """ 6 | import numpy as np 7 | import cv2 8 | import tensorflow as tf 9 | 10 | def IoU(box, boxes): 11 | """ 12 | Compute IoU between detect box and face boxes 13 | 14 | Parameters: 15 | ---------- 16 | box: numpy array , shape (4, ): x1, y1, x2, y2 17 | random produced box 18 | boxes: numpy array, shape (n, 4): x1, y1, w, h 19 | input ground truth face boxes 20 | 21 | Returns: 22 | ------- 23 | ovr: numpy.array, shape (n, ) 24 | IoU 25 | """ 26 | 27 | box_area = (box[2] - box[0] + 1) * (box[3] - box[1] + 1) 28 | area = boxes[:, 2]*boxes[:, 3] 29 | 30 | x_right=boxes[:, 2]+boxes[:, 0] 31 | y_bottom=boxes[:, 3]+boxes[:, 1] 32 | 33 | xx1 = np.maximum(box[0], boxes[:, 0]) 34 | yy1 = np.maximum(box[1], boxes[:, 1]) 35 | xx2 = np.minimum(box[2], x_right) 36 | yy2 = np.minimum(box[3], y_bottom) 37 | 38 | # compute the width and height of the bounding box 39 | w = np.maximum(0, xx2 - xx1 + 1) 40 | h = np.maximum(0, yy2 - yy1 + 1) 41 | 42 | inter = w * h 43 | ovr = inter / (box_area + area - inter) 44 | return ovr 45 | 46 | 47 | def NMS(box,_overlap): 48 | 49 | if len(box) == 0: 50 | return [] 51 | 52 | #xmin, ymin, xmax, ymax, score, cropped_img, scale 53 | box.sort(key=lambda x :x[4]) 54 | box.reverse() 55 | 56 | pick = [] 57 | x_min = np.array([box[i][0] for i in range(len(box))],np.float32) 58 | y_min = np.array([box[i][1] for i in range(len(box))],np.float32) 59 | x_max = np.array([box[i][2] for i in range(len(box))],np.float32) 60 | y_max = np.array([box[i][3] for i in range(len(box))],np.float32) 61 | 62 | area = (x_max-x_min)*(y_max-y_min) 63 | idxs = np.array(range(len(box))) 64 | 65 | while len(idxs) > 0: 66 | i = idxs[0] 67 | pick.append(i) 68 | 69 | xx1 = np.maximum(x_min[i],x_min[idxs[1:]]) 70 | yy1 = np.maximum(y_min[i],y_min[idxs[1:]]) 71 | xx2 = np.minimum(x_max[i],x_max[idxs[1:]]) 72 | yy2 = np.minimum(y_max[i],y_max[idxs[1:]]) 73 | 74 | w = np.maximum(xx2-xx1,0) 75 | h = np.maximum(yy2-yy1,0) 76 | 77 | overlap = (w*h)/(area[idxs[1:]] + area[i] - w*h) 78 | 79 | idxs = np.delete(idxs, np.concatenate(([0],np.where(((overlap >= _overlap) & (overlap <= 1)))[0]+1))) 80 | 81 | return [box[i] for i in pick] 82 | 83 | 84 | def featuremap(sess,graph,img,scale,map_shape,stride,threshold): 85 | 86 | left=0 87 | up=0 88 | boundingBox=[] 89 | 90 | images=graph.get_tensor_by_name("input/image:0") 91 | label= graph.get_tensor_by_name("output/label:0") 92 | roi= graph.get_tensor_by_name("output/roi:0") 93 | landmark= graph.get_tensor_by_name("output/landmark:0") 94 | img1=np.reshape(img,(-1,img.shape[0],img.shape[1],img.shape[2])) 95 | 96 | a,b,c=sess.run([label,roi,landmark],feed_dict={images:img1}) 97 | a=np.reshape(a,(-1,2)) 98 | b=np.reshape(b,(-1,4)) 99 | c=np.reshape(c,(-1,10)) 100 | for idx,prob in enumerate(a): 101 | 102 | if prob[1]>threshold: 103 | biasBox=[] 104 | biasBox.extend([float(left*stride)/scale,float(up*stride)/scale, float(left*stride+map_shape)/scale, float(up*stride+map_shape)/scale,prob[1]]) 105 | biasBox.extend(b[idx]) 106 | biasBox.extend(c[idx]) 107 | boundingBox.append(biasBox) 108 | 109 | #防止左越界与下越界 110 | if (left*stride+map_shapethreshold: 56 | biasBox=[] 57 | if(len(boxes) == 0): 58 | biasBox.extend([float(left*stride)/scale,float(up*stride)/scale, float(left*stride+12)/scale, float(up*stride+12)/scale,prob[1]]) 59 | else: 60 | biasBox.extend([boxes[idx][0],boxes[idx][1],boxes[idx][2],boxes[idx][3],prob[1]]) 61 | biasBox.extend(pre_box[idx]) 62 | biasBox.extend(pre_land[idx]) 63 | boundingBox.append(biasBox) 64 | 65 | if (len(boxes) == 0): 66 | #prevent the sliding window to overstep the boundary 67 | if (left*stride+img_sizew)|(box[3]>h)|(box[2]-box[0]w)|(t_box[3]>h)|(t_box[2]-t_box[0]=12: 101 | scales.append(pro) 102 | pro*=factor 103 | small*=factor 104 | 105 | for scale in scales: 106 | 107 | crop_img=img 108 | scale_img=cv2.resize(crop_img,((int(crop_img.shape[1]*scale)),(int(crop_img.shape[0]*scale)))) 109 | scale_img1=np.reshape(scale_img,(-1,scale_img.shape[0],scale_img.shape[1],scale_img.shape[2])) 110 | 111 | bounding_boxes=pnet_detector.predict(scale_img1,scale,img_size=12,stride=2,threshold=self.threshold[0],boxes=[]) 112 | 113 | if(bounding_boxes): 114 | for box in bounding_boxes: 115 | total_box.append(box) 116 | 117 | NMS_box=NMS(total_box,0.7) 118 | if(len(NMS_box)==0): 119 | return None,None,None 120 | 121 | score_box,pnet_box,_=self.calibrate_box(img,NMS_box) 122 | 123 | return score_box,pnet_box,None 124 | 125 | 126 | def detect_Rnet(self,rnet_detector,img,bounding_box): 127 | """ 128 | input : detector , img , bounding_box 129 | output: score_box , rnet_box , None 130 | 131 | format of input : 132 | detector : class detector 133 | img : np.array() 134 | bounding_box : list of box output from function(detect_Pnet) -1*[p_face_x1,p_face_x2,p_face_y1,p_face_y2] 135 | 136 | format of output : 137 | score_box : list of score -1*[score] 138 | rnet_box : list of box after calibration -1*[r_face_x1,r_face_x2,r_face_y1,r_face_y2] 139 | """ 140 | score_box=[] 141 | scale_img=np.zeros((len(bounding_box),24,24,3)) 142 | 143 | for idx,box in enumerate(bounding_box): 144 | scale_img[idx,:,:,:] = cv2.resize(img[int(box[1]):int(box[3]),int(box[0]):int(box[2]),:], (24, 24)) 145 | 146 | bounding_boxes=rnet_detector.predict(scale_img,scale=1,img_size=24,stride=4,threshold=self.threshold[1],boxes=bounding_box) 147 | 148 | NMS_box=NMS(bounding_boxes,0.6) 149 | 150 | if(len(NMS_box)==0): 151 | return None,None,None 152 | 153 | score_box,rnet_box,_=self.calibrate_box(img,NMS_box) 154 | 155 | return score_box,rnet_box,None 156 | 157 | 158 | def detect_Onet(self,onet_detector,img,bounding_box): 159 | """ 160 | input : detector , img , bounding_box 161 | output: score_box , onet_box , landmark_box 162 | 163 | format of input : 164 | detector : class detector 165 | img : np.array() 166 | bounding_box : list of box output from function(detect_Rnet) -1*[r_face_x1,r_face_x2,r_face_y1,r_face_y2] 167 | 168 | format of output : 169 | score_box : list of score -1*[score] 170 | onet_box : list of box after calibration -1*[o_face_x1,o_face_x2,o_face_y1,o_face_y2] 171 | landmark_box : list of landmark -1*[5*(o_landmark_x,o_landmark_y)] 172 | """ 173 | score_box=[] 174 | landmark_box=[] 175 | 176 | scale_img=np.zeros((len(bounding_box),48,48,3)) 177 | 178 | for idx,box in enumerate(bounding_box): 179 | scale_img[idx,:,:,:] = cv2.resize(img[int(box[1]):int(box[3]),int(box[0]):int(box[2]),:], (48, 48)) 180 | 181 | bounding_boxes=onet_detector.predict(scale_img,scale=1,img_size=48,stride=8,threshold=self.threshold[2],boxes=bounding_box) 182 | 183 | NMS_box=NMS(bounding_boxes,0.6) 184 | 185 | if(len(NMS_box)==0): 186 | return None,None,None 187 | 188 | score_box,onet_box,landmark_box=self.calibrate_box(img,NMS_box) 189 | 190 | return score_box,onet_box,landmark_box 191 | 192 | 193 | def detect_face(self,images): 194 | """ 195 | used for detecting face in both batch images and single image 196 | 197 | input : images 198 | output: face_boxes , landmark_boxes 199 | 200 | format of input : 201 | img : np.array() batch_size*single_img 202 | 203 | format of output : 204 | face_boxes : list of face_box batch_size*[face_x1,face_x2,face_y1,face_y2] 205 | landmark_boxes : list of landmark_box batch_size*[5*(landmark_x,landmark_y)] 206 | """ 207 | sign=False 208 | bounding_box=[] 209 | landmark_box=[] 210 | face_boxes=[] 211 | landmark_boxes=[] 212 | detect_begin=time.time() 213 | 214 | if(np.size(images.shape)==3): 215 | sign=True 216 | img=np.zeros((1,images.shape[0],images.shape[1],images.shape[2])) 217 | img[0,:,:,:]=images 218 | images=img 219 | 220 | for img in images: 221 | 222 | if(img is None): 223 | face_boxes.append([]) 224 | landmark_boxes.append([]) 225 | continue 226 | 227 | if self.pnet_model: 228 | pt=time.time() 229 | pnet_detector=Detector(self.pnet_model,self.model_path[0],self.batch_size) 230 | score_box,bounding_box,landmark_box=self.detect_Pnet(pnet_detector,img) 231 | 232 | print("pnet-time: ",time.time()-pt) 233 | if((bounding_box is None) or (len(bounding_box)==0)): 234 | face_boxes.append([]) 235 | landmark_boxes.append([]) 236 | continue 237 | 238 | if self.rnet_model: 239 | rt=time.time() 240 | batch_size=len(bounding_box) 241 | rnet_detector=Detector(self.rnet_model,self.model_path[1],batch_size) 242 | score_box,bounding_box,landmark_box=self.detect_Rnet(rnet_detector,img,bounding_box) 243 | 244 | print("rnet-time: ",time.time()-rt) 245 | if((bounding_box is None) or (len(bounding_box)==0)): 246 | face_boxes.append([]) 247 | landmark_boxes.append([]) 248 | continue 249 | 250 | if self.onet_model: 251 | ot=time.time() 252 | batch_size=len(bounding_box) 253 | onet_detector=Detector(self.onet_model,self.model_path[2],batch_size) 254 | score_box,bounding_box,landmark_box=self.detect_Onet(onet_detector,img,bounding_box) 255 | 256 | print("onet-time: ",time.time()-ot) 257 | if((bounding_box is None) or (len(bounding_box)==0)): 258 | face_boxes.append([]) 259 | landmark_boxes.append([]) 260 | continue 261 | 262 | face_boxes.append(bounding_box) 263 | landmark_boxes.append(landmark_box) 264 | 265 | print("detect-time: ",time.time()-detect_begin) 266 | if(sign): 267 | return face_boxes[0],landmark_boxes[0] 268 | else: 269 | return face_boxes,landmark_boxes 270 | 271 | 272 | def detect_single_face(self,img): 273 | """ 274 | used for detecting single face or vidio 275 | 276 | input : images 277 | output: bounding_box , landmark_box 278 | 279 | format of input : 280 | img : np.array() 281 | 282 | format of output : 283 | bounding_box : list of box [face_x1,face_x2,face_y1,face_y2] 284 | landmark_box : list of box [5*(landmark_x,landmark_y)] 285 | """ 286 | bounding_box=[] 287 | landmark_box=[] 288 | detect_begin=time.time() 289 | 290 | if(img is None): 291 | return [],[] 292 | 293 | if self.pnet_model: 294 | pt=time.time() 295 | pnet_detector=Detector(self.pnet_model,self.model_path[0],self.batch_size) 296 | score_box,bounding_box,landmark_box=self.detect_Pnet(pnet_detector,img) 297 | 298 | print("pnet-time: ",time.time()-pt) 299 | if((bounding_box is None) or (len(bounding_box)==0)): 300 | return [],[] 301 | 302 | if self.rnet_model: 303 | rt=time.time() 304 | batch_size=len(bounding_box) 305 | rnet_detector=Detector(self.rnet_model,self.model_path[1],batch_size) 306 | score_box,bounding_box,landmark_box=self.detect_Rnet(rnet_detector,img,bounding_box) 307 | 308 | print("rnet-time: ",time.time()-rt) 309 | if((bounding_box is None) or (len(bounding_box)==0)): 310 | return [],[] 311 | 312 | if self.onet_model: 313 | ot=time.time() 314 | batch_size=len(bounding_box) 315 | onet_detector=Detector(self.onet_model,self.model_path[2],batch_size) 316 | score_box,bounding_box,landmark_box=self.detect_Onet(onet_detector,img,bounding_box) 317 | 318 | print("onet-time: ",time.time()-ot) 319 | if((bounding_box is None) or (len(bounding_box)==0)): 320 | return [],[] 321 | 322 | print("detect-time: ",time.time()-detect_begin) 323 | 324 | return bounding_box,landmark_box -------------------------------------------------------------------------------- /version 1.0/MTCNN code/prepare_data/gen_classify_regression_data.py: -------------------------------------------------------------------------------- 1 | from core.tool import IoU 2 | import numpy as np 3 | from numpy.random import randint 4 | import cv2 5 | import os 6 | import time 7 | 8 | def main(): 9 | 10 | f1 = open(os.path.join(save_dir, 'pos_%d.txt'%(img_size)), 'w') 11 | f2 = open(os.path.join(save_dir, 'neg_%d.txt'%(img_size)), 'w') 12 | f3 = open(os.path.join(save_dir, 'par_%d.txt'%(img_size)), 'w') 13 | 14 | with open(WIDER_spilt_dir) as filenames: 15 | p=0 16 | neg_idx=0 17 | pos_idx=0 18 | par_idx=0 19 | for line in filenames.readlines(): 20 | line=line.strip().split(' ') 21 | if(p==0): 22 | pic_dir=line[0] 23 | p=1 24 | boxes=[] 25 | elif(p==1): 26 | k=int(line[0]) 27 | p=2 28 | elif(p==2): 29 | b=[] 30 | k=k-1 31 | if(k==0): 32 | p=0 33 | for i in range(4): 34 | b.append(int(line[i])) 35 | boxes.append(b) 36 | # format of boxes is [x,y,w,h] 37 | if(p==0): 38 | img=cv2.imread(os.path.join(WIDER_dir,pic_dir).replace('/','\\')) 39 | h,w,c=img.shape 40 | 41 | #save num negative pics whose IoU less than 0.3 42 | num=50 43 | while(num): 44 | size=randint(12,min(w,h)/2) 45 | x=randint(0,w-size) 46 | y=randint(0,h-size) 47 | if(np.max(IoU(np.array([x,y,x+size,y+size]),np.array(boxes)))<0.3): 48 | resized_img = cv2.resize(img[y:y+size,x:x+size,:], (img_size, img_size)) 49 | cv2.imwrite(os.path.join(negative_dir,'neg_%d.jpg'%(neg_idx)),resized_img) 50 | f2.write(os.path.join(negative_dir,'neg_%d.jpg'%(neg_idx)) + ' 0\n') 51 | neg_idx=neg_idx+1 52 | num=num-1 53 | 54 | for box in boxes: 55 | if((box[0]<0)|(box[1]<0)|(max(box[2],box[3])<20)|(min(box[2],box[3])<=5)): 56 | continue 57 | x1, y1, w1, h1 = box 58 | 59 | # crop images near the bounding box if IoU less than 0.3, save as negative samples 60 | for i in range(10): 61 | size = randint(12, min(w, h) / 2) 62 | delta_x = randint(max(-size, -x1), w1) 63 | delta_y = randint(max(-size, -y1), h1) 64 | nx1 = int(max(0, x1 + delta_x)) 65 | ny1 = int(max(0, y1 + delta_y)) 66 | if((nx1 + size > w1)|(ny1 + size > h1)): 67 | continue 68 | if(np.max(IoU(np.array([nx1,ny1,nx1+size,ny1+size]),np.array(boxes)))<0.3): 69 | resized_img = cv2.resize(img[y:y+size,x:x+size,:], (img_size, img_size)) 70 | cv2.imwrite(os.path.join(negative_dir,'neg_%d.jpg'%(neg_idx)),resized_img) 71 | f2.write(os.path.join(negative_dir,'neg_%d.jpg'%(neg_idx)) + ' 0\n') 72 | neg_idx=neg_idx+1 73 | 74 | #save num positive&part face whose IoU more than 0.65|0.4 75 | box_ = np.array(box).reshape(1, -1) 76 | for i in range(10): 77 | size=randint(np.floor(0.8*min(w1,h1)),np.ceil(1.25*max(w1,h1))+1) 78 | 79 | delta_w = randint(-w1 * 0.2, w1 * 0.2 + 1) 80 | delta_h = randint(-h1 * 0.2, h1 * 0.2 + 1) 81 | # random face box 82 | nx1 = int(max(x1 + w1 / 2 + delta_w - size / 2, 0)) 83 | ny1 = int(max(y1 + h1 / 2 + delta_h - size / 2, 0)) 84 | nx2 = nx1 + size 85 | ny2 = ny1 + size 86 | 87 | if( nx2 > w | ny2 > h): 88 | continue 89 | 90 | offset_x1 = (x1 - nx1) / float(size) 91 | offset_y1 = (y1 - ny1) / float(size) 92 | offset_x2 = (x1+w1 - nx2) / float(size) 93 | offset_y2 = (y1+h1 - ny2) / float(size) 94 | 95 | if(IoU(np.array([nx1,ny1,nx2,ny2]),box_)>0.65): 96 | resized_img = cv2.resize(img[ny1:ny2,nx1:nx2,:], (img_size, img_size)) 97 | cv2.imwrite(os.path.join(positive_dir,'pos_%d.jpg'%(pos_idx)),resized_img) 98 | f1.write(os.path.join(positive_dir,'pos_%d.jpg'%(pos_idx)) + ' 1 %.2f %.2f %.2f %.2f\n'%(offset_x1,offset_y1,offset_x2,offset_y2)) 99 | pos_idx=pos_idx+1 100 | 101 | elif(IoU(np.array([nx1,ny1,nx2,ny2]),box_)>0.4): 102 | resized_img = cv2.resize(img[ny1:ny2,nx1:nx2,:], (img_size, img_size)) 103 | cv2.imwrite(os.path.join(par_dir,'par_%d.jpg'%(par_idx)),resized_img) 104 | f3.write(os.path.join(par_dir,'par_%d.jpg'%(par_idx)) + ' -1 %.2f %.2f %.2f %.2f\n'%(offset_x1,offset_y1,offset_x2,offset_y2)) 105 | par_idx=par_idx+1 106 | print("pics all done,neg_pics %d in total,pos_pics %d in total,par_pics %d in total"%(neg_idx,pos_idx,par_idx)) 107 | 108 | f1.close() 109 | f2.close() 110 | f3.close() 111 | 112 | 113 | if __name__=="__main__": 114 | 115 | img_size=12 116 | 117 | WIDER_dir="E:\\friedhelm\\object\\face_detection_MTCNN\\prepare_data\\WIDER_train\\images" 118 | WIDER_spilt_dir="E:\\friedhelm\\object\\face_detection_MTCNN\\prepare_data\\wider_face_split\\wider_face_train_bbx_gt.txt" 119 | negative_dir="E:\\friedhelm\\object\\face_detection_MTCNN\\DATA\\%d\\negative"%(img_size) 120 | positive_dir="E:\\friedhelm\\object\\face_detection_MTCNN\\DATA\\%d\\positive"%(img_size) 121 | par_dir="E:\\friedhelm\\object\\face_detection_MTCNN\\DATA\\%d\\part"%(img_size) 122 | save_dir="E:\\friedhelm\\object\\face_detection_MTCNN\\DATA\\%d"%(img_size) 123 | 124 | if not os.path.exists(positive_dir): 125 | os.makedirs(positive_dir) 126 | if not os.path.exists(par_dir): 127 | os.makedirs(par_dir) 128 | if not os.path.exists(negative_dir): 129 | os.makedirs(negative_dir) 130 | 131 | begin=time.time() 132 | 133 | main() 134 | 135 | print(time.time()-begin) 136 | #6841.530851840973 -------------------------------------------------------------------------------- /version 1.0/MTCNN code/prepare_data/gen_hard_sample_O48.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | @author: friedhelm 4 | 5 | ops: too slow to generate pics and may have some problems in theory 6 | """ 7 | import tensorflow as tf 8 | import numpy as np 9 | import cv2 10 | import time 11 | from core.tool import IoU,NMS 12 | import os 13 | from core.MTCNN_model import Rnet_model 14 | 15 | begin=time.time() 16 | 17 | def featuremap1(sess,graph,img,scales,map_shape,stride,threshold): 18 | 19 | crop_img=img 20 | boundingBox=[] 21 | 22 | for scale in scales: 23 | 24 | img=cv2.resize(crop_img,((int(crop_img.shape[1]*scale)),(int(crop_img.shape[0]*scale)))) 25 | 26 | left=0 27 | up=0 28 | 29 | images=graph.get_tensor_by_name("input/image:0") 30 | label= graph.get_tensor_by_name("output/label:0") 31 | roi= graph.get_tensor_by_name("output/roi:0") 32 | landmark= graph.get_tensor_by_name("output/landmark:0") 33 | img1=np.reshape(img,(-1,img.shape[0],img.shape[1],img.shape[2])) 34 | 35 | a,b,c=sess.run([label,roi,landmark],feed_dict={images:img1}) 36 | a=np.reshape(a,(-1,2)) 37 | b=np.reshape(b,(-1,4)) 38 | c=np.reshape(c,(-1,10)) 39 | for idx,prob in enumerate(a): 40 | 41 | if prob[1]>threshold: 42 | biasBox=[] 43 | biasBox.extend([float(left*stride)/scale,float(up*stride)/scale, float(left*stride+map_shape)/scale, float(up*stride+map_shape)/scale,prob[1]]) 44 | biasBox.extend(b[idx]) 45 | biasBox.extend(c[idx]) 46 | boundingBox.append(biasBox) 47 | 48 | #防止左越界与下越界 49 | if (left*stride+map_shapethreshold: 71 | biasBox=[] 72 | biasBox.extend([P_net_box[idx][0],P_net_box[idx][1],P_net_box[idx][2],P_net_box[idx][3],prob[1]]) 73 | biasBox.extend(b[idx]) 74 | biasBox.extend(c[idx]) 75 | boundingBox.append(biasBox) 76 | 77 | return boundingBox 78 | 79 | 80 | img_size=48 81 | P_map_shape=12 82 | R_map_shape=24 83 | stride=2 84 | factor=0.79 85 | threshold=0.8 86 | 87 | P_graph_path='E:\\friedhelm\\object\\face_detection_MTCNN\\\model\\Pnet_model.ckpt-60000.meta' 88 | P_model_path='E:\\friedhelm\\object\\face_detection_MTCNN\\\model\\Pnet_model.ckpt-60000' 89 | 90 | R_graph_path='E:\\friedhelm\\object\\face_detection_MTCNN\\\Rnet_model\\Rnet_model.ckpt-40000.meta' 91 | R_model_path='E:\\friedhelm\\object\\face_detection_MTCNN\\\Rnet_model\\Rnet_model.ckpt-40000' 92 | 93 | 94 | WIDER_dir="E:\\friedhelm\\object\\face_detection_MTCNN\\prepare_data\\WIDER_train\\images" 95 | WIDER_spilt_dir="E:\\friedhelm\\object\\face_detection_MTCNN\\prepare_data\\wider_face_split\\wider_face_train_bbx_gt.txt" 96 | negative_dir="E:\\friedhelm\\object\\face_detection_MTCNN\\DATA\\%d\\negative"%(img_size) 97 | positive_dir="E:\\friedhelm\\object\\face_detection_MTCNN\\DATA\\%d\\positive"%(img_size) 98 | par_dir="E:\\friedhelm\\object\\face_detection_MTCNN\\DATA\\%d\\part"%(img_size) 99 | save_dir="E:\\friedhelm\\object\\face_detection_MTCNN\\DATA\\%d"%(img_size) 100 | 101 | if not os.path.exists(positive_dir): 102 | os.makedirs(positive_dir) 103 | if not os.path.exists(par_dir): 104 | os.makedirs(par_dir) 105 | if not os.path.exists(negative_dir): 106 | os.makedirs(negative_dir) 107 | 108 | f1 = open(os.path.join(save_dir, 'pos_%d.txt'%(img_size)), 'w') 109 | f2 = open(os.path.join(save_dir, 'neg_%d.txt'%(img_size)), 'w') 110 | f3 = open(os.path.join(save_dir, 'par_%d.txt'%(img_size)), 'w') 111 | 112 | with open(WIDER_spilt_dir) as filenames: 113 | p=0 114 | idx=0 115 | neg_idx=0 116 | pos_idx=0 117 | par_idx=0 118 | for line in filenames.readlines(): 119 | line=line.strip().split(' ') 120 | if(p==0): 121 | pic_dir=line[0] 122 | p=1 123 | boxes=[] 124 | elif(p==1): 125 | k=int(line[0]) 126 | p=2 127 | elif(p==2): 128 | b=[] 129 | k=k-1 130 | if(k==0): 131 | p=0 132 | for i in range(4): 133 | b.append(int(line[i])) 134 | boxes.append(b) 135 | # format of boxes is [x,y,w,h] 136 | if(p==0): 137 | if(idx<5000): 138 | idx+=1 139 | continue 140 | img=cv2.imread(os.path.join(WIDER_dir,pic_dir).replace('/','\\')) 141 | h,w,c=img.shape 142 | print(pic_dir) 143 | if(min(h,w)<20): 144 | continue 145 | model_begin=time.time() 146 | scales=[] 147 | total_box=[] 148 | small=min(img.shape[0:2]) 149 | pro=12/20 150 | 151 | while small>=20: 152 | scales.append(pro) 153 | pro*=factor 154 | small*=factor 155 | 156 | #方式1 157 | P_graph=tf.Graph() 158 | with P_graph.as_default(): 159 | P_saver=tf.train.import_meta_graph(P_graph_path) 160 | with tf.Session(graph=P_graph) as sess: 161 | P_saver.restore(sess,P_model_path) 162 | bounding_boxes=featuremap1(sess,P_graph,img,scales,P_map_shape,2,threshold) 163 | 164 | 165 | P_NMS_box=NMS(bounding_boxes,0.7) 166 | P_net_box=[] 167 | for box_ in P_NMS_box: 168 | 169 | box=box_.copy() 170 | if((box[0]<0)|(box[1]<0)|(box[2]>w)|(box[3]>h)|(box[2]-box[0]<=20)|(box[3]-box[1]<=20)): 171 | continue 172 | # format of total_box: [x1,y1,x2,y2,score,offset_x1,offset_y1,offset_x2,offset_y2,10*landmark] 173 | 174 | t_box=[0]*4 175 | t_w=box[2]-box[0]+1 176 | t_h=box[3]-box[1]+1 177 | 178 | t_box[0]=box[5]*t_w+box[0] 179 | t_box[1]=box[6]*t_h+box[1] 180 | t_box[2]=box[7]*t_w+box[2] 181 | t_box[3]=box[8]*t_h+box[3] 182 | # 计算真实人脸框 183 | 184 | if((t_box[0]<0)|(t_box[1]<0)|(t_box[2]>img.shape[1])|(t_box[3]>img.shape[0])|(t_box[2]-t_box[0]<=20)|(t_box[3]-t_box[1]<=20)): 185 | continue 186 | 187 | ti_box=t_box.copy() 188 | ti_box=[int(_) for _ in ti_box] 189 | 190 | P_net_box.append(ti_box) 191 | 192 | R_graph=tf.Graph() 193 | with R_graph.as_default(): 194 | images = tf.placeholder(tf.float32) 195 | label,roi,landmark=Rnet_model(images,len(P_net_box)) 196 | # R_saver=tf.train.import_meta_graph(R_graph_path) 197 | R_saver=tf.train.Saver() 198 | with tf.Session() as sess: 199 | R_saver.restore(sess,R_model_path) 200 | resized_img=np.zeros((len(P_net_box),R_map_shape,R_map_shape,3),dtype=np.float32) 201 | for i,box in enumerate(P_net_box): 202 | resized_img[i,:,:,:] = cv2.resize(img[box[1]:box[3],box[0]:box[2],:], (R_map_shape,R_map_shape)) 203 | bounding_boxes=featuremap2(sess,images,label,roi,landmark,resized_img,1,R_map_shape,4,0.85,P_net_box) 204 | 205 | R_NMS_box=NMS(bounding_boxes,0.6) 206 | neg_num=0 207 | 208 | for box_ in R_NMS_box: 209 | 210 | box=box_.copy() 211 | if((box[0]<0)|(box[1]<0)|(box[2]>w)|(box[3]>h)|(box[2]-box[0]<=20)|(box[3]-box[1]<=20)): 212 | continue 213 | # format of total_box: [x1,y1,x2,y2,score,offset_x1,offset_y1,offset_x2,offset_y2,10*landmark] 214 | 215 | t_box=[0]*4 216 | t_w=box[2]-box[0]+1 217 | t_h=box[3]-box[1]+1 218 | 219 | t_box[0]=box[5]*t_w+box[0] 220 | t_box[1]=box[6]*t_h+box[1] 221 | t_box[2]=box[7]*t_w+box[2] 222 | t_box[3]=box[8]*t_h+box[3] 223 | # 计算真实人脸框 224 | 225 | if((t_box[0]<0)|(t_box[1]<0)|(t_box[2]>img.shape[1])|(t_box[3]>img.shape[0])|(t_box[2]-t_box[0]<=20)|(t_box[3]-t_box[1]<=20)): 226 | continue 227 | 228 | ti_box=t_box.copy() 229 | ti_box=[int(_) for _ in ti_box] 230 | 231 | Iou=IoU(np.array(t_box),np.array(boxes)) 232 | 233 | if(np.max(Iou)<0.3): 234 | resized_img = cv2.resize(img[ti_box[1]:ti_box[3],ti_box[0]:ti_box[2],:], (img_size,img_size)) 235 | cv2.imwrite(os.path.join(negative_dir,'neg_%d.jpg'%(neg_idx)),resized_img) 236 | f2.write(os.path.join(negative_dir,'neg_%d.jpg'%(neg_idx)) + ' 0\n') 237 | neg_idx=neg_idx+1 238 | neg_num=neg_num+1 239 | 240 | else: 241 | x1,y1,w1,h1=boxes[np.argmax(Iou)] 242 | 243 | offset_x1 = (x1 - t_box[0]) / float(t_box[2]-t_box[0]+1) 244 | offset_y1 = (y1 - t_box[1]) / float(t_box[3]-t_box[1]+1) 245 | offset_x2 = (x1+w1 - t_box[2]) / float(t_box[2]-t_box[0]+1) 246 | offset_y2 = (y1+h1 - t_box[3]) / float(t_box[3]-t_box[1]+1) 247 | 248 | if(np.max(Iou)>0.65): 249 | resized_img = cv2.resize(img[ti_box[1]:ti_box[3],ti_box[0]:ti_box[2],:], (img_size, img_size)) 250 | cv2.imwrite(os.path.join(positive_dir,'pos_%d.jpg'%(pos_idx)),resized_img) 251 | f1.write(os.path.join(positive_dir,'pos_%d.jpg'%(pos_idx)) + ' 1 %.2f %.2f %.2f %.2f\n'%(offset_x1,offset_y1,offset_x2,offset_y2)) 252 | pos_idx=pos_idx+1 253 | 254 | elif(np.max(Iou)>0.4): 255 | resized_img = cv2.resize(img[ti_box[1]:ti_box[3],ti_box[0]:ti_box[2],:], (img_size, img_size)) 256 | cv2.imwrite(os.path.join(par_dir,'par_%d.jpg'%(par_idx)),resized_img) 257 | f3.write(os.path.join(par_dir,'par_%d.jpg'%(par_idx)) + ' -1 %.2f %.2f %.2f %.2f\n'%(offset_x1,offset_y1,offset_x2,offset_y2)) 258 | par_idx=par_idx+1 259 | print(time.time()-model_begin) 260 | idx+=1 261 | if(idx%100==0): 262 | print('idx: ',idx," ;neg_idx: ",neg_idx," ;pos_idx: ",pos_idx," ;par_idx: ",par_idx) 263 | print(time.time()-begin) 264 | print("pics all done,neg_pics %d in total,pos_pics %d in total,par_pics %d in total"%(neg_idx,pos_idx,par_idx)) 265 | 266 | f1.close() 267 | f2.close() 268 | f3.close() 269 | print(time.time()-begin ) 270 | # idx: 10000 ;neg_idx: 9825 ;pos_idx: 98071 ;par_idx: 32023 -------------------------------------------------------------------------------- /version 1.0/MTCNN code/prepare_data/gen_hard_sample_R24.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | @author: friedhelm 4 | 5 | """ 6 | #159424张人脸 7 | import tensorflow as tf 8 | import numpy as np 9 | import cv2 10 | import time 11 | from core.tool import IoU,NMS,featuremap 12 | import os 13 | 14 | def main(): 15 | saver=tf.train.import_meta_graph(graph_path) 16 | 17 | f1 = open(os.path.join(save_dir, 'pos_%d.txt'%(img_size)), 'w') 18 | f2 = open(os.path.join(save_dir, 'neg_%d.txt'%(img_size)), 'w') 19 | f3 = open(os.path.join(save_dir, 'par_%d.txt'%(img_size)), 'w') 20 | 21 | with tf.Session() as sess: 22 | 23 | saver.restore(sess,model_path) 24 | graph = tf.get_default_graph() 25 | 26 | with open(WIDER_spilt_dir) as filenames: 27 | p=0 28 | idx=0 29 | neg_idx=0 30 | pos_idx=0 31 | par_idx=0 32 | for line in filenames.readlines(): 33 | line=line.strip().split(' ') 34 | if(p==0): 35 | pic_dir=line[0] 36 | p=1 37 | boxes=[] 38 | elif(p==1): 39 | k=int(line[0]) 40 | p=2 41 | elif(p==2): 42 | b=[] 43 | k=k-1 44 | if(k==0): 45 | p=0 46 | for i in range(4): 47 | b.append(int(line[i])) 48 | boxes.append(b) 49 | # format of boxes is [x,y,w,h] 50 | if(p==0): 51 | img=cv2.imread(os.path.join(WIDER_dir,pic_dir).replace('/','\\')) 52 | h,w,c=img.shape 53 | print(pic_dir) 54 | if(min(h,w)<20): 55 | continue 56 | 57 | scales=[] 58 | total_box=[] 59 | pro=map_shape/min_face_size 60 | small=min(img.shape[0:2])*pro 61 | 62 | 63 | while small>=12: 64 | scales.append(pro) 65 | pro*=factor 66 | small*=factor 67 | 68 | for scale in scales: 69 | 70 | scale_img=cv2.resize(img,((int(img.shape[1]*scale)),(int(img.shape[0]*scale)))) 71 | bounding_boxes=featuremap(sess,graph,scale_img,scale,map_shape,stride,threshold) 72 | 73 | if(bounding_boxes): 74 | for box in bounding_boxes: 75 | total_box.append(box) 76 | 77 | NMS_box=NMS(total_box,0.7) 78 | neg_num=0 79 | for box_ in NMS_box: 80 | 81 | box=box_.copy() 82 | if((box[0]<0)|(box[1]<0)|(box[2]>w)|(box[3]>h)|(box[2]-box[0]<=min_face_size)|(box[3]-box[1]<=min_face_size)): 83 | continue 84 | # format of total_box: [x1,y1,x2,y2,score,offset_x1,offset_y1,offset_x2,offset_y2,10*landmark] 85 | 86 | t_box=[0]*4 87 | t_w=box[2]-box[0]+1 88 | t_h=box[3]-box[1]+1 89 | 90 | t_box[0]=box[5]*t_w+box[0] 91 | t_box[1]=box[6]*t_h+box[1] 92 | t_box[2]=box[7]*t_w+box[2] 93 | t_box[3]=box[8]*t_h+box[3] 94 | # calculate ground truth predict-face boxes 95 | 96 | if((t_box[0]<0)|(t_box[1]<0)|(t_box[2]>w)|(t_box[3]>h)|(t_box[2]-t_box[0]<=min_face_size)|(t_box[3]-t_box[1]<=min_face_size)): 97 | continue 98 | 99 | ti_box=t_box.copy() 100 | ti_box=[int(_) for _ in ti_box] 101 | 102 | Iou=IoU(np.array(t_box),np.array(boxes)) 103 | 104 | if((np.max(Iou)<0.3)&(neg_num<60)): 105 | resized_img = cv2.resize(img[ti_box[1]:ti_box[3],ti_box[0]:ti_box[2],:], (img_size,img_size)) 106 | cv2.imwrite(os.path.join(negative_dir,'neg_%d.jpg'%(neg_idx)),resized_img) 107 | f2.write(os.path.join(negative_dir,'neg_%d.jpg'%(neg_idx)) + ' 0\n') 108 | neg_idx=neg_idx+1 109 | neg_num=neg_num+1 110 | 111 | else: 112 | x1,y1,w1,h1=boxes[np.argmax(Iou)] 113 | 114 | offset_x1 = (x1 - t_box[0]) / float(t_box[2]-t_box[0]+1) 115 | offset_y1 = (y1 - t_box[1]) / float(t_box[3]-t_box[1]+1) 116 | offset_x2 = (x1+w1 - t_box[2]) / float(t_box[2]-t_box[0]+1) 117 | offset_y2 = (y1+h1 - t_box[3]) / float(t_box[3]-t_box[1]+1) 118 | 119 | if(np.max(Iou)>0.65): 120 | resized_img = cv2.resize(img[ti_box[1]:ti_box[3],ti_box[0]:ti_box[2],:], (img_size, img_size)) 121 | cv2.imwrite(os.path.join(positive_dir,'pos_%d.jpg'%(pos_idx)),resized_img) 122 | f1.write(os.path.join(positive_dir,'pos_%d.jpg'%(pos_idx)) + ' 1 %.2f %.2f %.2f %.2f\n'%(offset_x1,offset_y1,offset_x2,offset_y2)) 123 | pos_idx=pos_idx+1 124 | 125 | elif(np.max(Iou)>0.4): 126 | resized_img = cv2.resize(img[ti_box[1]:ti_box[3],ti_box[0]:ti_box[2],:], (img_size, img_size)) 127 | cv2.imwrite(os.path.join(par_dir,'par_%d.jpg'%(par_idx)),resized_img) 128 | f3.write(os.path.join(par_dir,'par_%d.jpg'%(par_idx)) + ' -1 %.2f %.2f %.2f %.2f\n'%(offset_x1,offset_y1,offset_x2,offset_y2)) 129 | par_idx=par_idx+1 130 | idx+=1 131 | if(idx%100==0): 132 | print('idx: ',idx," ;neg_idx: ",neg_idx," ;pos_idx: ",pos_idx," ;par_idx: ",par_idx) 133 | print(time.time()-begin) 134 | print("pics all done,neg_pics %d in total,pos_pics %d in total,par_pics %d in total"%(neg_idx,pos_idx,par_idx)) 135 | 136 | f1.close() 137 | f2.close() 138 | f3.close() 139 | 140 | 141 | if __name__=="__main__": 142 | 143 | begin=time.time() 144 | img_size=24 145 | map_shape=12 146 | min_face_size=20 147 | stride=2 148 | factor=0.79 149 | threshold=0.8 150 | 151 | graph_path='E:\\friedhelm\\object\\face_detection_MTCNN\\\Pnet_model\\Pnet_model.ckpt-60000.meta' 152 | model_path='E:\\friedhelm\\object\\face_detection_MTCNN\\\Pnet_model\\Pnet_model.ckpt-60000' 153 | 154 | WIDER_dir="E:\\friedhelm\\object\\face_detection_MTCNN\\prepare_data\\WIDER_train\\images" 155 | WIDER_spilt_dir="E:\\friedhelm\\object\\face_detection_MTCNN\\prepare_data\\wider_face_split\\wider_face_train_bbx_gt.txt" 156 | negative_dir="E:\\friedhelm\\object\\face_detection_MTCNN\\DATA\\%d\\negative"%(img_size) 157 | positive_dir="E:\\friedhelm\\object\\face_detection_MTCNN\\DATA\\%d\\positive"%(img_size) 158 | par_dir="E:\\friedhelm\\object\\face_detection_MTCNN\\DATA\\%d\\part"%(img_size) 159 | save_dir="E:\\friedhelm\\object\\face_detection_MTCNN\\DATA\\%d"%(img_size) 160 | 161 | if not os.path.exists(positive_dir): 162 | os.makedirs(positive_dir) 163 | if not os.path.exists(par_dir): 164 | os.makedirs(par_dir) 165 | if not os.path.exists(negative_dir): 166 | os.makedirs(negative_dir) 167 | 168 | main() 169 | 170 | print(time.time()-begin) 171 | 172 | #pics all done,neg_pics 758503 in total,pos_pics 285017 in total,par_pics 572771 in total 173 | # 17590.795156002045 -------------------------------------------------------------------------------- /version 1.0/MTCNN code/prepare_data/gen_landmark_data.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | @author: friedhelm 4 | 5 | """ 6 | 7 | from core.tool import IoU,flip 8 | import numpy as np 9 | import random 10 | from numpy.random import randint 11 | import cv2 12 | import os 13 | import time 14 | 15 | def main(): 16 | 17 | f4 = open(os.path.join(save_dir, 'land_%d.txt'%(img_size)), 'w') 18 | 19 | with open(pic_spilt_dir) as filenames: 20 | land_idx=0 21 | for line in filenames: 22 | img_list=[] 23 | mark_list=[] 24 | line=line.strip().split(' ') 25 | img=cv2.imread(os.path.join(lfw_dir,line[0])) 26 | box=(line[1],line[2],line[3],line[4]) 27 | box=[int(_) for _ in box] 28 | #format of box is [x,x+w,y,y+h] 29 | height,weight,channel=img.shape 30 | landmark=np.zeros((5,2)) 31 | for i in range(5): 32 | mark=(float(line[5+2*i]),float(line[5+2*i+1])) 33 | landmark[i]=mark 34 | 35 | facemark=np.zeros((5,2)) 36 | for i in range(5): 37 | mark=((landmark[i][0]-box[0])/(box[1]-box[0]),(landmark[i][1]-box[2])/(box[3]-box[2])) 38 | facemark[i]=mark 39 | img_list.append(cv2.resize(img[box[2]:box[3],box[0]:box[1]], (img_size, img_size))) 40 | mark_list.append(facemark.reshape(10)) 41 | 42 | box_=[box[0],box[2],box[1],box[3]] 43 | #format of box is [x,y,x+w,y+h] 44 | x1,y1,x2,y2=box_ 45 | w=x2-x1+1 46 | h=y2-y1+1 47 | 48 | if((x1<0)|(y1<0)|(max(w,h)<40)|(min(w,h)<=5)): 49 | continue 50 | num=40 51 | while(num): 52 | 53 | size=randint(np.floor(0.8*min(w,h)),np.ceil(1.25*max(w,h))+1) 54 | 55 | delta_w = randint(-w * 0.2, w * 0.2 + 1) 56 | delta_h = randint(-h * 0.2, h * 0.2 + 1) 57 | # random face box 58 | nx1 = int(max(x1 + w / 2 + delta_w - size / 2, 0)) 59 | ny1 = int(max(y1 + h / 2 + delta_h - size / 2, 0)) 60 | nx2 = nx1 + size 61 | ny2 = ny1 + size 62 | 63 | if( nx2 > weight | ny2 > height): 64 | continue 65 | 66 | _box=[x1,y1,w,h] 67 | _box=np.array(_box).reshape(1,-1) 68 | if(IoU(np.array([nx1,ny1,nx2,ny2]),_box)>0.65): 69 | facemark=np.zeros((5,2)) 70 | for i in range(5): 71 | mark=((landmark[i][0]-nx1)/size,(landmark[i][1]-ny1)/size) 72 | facemark[i]=mark 73 | img_list.append(cv2.resize(img[ny1:ny2,nx1:nx2,:], (img_size, img_size))) 74 | mark_list.append(facemark.reshape(10)) 75 | 76 | #mirro 77 | mirro_mark=facemark.copy() 78 | if(random.choice([0,1])): 79 | img1,mirro_mark=flip(img[ny1:ny2,nx1:nx2,:],mirro_mark) 80 | img_list.append(cv2.resize(img1, (img_size, img_size))) 81 | mark_list.append(mirro_mark.reshape(10)) 82 | 83 | num=num-1 84 | for i in range(len(img_list)): 85 | 86 | if np.sum(np.where(mark_list[i] <= 0, 1, 0)) > 0: 87 | continue 88 | 89 | if np.sum(np.where(mark_list[i] >= 1, 1, 0)) > 0: 90 | continue 91 | 92 | cv2.imwrite(os.path.join(landmark_dir,'land_%d.jpg'%(land_idx)),img_list[i]) 93 | mark=[str(_)for _ in mark_list[i]] 94 | f4.write(os.path.join(landmark_dir,'land_%d.jpg'%(land_idx)) +' -2 '+' '.join(mark)+'\n') 95 | land_idx=land_idx+1 96 | 97 | f4.close() 98 | 99 | if __name__=="__main__": 100 | 101 | img_size=12 102 | 103 | #change img_size to P=12 R=24 O=48 net 104 | 105 | begin=time.time() 106 | 107 | lfw_dir="E:\\friedhelm\\object\\face_detection_MTCNN\\prepare_data" 108 | pic_spilt_dir="E:\\friedhelm\\object\\face_detection_MTCNN\\prepare_data\\trainImageList.txt" 109 | landmark_dir="E:\\friedhelm\\object\\face_detection_MTCNN\\DATA\\%d\\landmark"%(img_size) 110 | save_dir="E:\\friedhelm\\object\\face_detection_MTCNN\\DATA\\%d"%(img_size) 111 | 112 | if not os.path.exists(landmark_dir): 113 | os.makedirs(landmark_dir) 114 | 115 | main() 116 | 117 | print(time.time()-begin) -------------------------------------------------------------------------------- /version 1.0/MTCNN code/prepare_data/gen_tfrecord.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | @author: friedhelm 4 | 5 | """ 6 | import tensorflow as tf 7 | import cv2 8 | import random 9 | import time 10 | 11 | def main(): 12 | 13 | t_time=time.time() 14 | for index,term in enumerate(terms): 15 | num=0 16 | print("%s start"%(term)) 17 | with tf.python_io.TFRecordWriter("E:\\friedhelm\\object\\face_detection_MTCNN\\DATA\\%d\\%s_train.tfrecords"%(img_size,term)) as writer: 18 | with open(r'E:\friedhelm\object\face_detection_MTCNN\DATA\%d\%s.txt'%(img_size,term)) as readlines: 19 | readlines=[line.strip().split(' ') for line in readlines] 20 | random.shuffle(readlines) 21 | for i,line in enumerate(readlines): 22 | if(i%10000==0): 23 | print(i,time.time()-t_time) 24 | t_time=time.time() 25 | img=cv2.imread(line[0].replace('/','\\')) 26 | if(img is None): 27 | continue 28 | img_raw = img.tobytes() 29 | label=int(line[1]) 30 | roi=[0.0]*4 31 | landmark=[0.0]*10 32 | if(len(line)==6): 33 | roi=[float(_) for _ in line[2:6]] 34 | if(len(line)==12): 35 | landmark=[float(_) for _ in line[2:12]] 36 | example = tf.train.Example(features=tf.train.Features(feature={ 37 | 'img': tf.train.Feature(bytes_list=tf.train.BytesList(value=[img_raw])), 38 | "label": tf.train.Feature(int64_list=tf.train.Int64List(value=[label])), 39 | "roi": tf.train.Feature(float_list=tf.train.FloatList(value=roi)), 40 | "landmark": tf.train.Feature(float_list=tf.train.FloatList(value=landmark)), 41 | })) 42 | writer.write(example.SerializeToString()) #序列化为字符串 43 | num+=1 44 | if(num==base*scale[index]): 45 | print("%s finish"%(term)) 46 | break 47 | 48 | if __name__=="__main__": 49 | 50 | img_size=12 51 | #change img_size to P=12 R=24 O=48 net 52 | terms=['neg_%d'%(img_size),'pos_%d'%(img_size),'par_%d'%(img_size),'land_%d'%(img_size)] 53 | scale=[3,1,1,2] 54 | 55 | #set base number of pos_pic 56 | base=200000 57 | 58 | begin=time.time() 59 | 60 | main() 61 | 62 | print(time.time()-begin) 63 | 64 | #Pnet train_data 65 | #neg 645017 66 | #par 507206 67 | #pos 285560 68 | #land 584332 69 | 70 | #Rnet train_data neg_pics 758503 in total,pos_pics 285017 in total,par_pics 572771 in total -------------------------------------------------------------------------------- /version 1.0/MTCNN code/prepare_data/test_TFRecord.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | @author: friedhelm 4 | 5 | """ 6 | import tensorflow as tf 7 | 8 | filename_queue = tf.train.string_input_producer(["E:\\friedhelm\\object\\face_detection_MTCNN\\DATA\\48\\neg_48_train.tfrecords"],shuffle=True,num_epochs=1) 9 | 10 | reader = tf.TFRecordReader() 11 | _, serialized_example = reader.read(filename_queue) #返回文件名和文件 12 | 13 | features = tf.parse_single_example(serialized_example, 14 | features={ 15 | 'img':tf.FixedLenFeature([],tf.string), 16 | 'label':tf.FixedLenFeature([],tf.int64), 17 | 'roi':tf.FixedLenFeature([4],tf.float32), 18 | 'landmark':tf.FixedLenFeature([10],tf.float32), 19 | }) 20 | img=tf.decode_raw(features['img'],tf.uint8) 21 | label=tf.cast(features['label'],tf.int32) 22 | roi=tf.cast(features['roi'],tf.float32) 23 | landmark=tf.cast(features['landmark'],tf.float32) 24 | img = tf.reshape(img, [48,48,3]) 25 | # img=img_preprocess(img) 26 | min_after_dequeue = 10000 27 | batch_size = 64 28 | capacity = min_after_dequeue + 10 * batch_size 29 | image_batch, label_batch, roi_batch, landmark_batch = tf.train.shuffle_batch([img,label,roi,landmark], 30 | batch_size=batch_size, 31 | capacity=capacity, 32 | min_after_dequeue=min_after_dequeue, 33 | num_threads=7) 34 | 35 | 36 | i=0 37 | with tf.Session() as sess: 38 | sess.run((tf.global_variables_initializer(), 39 | tf.local_variables_initializer())) 40 | coord = tf.train.Coordinator() 41 | threads = tf.train.start_queue_runners(sess=sess,coord=coord) 42 | while(1): 43 | i=i+1 44 | if(i%9==1): 45 | print(sess.run(label_batch)) -------------------------------------------------------------------------------- /version 1.0/MTCNN code/train/train.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | @author: friedhelm 4 | 5 | """ 6 | import tensorflow as tf 7 | import time 8 | from core.tool import read_multi_tfrecords,image_color_distort 9 | from core.MTCNN_model import Pnet_model,Rnet_model,Onet_model 10 | from train.train_tool import label_los,roi_los,landmark_los,cal_accuracy 11 | import os 12 | 13 | def train(image,label,roi,landmark,model,model_name): 14 | 15 | _label, _roi ,_landmark=model(image,batch) 16 | 17 | with tf.name_scope('output'): 18 | _label=tf.squeeze(_label,name='label') 19 | _roi=tf.squeeze(_roi,name='roi') 20 | _landmark=tf.squeeze(_landmark,name='landmark') 21 | 22 | _label_los=label_los(_label,label) 23 | _box_los=roi_los(label,_roi,roi) 24 | _landmark_los=landmark_los(label,_landmark,landmark) 25 | 26 | function_loss=_label_los*ratio[0]+_box_los*ratio[1]+_landmark_los*ratio[2] 27 | 28 | tf.add_to_collection("loss", function_loss) 29 | loss_all=tf.get_collection('loss') 30 | 31 | with tf.name_scope('loss'): 32 | loss=tf.reduce_sum(loss_all) 33 | tf.summary.scalar('loss',loss) 34 | 35 | opt=tf.train.AdamOptimizer(learning_rate).minimize(loss) 36 | 37 | with tf.name_scope('accuracy'): 38 | train_accuracy=cal_accuracy(_label,label) 39 | tf.summary.scalar('accuracy',train_accuracy) 40 | 41 | saver=tf.train.Saver(max_to_keep=10) 42 | merged=tf.summary.merge_all() 43 | 44 | images,labels,rois,landmarks=read_multi_tfrecords(addr,batch_size,img_size) 45 | images=image_color_distort(images) 46 | 47 | with tf.Session() as sess: 48 | sess.run((tf.global_variables_initializer(), 49 | tf.local_variables_initializer())) 50 | coord = tf.train.Coordinator() 51 | threads = tf.train.start_queue_runners(sess=sess,coord=coord) 52 | image_batch,label_batch,roi_batch,landmark_batch=sess.run([images,labels,rois,landmarks]) 53 | 54 | writer_train=tf.summary.FileWriter('C:\\Users\\312\\Desktop\\',sess.graph) 55 | try: 56 | 57 | for i in range(1,train_step): 58 | 59 | image_batch,label_batch,roi_batch,landmark_batch=sess.run([images,labels,rois,landmarks]) 60 | 61 | sess.run(opt,feed_dict={image:image_batch,label:label_batch,roi:roi_batch,landmark:landmark_batch}) 62 | if(i%100==0): 63 | summary=sess.run(merged,feed_dict={image:image_batch,label:label_batch,roi:roi_batch,landmark:landmark_batch}) 64 | writer_train.add_summary(summary,i) 65 | if(i%1000==0): 66 | print('次数',i) 67 | print('train_accuracy',sess.run(train_accuracy,feed_dict={image:image_batch,label:label_batch,roi:roi_batch,landmark:landmark_batch})) 68 | print('loss',sess.run(loss,{image:image_batch,label:label_batch,roi:roi_batch,landmark:landmark_batch})) 69 | print('time',time.time()-begin) 70 | if(i%10000==0): 71 | saver.save(sess,"E:\\friedhelm\\object\\face_detection_MTCNN\\%s\\%s.ckpt"%(model_name,model_name),global_step=i) 72 | except tf.errors.OutOfRangeError: 73 | print("finished") 74 | finally: 75 | coord.request_stop() 76 | writer_train.close() 77 | coord.join(threads) 78 | 79 | def main(model): 80 | 81 | with tf.name_scope('input'): 82 | image=tf.placeholder(tf.float32,name='image') 83 | label=tf.placeholder(tf.int32,name='label') 84 | roi=tf.placeholder(tf.float32,name='roi') 85 | landmark = tf.placeholder(tf.float32,name='landmark') 86 | 87 | train(image,label,roi,landmark,model,model_name) 88 | 89 | if __name__=='__main__': 90 | 91 | img_size=24 92 | batch=448 93 | batch_size=[192,64,64,128] 94 | addr=["E:\\friedhelm\\object\\face_detection_MTCNN\\DATA\\%d\\neg_%d_train.tfrecords"%(img_size,img_size), 95 | "E:\\friedhelm\\object\\face_detection_MTCNN\\DATA\\%d\\pos_%d_train.tfrecords"%(img_size,img_size), 96 | "E:\\friedhelm\\object\\face_detection_MTCNN\\DATA\\%d\\par_%d_train.tfrecords"%(img_size,img_size), 97 | "E:\\friedhelm\\object\\face_detection_MTCNN\\DATA\\%d\\land_%d_train.tfrecords"%(img_size,img_size)] 98 | 99 | model=Rnet_model 100 | model_name="Rnet_model" 101 | train_step=100001 102 | learning_rate=0.001 103 | 104 | save_model_path="E:\\friedhelm\\object\\face_detection_MTCNN\\%s"%(model_name) 105 | 106 | if not os.path.exists(save_model_path): 107 | os.makedirs(save_model_path) 108 | 109 | if(model_name=="Onet_model"): 110 | ratio=[1,0.5,1] 111 | else: 112 | ratio=[1,0.5,0.5] 113 | 114 | 115 | begin=time.time() 116 | main(model) 117 | 118 | # tensorboard --logdir=C:\\Users\\312\\Desktop\\ -------------------------------------------------------------------------------- /version 1.0/MTCNN code/train/train_tool.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | @author: friedhelm 4 | 5 | """ 6 | import tensorflow as tf 7 | 8 | def label_los(pre_label,act_label): 9 | 10 | ratio=tf.constant(0.7) 11 | zeros=tf.zeros_like(act_label,dtype=tf.int32) 12 | valid_label=tf.where(tf.less(act_label,0),zeros,act_label) 13 | 14 | column_num=tf.shape(pre_label,out_type=tf.int32)[0] 15 | pre_label=tf.squeeze(tf.reshape(pre_label,(1,-1))) 16 | column=tf.range(0,column_num)*2 17 | column_to_stay=column+valid_label 18 | 19 | pre_label=tf.squeeze(tf.gather(pre_label,column_to_stay)) 20 | loss = -tf.log(pre_label+1e-10) 21 | ones=tf.ones_like(act_label,dtype=tf.float32) 22 | zero=tf.zeros_like(act_label,dtype=tf.float32) 23 | valid_colunm = tf.where(act_label < zeros,zero,ones) 24 | 25 | num_column=tf.reduce_sum(valid_colunm) 26 | num=tf.cast(num_column*ratio,dtype=tf.int32) 27 | loss=tf.multiply(loss,valid_colunm,'label_los') 28 | loss,_=tf.nn.top_k(loss,num) 29 | 30 | return tf.reduce_mean(loss) 31 | 32 | 33 | def roi_los(label,pre_box,act_box) : 34 | 35 | zeros=tf.zeros_like(label,dtype=tf.float32) 36 | ones=tf.ones_like(label,dtype=tf.float32) 37 | valid_label=tf.where(tf.equal(abs(label),1),ones,zeros) 38 | loss=tf.reduce_sum(tf.square(act_box-pre_box),axis=1) 39 | loss=tf.multiply(loss,valid_label,'roi_los') 40 | return tf.reduce_mean(loss) 41 | 42 | 43 | def landmark_los(label,pre_landmark,act_landmark): 44 | 45 | zeros=tf.zeros_like(label,dtype=tf.float32) 46 | ones = tf.ones_like(label,dtype=tf.float32) 47 | valid_label=tf.where(tf.equal(label,-2),ones,zeros) 48 | loss=tf.reduce_sum(tf.square(act_landmark-pre_landmark),axis=1) 49 | loss=tf.multiply(loss,valid_label,'landmark_los') 50 | return tf.reduce_mean(loss) 51 | 52 | 53 | def cal_accuracy(cls_prob,label): 54 | 55 | pred = tf.argmax(cls_prob,axis=1) 56 | label_int = tf.cast(label,tf.int64) 57 | cond = tf.where(tf.greater_equal(label_int,0)) 58 | picked = tf.squeeze(cond) 59 | label_picked = tf.gather(label_int,picked) 60 | pred_picked = tf.gather(pred,picked) 61 | accuracy_op = tf.reduce_mean(tf.cast(tf.equal(label_picked,pred_picked),tf.float32)) 62 | 63 | return accuracy_op -------------------------------------------------------------------------------- /version 1.0/model/Onet_model/Onet_model_100000.ckpt.data-00000-of-00001: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Onet_model/Onet_model_100000.ckpt.data-00000-of-00001 -------------------------------------------------------------------------------- /version 1.0/model/Onet_model/Onet_model_100000.ckpt.index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Onet_model/Onet_model_100000.ckpt.index -------------------------------------------------------------------------------- /version 1.0/model/Onet_model/Onet_model_100000.ckpt.meta: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Onet_model/Onet_model_100000.ckpt.meta -------------------------------------------------------------------------------- /version 1.0/model/Onet_model/Onet_model_60000.ckpt.data-00000-of-00001: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Onet_model/Onet_model_60000.ckpt.data-00000-of-00001 -------------------------------------------------------------------------------- /version 1.0/model/Onet_model/Onet_model_60000.ckpt.index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Onet_model/Onet_model_60000.ckpt.index -------------------------------------------------------------------------------- /version 1.0/model/Onet_model/Onet_model_60000.ckpt.meta: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Onet_model/Onet_model_60000.ckpt.meta -------------------------------------------------------------------------------- /version 1.0/model/Onet_model/Onet_model_70000.ckpt.data-00000-of-00001: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Onet_model/Onet_model_70000.ckpt.data-00000-of-00001 -------------------------------------------------------------------------------- /version 1.0/model/Onet_model/Onet_model_70000.ckpt.index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Onet_model/Onet_model_70000.ckpt.index -------------------------------------------------------------------------------- /version 1.0/model/Onet_model/Onet_model_70000.ckpt.meta: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Onet_model/Onet_model_70000.ckpt.meta -------------------------------------------------------------------------------- /version 1.0/model/Onet_model/Onet_model_80000.ckpt.data-00000-of-00001: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Onet_model/Onet_model_80000.ckpt.data-00000-of-00001 -------------------------------------------------------------------------------- /version 1.0/model/Onet_model/Onet_model_80000.ckpt.index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Onet_model/Onet_model_80000.ckpt.index -------------------------------------------------------------------------------- /version 1.0/model/Onet_model/Onet_model_80000.ckpt.meta: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Onet_model/Onet_model_80000.ckpt.meta -------------------------------------------------------------------------------- /version 1.0/model/Onet_model/Onet_model_90000.ckpt.data-00000-of-00001: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Onet_model/Onet_model_90000.ckpt.data-00000-of-00001 -------------------------------------------------------------------------------- /version 1.0/model/Onet_model/Onet_model_90000.ckpt.index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Onet_model/Onet_model_90000.ckpt.index -------------------------------------------------------------------------------- /version 1.0/model/Onet_model/Onet_model_90000.ckpt.meta: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Onet_model/Onet_model_90000.ckpt.meta -------------------------------------------------------------------------------- /version 1.0/model/Onet_model/checkpoint: -------------------------------------------------------------------------------- 1 | model_checkpoint_path: "E:\\friedhelm\\object\\face_detection_MTCNN\\Onet_model\\Onet_model_100000.ckpt" 2 | all_model_checkpoint_paths: "E:\\friedhelm\\object\\face_detection_MTCNN\\Onet_model\\Onet_model_60000.ckpt" 3 | all_model_checkpoint_paths: "E:\\friedhelm\\object\\face_detection_MTCNN\\Onet_model\\Onet_model_70000.ckpt" 4 | all_model_checkpoint_paths: "E:\\friedhelm\\object\\face_detection_MTCNN\\Onet_model\\Onet_model_80000.ckpt" 5 | all_model_checkpoint_paths: "E:\\friedhelm\\object\\face_detection_MTCNN\\Onet_model\\Onet_model_90000.ckpt" 6 | all_model_checkpoint_paths: "E:\\friedhelm\\object\\face_detection_MTCNN\\Onet_model\\Onet_model_100000.ckpt" 7 | -------------------------------------------------------------------------------- /version 1.0/model/Onet_model/events.out.tfevents.1551514455.DESKTOP-FFN3HIC: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Onet_model/events.out.tfevents.1551514455.DESKTOP-FFN3HIC -------------------------------------------------------------------------------- /version 1.0/model/Onet_model/训练曲线.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Onet_model/训练曲线.png -------------------------------------------------------------------------------- /version 1.0/model/Pnet_model/Pnet_model.ckpt-100000.data-00000-of-00001: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Pnet_model/Pnet_model.ckpt-100000.data-00000-of-00001 -------------------------------------------------------------------------------- /version 1.0/model/Pnet_model/Pnet_model.ckpt-100000.index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Pnet_model/Pnet_model.ckpt-100000.index -------------------------------------------------------------------------------- /version 1.0/model/Pnet_model/Pnet_model.ckpt-100000.meta: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Pnet_model/Pnet_model.ckpt-100000.meta -------------------------------------------------------------------------------- /version 1.0/model/Pnet_model/Pnet_model.ckpt-60000.data-00000-of-00001: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Pnet_model/Pnet_model.ckpt-60000.data-00000-of-00001 -------------------------------------------------------------------------------- /version 1.0/model/Pnet_model/Pnet_model.ckpt-60000.index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Pnet_model/Pnet_model.ckpt-60000.index -------------------------------------------------------------------------------- /version 1.0/model/Pnet_model/Pnet_model.ckpt-60000.meta: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Pnet_model/Pnet_model.ckpt-60000.meta -------------------------------------------------------------------------------- /version 1.0/model/Pnet_model/Pnet_model.ckpt-70000.data-00000-of-00001: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Pnet_model/Pnet_model.ckpt-70000.data-00000-of-00001 -------------------------------------------------------------------------------- /version 1.0/model/Pnet_model/Pnet_model.ckpt-70000.index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Pnet_model/Pnet_model.ckpt-70000.index -------------------------------------------------------------------------------- /version 1.0/model/Pnet_model/Pnet_model.ckpt-70000.meta: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Pnet_model/Pnet_model.ckpt-70000.meta -------------------------------------------------------------------------------- /version 1.0/model/Pnet_model/Pnet_model.ckpt-80000.data-00000-of-00001: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Pnet_model/Pnet_model.ckpt-80000.data-00000-of-00001 -------------------------------------------------------------------------------- /version 1.0/model/Pnet_model/Pnet_model.ckpt-80000.index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Pnet_model/Pnet_model.ckpt-80000.index -------------------------------------------------------------------------------- /version 1.0/model/Pnet_model/Pnet_model.ckpt-80000.meta: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Pnet_model/Pnet_model.ckpt-80000.meta -------------------------------------------------------------------------------- /version 1.0/model/Pnet_model/Pnet_model.ckpt-90000.data-00000-of-00001: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Pnet_model/Pnet_model.ckpt-90000.data-00000-of-00001 -------------------------------------------------------------------------------- /version 1.0/model/Pnet_model/Pnet_model.ckpt-90000.index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Pnet_model/Pnet_model.ckpt-90000.index -------------------------------------------------------------------------------- /version 1.0/model/Pnet_model/Pnet_model.ckpt-90000.meta: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Pnet_model/Pnet_model.ckpt-90000.meta -------------------------------------------------------------------------------- /version 1.0/model/Pnet_model/checkpoint: -------------------------------------------------------------------------------- 1 | model_checkpoint_path: "E:\\friedhelm\\object\\face_detection_MTCNN\\model\\Pnet_model.ckpt-100000" 2 | all_model_checkpoint_paths: "E:\\friedhelm\\object\\face_detection_MTCNN\\model\\Pnet_model.ckpt-60000" 3 | all_model_checkpoint_paths: "E:\\friedhelm\\object\\face_detection_MTCNN\\model\\Pnet_model.ckpt-70000" 4 | all_model_checkpoint_paths: "E:\\friedhelm\\object\\face_detection_MTCNN\\model\\Pnet_model.ckpt-80000" 5 | all_model_checkpoint_paths: "E:\\friedhelm\\object\\face_detection_MTCNN\\model\\Pnet_model.ckpt-90000" 6 | all_model_checkpoint_paths: "E:\\friedhelm\\object\\face_detection_MTCNN\\model\\Pnet_model.ckpt-100000" 7 | -------------------------------------------------------------------------------- /version 1.0/model/Pnet_model/events.out.tfevents.1551238146.DESKTOP-FFN3HIC: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Pnet_model/events.out.tfevents.1551238146.DESKTOP-FFN3HIC -------------------------------------------------------------------------------- /version 1.0/model/Pnet_model/训练曲线.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Pnet_model/训练曲线.png -------------------------------------------------------------------------------- /version 1.0/model/Rnet_model/Rnet_model.ckpt-10000.data-00000-of-00001: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Rnet_model/Rnet_model.ckpt-10000.data-00000-of-00001 -------------------------------------------------------------------------------- /version 1.0/model/Rnet_model/Rnet_model.ckpt-10000.index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Rnet_model/Rnet_model.ckpt-10000.index -------------------------------------------------------------------------------- /version 1.0/model/Rnet_model/Rnet_model.ckpt-10000.meta: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Rnet_model/Rnet_model.ckpt-10000.meta -------------------------------------------------------------------------------- /version 1.0/model/Rnet_model/Rnet_model.ckpt-100000.data-00000-of-00001: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Rnet_model/Rnet_model.ckpt-100000.data-00000-of-00001 -------------------------------------------------------------------------------- /version 1.0/model/Rnet_model/Rnet_model.ckpt-100000.index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Rnet_model/Rnet_model.ckpt-100000.index -------------------------------------------------------------------------------- /version 1.0/model/Rnet_model/Rnet_model.ckpt-100000.meta: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Rnet_model/Rnet_model.ckpt-100000.meta -------------------------------------------------------------------------------- /version 1.0/model/Rnet_model/Rnet_model.ckpt-20000.data-00000-of-00001: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Rnet_model/Rnet_model.ckpt-20000.data-00000-of-00001 -------------------------------------------------------------------------------- /version 1.0/model/Rnet_model/Rnet_model.ckpt-20000.index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Rnet_model/Rnet_model.ckpt-20000.index -------------------------------------------------------------------------------- /version 1.0/model/Rnet_model/Rnet_model.ckpt-20000.meta: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Rnet_model/Rnet_model.ckpt-20000.meta -------------------------------------------------------------------------------- /version 1.0/model/Rnet_model/Rnet_model.ckpt-30000.data-00000-of-00001: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Rnet_model/Rnet_model.ckpt-30000.data-00000-of-00001 -------------------------------------------------------------------------------- /version 1.0/model/Rnet_model/Rnet_model.ckpt-30000.index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Rnet_model/Rnet_model.ckpt-30000.index -------------------------------------------------------------------------------- /version 1.0/model/Rnet_model/Rnet_model.ckpt-30000.meta: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Rnet_model/Rnet_model.ckpt-30000.meta -------------------------------------------------------------------------------- /version 1.0/model/Rnet_model/Rnet_model.ckpt-40000.data-00000-of-00001: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Rnet_model/Rnet_model.ckpt-40000.data-00000-of-00001 -------------------------------------------------------------------------------- /version 1.0/model/Rnet_model/Rnet_model.ckpt-40000.index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Rnet_model/Rnet_model.ckpt-40000.index -------------------------------------------------------------------------------- /version 1.0/model/Rnet_model/Rnet_model.ckpt-40000.meta: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Rnet_model/Rnet_model.ckpt-40000.meta -------------------------------------------------------------------------------- /version 1.0/model/Rnet_model/Rnet_model.ckpt-50000.data-00000-of-00001: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Rnet_model/Rnet_model.ckpt-50000.data-00000-of-00001 -------------------------------------------------------------------------------- /version 1.0/model/Rnet_model/Rnet_model.ckpt-50000.index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Rnet_model/Rnet_model.ckpt-50000.index -------------------------------------------------------------------------------- /version 1.0/model/Rnet_model/Rnet_model.ckpt-50000.meta: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Rnet_model/Rnet_model.ckpt-50000.meta -------------------------------------------------------------------------------- /version 1.0/model/Rnet_model/Rnet_model.ckpt-60000.data-00000-of-00001: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Rnet_model/Rnet_model.ckpt-60000.data-00000-of-00001 -------------------------------------------------------------------------------- /version 1.0/model/Rnet_model/Rnet_model.ckpt-60000.index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Rnet_model/Rnet_model.ckpt-60000.index -------------------------------------------------------------------------------- /version 1.0/model/Rnet_model/Rnet_model.ckpt-60000.meta: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Rnet_model/Rnet_model.ckpt-60000.meta -------------------------------------------------------------------------------- /version 1.0/model/Rnet_model/Rnet_model.ckpt-70000.data-00000-of-00001: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Rnet_model/Rnet_model.ckpt-70000.data-00000-of-00001 -------------------------------------------------------------------------------- /version 1.0/model/Rnet_model/Rnet_model.ckpt-70000.index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Rnet_model/Rnet_model.ckpt-70000.index -------------------------------------------------------------------------------- /version 1.0/model/Rnet_model/Rnet_model.ckpt-70000.meta: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Rnet_model/Rnet_model.ckpt-70000.meta -------------------------------------------------------------------------------- /version 1.0/model/Rnet_model/Rnet_model.ckpt-80000.data-00000-of-00001: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Rnet_model/Rnet_model.ckpt-80000.data-00000-of-00001 -------------------------------------------------------------------------------- /version 1.0/model/Rnet_model/Rnet_model.ckpt-80000.index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Rnet_model/Rnet_model.ckpt-80000.index -------------------------------------------------------------------------------- /version 1.0/model/Rnet_model/Rnet_model.ckpt-80000.meta: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Rnet_model/Rnet_model.ckpt-80000.meta -------------------------------------------------------------------------------- /version 1.0/model/Rnet_model/Rnet_model.ckpt-90000.data-00000-of-00001: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Rnet_model/Rnet_model.ckpt-90000.data-00000-of-00001 -------------------------------------------------------------------------------- /version 1.0/model/Rnet_model/Rnet_model.ckpt-90000.index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Rnet_model/Rnet_model.ckpt-90000.index -------------------------------------------------------------------------------- /version 1.0/model/Rnet_model/Rnet_model.ckpt-90000.meta: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Rnet_model/Rnet_model.ckpt-90000.meta -------------------------------------------------------------------------------- /version 1.0/model/Rnet_model/checkpoint: -------------------------------------------------------------------------------- 1 | model_checkpoint_path: "E:\\friedhelm\\object\\face_detection_MTCNN\\Rnet_model\\Rnet_model.ckpt-100000" 2 | all_model_checkpoint_paths: "E:\\friedhelm\\object\\face_detection_MTCNN\\Rnet_model\\Rnet_model.ckpt-10000" 3 | all_model_checkpoint_paths: "E:\\friedhelm\\object\\face_detection_MTCNN\\Rnet_model\\Rnet_model.ckpt-20000" 4 | all_model_checkpoint_paths: "E:\\friedhelm\\object\\face_detection_MTCNN\\Rnet_model\\Rnet_model.ckpt-30000" 5 | all_model_checkpoint_paths: "E:\\friedhelm\\object\\face_detection_MTCNN\\Rnet_model\\Rnet_model.ckpt-40000" 6 | all_model_checkpoint_paths: "E:\\friedhelm\\object\\face_detection_MTCNN\\Rnet_model\\Rnet_model.ckpt-50000" 7 | all_model_checkpoint_paths: "E:\\friedhelm\\object\\face_detection_MTCNN\\Rnet_model\\Rnet_model.ckpt-60000" 8 | all_model_checkpoint_paths: "E:\\friedhelm\\object\\face_detection_MTCNN\\Rnet_model\\Rnet_model.ckpt-70000" 9 | all_model_checkpoint_paths: "E:\\friedhelm\\object\\face_detection_MTCNN\\Rnet_model\\Rnet_model.ckpt-80000" 10 | all_model_checkpoint_paths: "E:\\friedhelm\\object\\face_detection_MTCNN\\Rnet_model\\Rnet_model.ckpt-90000" 11 | all_model_checkpoint_paths: "E:\\friedhelm\\object\\face_detection_MTCNN\\Rnet_model\\Rnet_model.ckpt-100000" 12 | -------------------------------------------------------------------------------- /version 1.0/model/Rnet_model/events.out.tfevents.1551356909.DESKTOP-FFN3HIC: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Rnet_model/events.out.tfevents.1551356909.DESKTOP-FFN3HIC -------------------------------------------------------------------------------- /version 1.0/model/Rnet_model/训练曲线.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/model/Rnet_model/训练曲线.png -------------------------------------------------------------------------------- /version 1.0/result/MTCNN_test_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/result/MTCNN_test_1.jpg -------------------------------------------------------------------------------- /version 1.0/result/MTCNN_test_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/result/MTCNN_test_2.jpg -------------------------------------------------------------------------------- /version 1.0/result/MTCNN_test_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/result/MTCNN_test_3.jpg -------------------------------------------------------------------------------- /version 1.0/result/MTCNN_test_4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/result/MTCNN_test_4.jpg -------------------------------------------------------------------------------- /version 1.0/result/MTCNN_test_5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/result/MTCNN_test_5.jpg -------------------------------------------------------------------------------- /version 1.0/result/MTCNN_test_6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 1.0/result/MTCNN_test_6.jpg -------------------------------------------------------------------------------- /version 2.0/MTCNN code/.ipynb_checkpoints/detect face-checkpoint.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 13, 6 | "metadata": {}, 7 | "outputs": [ 8 | { 9 | "name": "stdout", 10 | "output_type": "stream", 11 | "text": [ 12 | "INFO:tensorflow:Restoring parameters from /home/dell/Desktop/prepared_data/model/Pnet_model/Pnet_model.ckpt-20000\n", 13 | "INFO:tensorflow:Restoring parameters from /home/dell/Desktop/prepared_data/model/Rnet_model/Rnet_model.ckpt-40000\n", 14 | "INFO:tensorflow:Restoring parameters from /home/dell/Desktop/prepared_data/model/Onet_model/Onet_model.ckpt-40000\n", 15 | "detect-time: 1.2219476699829102\n" 16 | ] 17 | } 18 | ], 19 | "source": [ 20 | "from detection.mtcnn_detector import MTCNN_Detector\n", 21 | "from core.MTCNN_model import Pnet_model,Rnet_model,Onet_model\n", 22 | "import cv2\n", 23 | "import matplotlib.pyplot as plt\n", 24 | "import numpy as np\n", 25 | "import os\n", 26 | "\n", 27 | "os.environ[\"TF_CPP_MIN_LOG_LEVEL\"] = \"2\"\n", 28 | "\n", 29 | "def main():\n", 30 | " \n", 31 | " if(model_name in [\"Pnet\",\"Rnet\",\"Onet\"]):\n", 32 | " model[0]=Pnet_model\n", 33 | " if(model_name in [\"Rnet\",\"Onet\"]):\n", 34 | " model[1]=Rnet_model\n", 35 | " if(model_name==\"Onet\"):\n", 36 | " model[2]=Onet_model\n", 37 | " \n", 38 | " detector=MTCNN_Detector(model,model_path,batch_size,factor,min_face_size,threshold)\n", 39 | " img=cv2.imread(\"/home/dell/Desktop/2.jpg\") \n", 40 | " blue = (255, 0, 0) \n", 41 | " \n", 42 | "# face_box,_=detector.detect_single_face(img)\n", 43 | "# for a in face_box: \n", 44 | "# cv2.rectangle(img,(int(a[0]),int(a[1])), (int(a[2]), int(a[3])),blue,3,8,0)\n", 45 | "\n", 46 | " face_box,landmarks_box=detector.detect_single_face(img)\n", 47 | " for idx,a in enumerate(face_box):\n", 48 | " for i in range(5):\n", 49 | " cv2.circle(img,(int(landmarks_box[idx][i][0]),int(landmarks_box[idx][i][1])),2,(0,255,0))\n", 50 | " cv2.rectangle(img,(int(a[0]),int(a[1])), (int(a[2]), int(a[3])),blue,3,8,0) \n", 51 | "\n", 52 | "# cv2.imwrite(\"/home/dell/Desktop/MTCNN_test_2.jpg\",img)\n", 53 | "# cv2.imshow(\"MTCNN_test_1\",img)\n", 54 | "# cv2.waitKey(0xff)\n", 55 | "# cv2.destroyAllWindows()\n", 56 | " plt.imshow(img) \n", 57 | " plt.show() \n", 58 | " \n", 59 | " \n", 60 | "if __name__==\"__main__\":\n", 61 | " \n", 62 | " factor=0.79\n", 63 | " \n", 64 | " model=[None,None,None]\n", 65 | " #原文参数\n", 66 | " threshold=[0.8,0.8,0.6]\n", 67 | " min_face_size=10\n", 68 | " #原文参数\n", 69 | " batch_size=1\n", 70 | " model_name=\"Onet\" \n", 71 | " base_dir=\"/home/dell/Desktop/prepared_data\"\n", 72 | " \n", 73 | " model_path=[os.path.join(base_dir,\"model/Pnet_model/Pnet_model.ckpt-20000\"),\n", 74 | " os.path.join(base_dir,\"model/Rnet_model/Rnet_model.ckpt-40000\"),\n", 75 | " os.path.join(base_dir,\"model/Onet_model/Onet_model.ckpt-40000\")] \n", 76 | " \n", 77 | "\n", 78 | " main()\n", 79 | " " 80 | ] 81 | } 82 | ], 83 | "metadata": { 84 | "kernelspec": { 85 | "display_name": "Python 3", 86 | "language": "python", 87 | "name": "python3" 88 | }, 89 | "language_info": { 90 | "codemirror_mode": { 91 | "name": "ipython", 92 | "version": 3 93 | }, 94 | "file_extension": ".py", 95 | "mimetype": "text/x-python", 96 | "name": "python", 97 | "nbconvert_exporter": "python", 98 | "pygments_lexer": "ipython3", 99 | "version": "3.6.5" 100 | } 101 | }, 102 | "nbformat": 4, 103 | "nbformat_minor": 2 104 | } 105 | -------------------------------------------------------------------------------- /version 2.0/MTCNN code/core/MTCNN_model.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | @author: friedhelm 4 | 5 | """ 6 | import tensorflow as tf 7 | 8 | def prelu(inputs): 9 | 10 | with tf.variable_scope('prelu'): 11 | alphas = tf.get_variable("alphas", shape=inputs.get_shape()[-1], dtype=tf.float32, initializer=tf.constant_initializer(0.25)) 12 | pos = tf.nn.relu(inputs) 13 | neg = alphas * (inputs-abs(inputs))*0.5 14 | 15 | return pos + neg 16 | 17 | 18 | def conv2d(_input,name,conv_size,conv_stride,bias_size,pad,activation='prelu'): 19 | 20 | regularizer=tf.contrib.layers.l2_regularizer(0.0005) 21 | with tf.variable_scope(name): 22 | weight=tf.get_variable('weight',conv_size,initializer=tf.truncated_normal_initializer(stddev=0.1)) 23 | bias=tf.get_variable('bias',bias_size,initializer=tf.constant_initializer(0.0)) 24 | weight_loss=regularizer(weight) 25 | tf.add_to_collection('loss',weight_loss) 26 | conv=tf.nn.conv2d(_input,weight,strides=conv_stride,padding=pad) 27 | he=tf.nn.bias_add(conv,bias) 28 | relu=tf.cond(tf.equal(activation,'prelu'),lambda:prelu(he),lambda:tf.cond(tf.equal(activation,'softmax'),lambda:tf.nn.softmax(he),lambda:he),name='output') 29 | 30 | return relu 31 | 32 | 33 | def fc2d(_input,name,fc_size,bias_size,activation='prelu'): 34 | 35 | regularizer=tf.contrib.layers.l2_regularizer(0.0005) 36 | with tf.variable_scope(name): 37 | weight=tf.get_variable('weight',fc_size,initializer=tf.truncated_normal_initializer(stddev=0.1)) 38 | bias=tf.get_variable('bias',bias_size,initializer=tf.constant_initializer(0.0)) 39 | weight_loss=regularizer(weight) 40 | tf.add_to_collection('loss',weight_loss) 41 | he=tf.nn.bias_add(tf.matmul(_input,weight,name='matmul'),bias) 42 | relu=tf.cond(tf.equal(activation,'prelu'),lambda:prelu(he),lambda:tf.cond(tf.equal(activation,'softmax'),lambda:tf.nn.softmax(he),lambda:he)) 43 | 44 | return relu 45 | 46 | 47 | def pool(_input,name,kernal_size,kernal_stride,pad): 48 | 49 | with tf.variable_scope(name): 50 | pool=tf.nn.max_pool(_input,ksize=kernal_size,strides=kernal_stride,padding=pad) 51 | 52 | return pool 53 | 54 | 55 | def Pnet_model(x,batch_size): 56 | 57 | conv_1=conv2d(x,'conv_1',[3,3,3,10],[1,1,1,1],[10],'VALID') 58 | pool_1=pool(conv_1,'pool_1',[1,3,3,1],[1,2,2,1],'SAME') 59 | conv_2=conv2d(pool_1,'conv_2',[3,3,10,16],[1,1,1,1],[16],'VALID') 60 | conv_3=conv2d(conv_2,'conv_3',[3,3,16,32],[1,1,1,1],[32],'VALID') 61 | 62 | face_label=conv2d(conv_3,'face_label',[1,1,32,2],[1,1,1,1],[2],'VALID','softmax') 63 | bounding_box=conv2d(conv_3,'bounding_box',[1,1,32,4],[1,1,1,1],[4],'VALID','None') 64 | landmark_local=conv2d(conv_3,'landmark_local',[1,1,32,10],[1,1,1,1],[10],'VALID','None') 65 | 66 | return face_label, bounding_box ,landmark_local 67 | 68 | 69 | def Rnet_model(x,batch_size): 70 | 71 | conv_1=conv2d(x,'conv_1',[3,3,3,28],[1,1,1,1],[28],'VALID') 72 | pool_1=pool(conv_1,'pool_1',[1,3,3,1],[1,2,2,1],'SAME') 73 | conv_2=conv2d(pool_1,'conv_2',[3,3,28,48],[1,1,1,1],[48],'VALID') 74 | pool_2=pool(conv_2,'pool_2',[1,3,3,1],[1,2,2,1],'VALID') 75 | conv_3=conv2d(pool_2,'conv_3',[2,2,48,64],[1,1,1,1],[64],'VALID') 76 | 77 | resh1 = tf.reshape(conv_3, [batch_size,3*3*64], name='resh1') 78 | 79 | fc_1=fc2d(resh1,'fc_1',[3*3*64,128],[128]) 80 | 81 | face_label=fc2d(fc_1,'face_label',[128,2],[2],'softmax') 82 | bounding_box=fc2d(fc_1,'bounding_box',[128,4],[4],'None') 83 | landmark_local=fc2d(fc_1,'landmark_local',[128,10],[10],'None') 84 | 85 | return face_label, bounding_box ,landmark_local 86 | 87 | 88 | def Onet_model(x,batch_size): 89 | 90 | conv_1=conv2d(x,'conv_1',[3,3,3,32],[1,1,1,1],[32],'VALID') 91 | pool_1=pool(conv_1,'pool_1',[1,3,3,1],[1,2,2,1],'SAME') 92 | conv_2=conv2d(pool_1,'conv_2',[3,3,32,64],[1,1,1,1],[64],'VALID') 93 | pool_2=pool(conv_2,'pool_2',[1,3,3,1],[1,2,2,1],'VALID') 94 | conv_3=conv2d(pool_2,'conv_3',[3,3,64,64],[1,1,1,1],[64],'VALID') 95 | pool_3=pool(conv_3,'pool_3',[1,2,2,1],[1,2,2,1],'SAME') 96 | conv_4=conv2d(pool_3,'conv_4',[2,2,64,128],[1,1,1,1],[128],'VALID') 97 | 98 | resh1 = tf.reshape(conv_4, [batch_size,3*3*128], name='resh1') 99 | 100 | fc_1=fc2d(resh1,'fc_1',[3*3*128,256],[256]) 101 | 102 | face_label=fc2d(fc_1,'face_label',[256,2],[2],'softmax') 103 | bounding_box=fc2d(fc_1,'bounding_box',[256,4],[4],'None') 104 | landmark_local=fc2d(fc_1,'landmark_local',[256,10],[10],'None') 105 | 106 | return face_label, bounding_box ,landmark_local -------------------------------------------------------------------------------- /version 2.0/MTCNN code/core/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 2.0/MTCNN code/core/__init__.py -------------------------------------------------------------------------------- /version 2.0/MTCNN code/core/__pycache__/MTCNN_model.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 2.0/MTCNN code/core/__pycache__/MTCNN_model.cpython-36.pyc -------------------------------------------------------------------------------- /version 2.0/MTCNN code/core/__pycache__/tool.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 2.0/MTCNN code/core/__pycache__/tool.cpython-36.pyc -------------------------------------------------------------------------------- /version 2.0/MTCNN code/core/tool.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | @author: friedhelm 4 | 5 | """ 6 | import numpy as np 7 | import cv2 8 | import tensorflow as tf 9 | 10 | def IoU(box, boxes): 11 | """ 12 | Compute IoU between detect box and face boxes 13 | 14 | Parameters: 15 | ---------- 16 | box: numpy array , shape (4, ): x1, y1, x2, y2 17 | random produced box 18 | boxes: numpy array, shape (n, 4): x1, y1, w, h 19 | input ground truth face boxes 20 | 21 | Returns: 22 | ------- 23 | ovr: numpy.array, shape (n, ) 24 | IoU 25 | """ 26 | 27 | box_area = (box[2] - box[0] + 1) * (box[3] - box[1] + 1) 28 | area = boxes[:, 2]*boxes[:, 3] 29 | 30 | x_right=boxes[:, 2]+boxes[:, 0] 31 | y_bottom=boxes[:, 3]+boxes[:, 1] 32 | 33 | xx1 = np.maximum(box[0], boxes[:, 0]) 34 | yy1 = np.maximum(box[1], boxes[:, 1]) 35 | xx2 = np.minimum(box[2], x_right) 36 | yy2 = np.minimum(box[3], y_bottom) 37 | 38 | # compute the width and height of the bounding box 39 | w = np.maximum(0, xx2 - xx1 + 1) 40 | h = np.maximum(0, yy2 - yy1 + 1) 41 | 42 | inter = w * h 43 | ovr = inter / (box_area + area - inter) 44 | return ovr 45 | 46 | 47 | def NMS(box,_overlap,mode="default"): 48 | 49 | if len(box) == 0: 50 | return [] 51 | 52 | pick = [] 53 | x_min = box[:,0] 54 | y_min = box[:,1] 55 | x_max = box[:,2] 56 | y_max = box[:,3] 57 | score = box[:,4] 58 | 59 | area = (x_max-x_min)*(y_max-y_min) 60 | idxs = score.argsort()[::-1] 61 | 62 | while len(idxs) > 0: 63 | i = idxs[0] 64 | pick.append(i) 65 | 66 | xx1 = np.maximum(x_min[i],x_min[idxs[1:]]) 67 | yy1 = np.maximum(y_min[i],y_min[idxs[1:]]) 68 | xx2 = np.minimum(x_max[i],x_max[idxs[1:]]) 69 | yy2 = np.minimum(y_max[i],y_max[idxs[1:]]) 70 | 71 | w = np.maximum(xx2-xx1,0) 72 | h = np.maximum(yy2-yy1,0) 73 | 74 | square=w*h 75 | 76 | if(mode != "Minimum"): 77 | overlap = square / (area[idxs[1:]] + area[i] - square) 78 | else: 79 | overlap = square / np.minimum(area[idxs[1:]] , area[i]) 80 | 81 | idxs = idxs[np.where(overlap < _overlap)[0]+1] 82 | 83 | return pick 84 | 85 | 86 | def flip(img,facemark): 87 | img=cv2.flip(img,1) 88 | facemark=np.asarray([(1-x,y) for (x,y) in facemark]) 89 | facemark[[0,1]]=facemark[[1,0]] 90 | facemark[[3,4]]=facemark[[4,3]] 91 | return (img,facemark) 92 | 93 | 94 | def read_single_tfrecord(addr,_batch_size,shape): 95 | 96 | filename_queue = tf.train.string_input_producer([addr],shuffle=True) 97 | 98 | reader = tf.TFRecordReader() 99 | _, serialized_example = reader.read(filename_queue) 100 | 101 | features = tf.parse_single_example(serialized_example, 102 | features={ 103 | 'img':tf.FixedLenFeature([],tf.string), 104 | 'label':tf.FixedLenFeature([],tf.int64), 105 | 'roi':tf.FixedLenFeature([4],tf.float32), 106 | 'landmark':tf.FixedLenFeature([10],tf.float32), 107 | }) 108 | img=tf.decode_raw(features['img'],tf.uint8) 109 | label=tf.cast(features['label'],tf.int32) 110 | roi=tf.cast(features['roi'],tf.float32) 111 | landmark=tf.cast(features['landmark'],tf.float32) 112 | img = tf.reshape(img, [shape,shape,3]) 113 | img=(tf.cast(img,tf.float32)-127.5)/128 114 | min_after_dequeue = 10000 115 | batch_size = _batch_size 116 | capacity = min_after_dequeue + 10 * batch_size 117 | image_batch, label_batch, roi_batch, landmark_batch = tf.train.shuffle_batch([img,label,roi,landmark], 118 | batch_size=batch_size, 119 | capacity=capacity, 120 | min_after_dequeue=min_after_dequeue, 121 | num_threads=7) 122 | 123 | label_batch = tf.reshape(label_batch, [batch_size]) 124 | roi_batch = tf.reshape(roi_batch,[batch_size,4]) 125 | landmark_batch = tf.reshape(landmark_batch,[batch_size,10]) 126 | 127 | return image_batch, label_batch, roi_batch, landmark_batch 128 | 129 | 130 | def read_multi_tfrecords(addr,_batch_size,shape): 131 | 132 | pos_dir,part_dir,neg_dir,landmark_dir = addr 133 | pos_batch_size,part_batch_size,neg_batch_size,landmark_batch_size = _batch_size 134 | 135 | pos_image,pos_label,pos_roi,pos_landmark = read_single_tfrecord(pos_dir, pos_batch_size, shape) 136 | part_image,part_label,part_roi,part_landmark = read_single_tfrecord(part_dir, part_batch_size, shape) 137 | neg_image,neg_label,neg_roi,neg_landmark = read_single_tfrecord(neg_dir, neg_batch_size, shape) 138 | landmark_image,landmark_label,landmark_roi,landmark_landmark = read_single_tfrecord(landmark_dir, landmark_batch_size, shape) 139 | 140 | images = tf.concat([pos_image,part_image,neg_image,landmark_image], 0, name="concat/image") 141 | labels = tf.concat([pos_label,part_label,neg_label,landmark_label],0,name="concat/label") 142 | rois = tf.concat([pos_roi,part_roi,neg_roi,landmark_roi],0,name="concat/roi") 143 | landmarks = tf.concat([pos_landmark,part_landmark,neg_landmark,landmark_landmark],0,name="concat/landmark") 144 | 145 | return images,labels,rois,landmarks 146 | 147 | 148 | def image_color_distort(inputs): 149 | inputs = tf.image.random_contrast(inputs, lower=0.5, upper=1.5) 150 | inputs = tf.image.random_brightness(inputs, max_delta=0.2) 151 | inputs = tf.image.random_hue(inputs,max_delta= 0.2) 152 | inputs = tf.image.random_saturation(inputs,lower = 0.5, upper= 1.5) 153 | 154 | return inputs 155 | -------------------------------------------------------------------------------- /version 2.0/MTCNN code/detect face.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 13, 6 | "metadata": {}, 7 | "outputs": [ 8 | { 9 | "name": "stdout", 10 | "output_type": "stream", 11 | "text": [ 12 | "INFO:tensorflow:Restoring parameters from /home/dell/Desktop/prepared_data/model/Pnet_model/Pnet_model.ckpt-20000\n", 13 | "INFO:tensorflow:Restoring parameters from /home/dell/Desktop/prepared_data/model/Rnet_model/Rnet_model.ckpt-40000\n", 14 | "INFO:tensorflow:Restoring parameters from /home/dell/Desktop/prepared_data/model/Onet_model/Onet_model.ckpt-40000\n", 15 | "detect-time: 1.2219476699829102\n" 16 | ] 17 | } 18 | ], 19 | "source": [ 20 | "from detection.mtcnn_detector import MTCNN_Detector\n", 21 | "from core.MTCNN_model import Pnet_model,Rnet_model,Onet_model\n", 22 | "import cv2\n", 23 | "import matplotlib.pyplot as plt\n", 24 | "import numpy as np\n", 25 | "import os\n", 26 | "\n", 27 | "os.environ[\"TF_CPP_MIN_LOG_LEVEL\"] = \"2\"\n", 28 | "\n", 29 | "def main():\n", 30 | " \n", 31 | " if(model_name in [\"Pnet\",\"Rnet\",\"Onet\"]):\n", 32 | " model[0]=Pnet_model\n", 33 | " if(model_name in [\"Rnet\",\"Onet\"]):\n", 34 | " model[1]=Rnet_model\n", 35 | " if(model_name==\"Onet\"):\n", 36 | " model[2]=Onet_model\n", 37 | " \n", 38 | " detector=MTCNN_Detector(model,model_path,batch_size,factor,min_face_size,threshold)\n", 39 | " img=cv2.imread(\"/home/dell/Desktop/2.jpg\") \n", 40 | " blue = (255, 0, 0) \n", 41 | " \n", 42 | "# face_box,_=detector.detect_single_face(img)\n", 43 | "# for a in face_box: \n", 44 | "# cv2.rectangle(img,(int(a[0]),int(a[1])), (int(a[2]), int(a[3])),blue,3,8,0)\n", 45 | "\n", 46 | " face_box,landmarks_box=detector.detect_single_face(img)\n", 47 | " for idx,a in enumerate(face_box):\n", 48 | " for i in range(5):\n", 49 | " cv2.circle(img,(int(landmarks_box[idx][i][0]),int(landmarks_box[idx][i][1])),2,(0,255,0))\n", 50 | " cv2.rectangle(img,(int(a[0]),int(a[1])), (int(a[2]), int(a[3])),blue,3,8,0) \n", 51 | "\n", 52 | "# cv2.imwrite(\"/home/dell/Desktop/MTCNN_test_2.jpg\",img)\n", 53 | "# cv2.imshow(\"MTCNN_test_1\",img)\n", 54 | "# cv2.waitKey(0xff)\n", 55 | "# cv2.destroyAllWindows()\n", 56 | " plt.imshow(img) \n", 57 | " plt.show() \n", 58 | " \n", 59 | " \n", 60 | "if __name__==\"__main__\":\n", 61 | " \n", 62 | " factor=0.79\n", 63 | " \n", 64 | " model=[None,None,None]\n", 65 | " #原文参数\n", 66 | " threshold=[0.8,0.8,0.6]\n", 67 | " min_face_size=10\n", 68 | " #原文参数\n", 69 | " batch_size=1\n", 70 | " model_name=\"Onet\" \n", 71 | " base_dir=\"/home/dell/Desktop/prepared_data\"\n", 72 | " \n", 73 | " model_path=[os.path.join(base_dir,\"model/Pnet_model/Pnet_model.ckpt-20000\"),\n", 74 | " os.path.join(base_dir,\"model/Rnet_model/Rnet_model.ckpt-40000\"),\n", 75 | " os.path.join(base_dir,\"model/Onet_model/Onet_model.ckpt-40000\")] \n", 76 | " \n", 77 | "\n", 78 | " main()\n", 79 | " " 80 | ] 81 | } 82 | ], 83 | "metadata": { 84 | "kernelspec": { 85 | "display_name": "Python 3", 86 | "language": "python", 87 | "name": "python3" 88 | }, 89 | "language_info": { 90 | "codemirror_mode": { 91 | "name": "ipython", 92 | "version": 3 93 | }, 94 | "file_extension": ".py", 95 | "mimetype": "text/x-python", 96 | "name": "python", 97 | "nbconvert_exporter": "python", 98 | "pygments_lexer": "ipython3", 99 | "version": "3.6.5" 100 | } 101 | }, 102 | "nbformat": 4, 103 | "nbformat_minor": 2 104 | } 105 | -------------------------------------------------------------------------------- /version 2.0/MTCNN code/detection/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 2.0/MTCNN code/detection/__init__.py -------------------------------------------------------------------------------- /version 2.0/MTCNN code/detection/__pycache__/detector.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 2.0/MTCNN code/detection/__pycache__/detector.cpython-36.pyc -------------------------------------------------------------------------------- /version 2.0/MTCNN code/detection/__pycache__/mtcnn_detector.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 2.0/MTCNN code/detection/__pycache__/mtcnn_detector.cpython-36.pyc -------------------------------------------------------------------------------- /version 2.0/MTCNN code/detection/detector.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | @author: friedhelm 4 | 5 | """ 6 | import tensorflow as tf 7 | import numpy as np 8 | import os 9 | 10 | class Detector(object): 11 | 12 | def __init__(self, model, model_path, model_name, batch_size, size_to_predict=128): 13 | 14 | if(model_path): 15 | self.model_name = model_name 16 | path = model_path.replace("/","\\") 17 | model_name = path.split("\\")[-1].split(".")[0] 18 | 19 | if not os.path.exists(model_path+".meta"): 20 | raise Exception("%s is not exists"%(model_name)) 21 | 22 | if(self.model_name == "Pnet"): 23 | self.size_to_predict = batch_size 24 | 25 | graph = tf.Graph() 26 | with graph.as_default(): 27 | config = tf.ConfigProto(allow_soft_placement=True) 28 | config.gpu_options.allow_growth = True 29 | self.sess = tf.Session(config = config) 30 | self.images = tf.placeholder(tf.float32) 31 | self.label, self.roi, self.landmark = model(self.images,batch_size) 32 | saver = tf.train.Saver() 33 | saver.restore(self.sess,model_path) 34 | 35 | self.size_to_predict = size_to_predict 36 | 37 | def predict(self, img): 38 | """ 39 | used for predict 40 | 41 | Parameters: 42 | ---------- 43 | img: numpy array 44 | 45 | Returns: 46 | ------- 47 | pre_label: numpy.array, shape (n,m,2 ) 48 | pre_box: numpy.array, shape (n,m, 4 ) 49 | pre_land: numpy.array, shape (n,m,10 ) 50 | 51 | predict 52 | """ 53 | pre_labels = [] 54 | pre_boxs = [] 55 | pre_lands = [] 56 | self.batch_size = img.shape[0] 57 | 58 | batch_num = self.batch_size // self.size_to_predict 59 | left = self.batch_size % self.size_to_predict 60 | 61 | if(self.model_name == "Pnet"): 62 | pre_labels, pre_boxs = self.sess.run([self.label, self.roi], feed_dict={self.images:img}) 63 | pre_lands = np.array([0]) 64 | else: 65 | for idx in range(batch_num): 66 | img_batch = img[idx*self.size_to_predict:(idx+1)*self.size_to_predict] 67 | pre_label, pre_box, pre_land = self.sess.run([self.label, self.roi, self.landmark], feed_dict={self.images:img_batch}) 68 | pre_labels += list(pre_label) 69 | pre_boxs += list(pre_box) 70 | pre_lands += list(pre_land) 71 | if left : 72 | img_batch = np.zeros((self.size_to_predict, img.shape[1], img.shape[2],3)) 73 | img_batch[:left,...] = img[-left:] 74 | pre_label, pre_box, pre_land = self.sess.run([self.label, self.roi, self.landmark], feed_dict={self.images:img_batch}) 75 | pre_labels += list(pre_label)[:left] 76 | pre_boxs += list(pre_box)[:left] 77 | pre_lands += list(pre_land)[:left] 78 | 79 | return np.vstack(pre_labels), np.vstack(pre_boxs), np.vstack(pre_lands) -------------------------------------------------------------------------------- /version 2.0/MTCNN code/detection/mtcnn_detector.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | @author: friedhelm 4 | 5 | """ 6 | import sys 7 | sys.path.append("../") 8 | 9 | import numpy as np 10 | import cv2 11 | from core.tool import NMS 12 | from detection.detector import Detector 13 | import time 14 | 15 | class MTCNN_Detector(object): 16 | 17 | def __init__(self,model,model_path,batch_size,factor,min_face_size,threshold): 18 | 19 | self.pnet_model=model[0] 20 | self.rnet_model=model[1] 21 | self.onet_model=model[2] 22 | self.model_path=model_path 23 | self.batch_size=batch_size 24 | self.factor=factor 25 | self.min_face_size=min_face_size 26 | self.threshold=threshold 27 | self.pnet_detector=Detector(self.pnet_model,self.model_path[0],"Pnet",self.batch_size) 28 | self.rnet_detector=Detector(self.rnet_model,self.model_path[1],"Rnet",-1) 29 | self.onet_detector=Detector(self.onet_model,self.model_path[2],"Onet",-1) 30 | 31 | 32 | def generate_box(self,score_box,bounding_box,img_size,scale,stride,threshold): 33 | """ 34 | used for sliding window 35 | 36 | Parameters: 37 | ---------- 38 | score_box : numpy.array, shape(n,m,1 ) 39 | bounding_box : numpy.array, shape(n,m,4 ) 40 | img_size : numpy.array 41 | scale : int 42 | stride : int 43 | threshold : int 44 | 45 | Returns: 46 | ------- 47 | numpy.array 48 | 49 | generate_box 50 | """ 51 | idx=np.where(score_box>threshold) 52 | 53 | if(idx[0].size==0): 54 | return np.array([]) 55 | 56 | delta_x1,delta_y1,delta_x2,delta_y2=[bounding_box[idx[0],idx[1],i] for i in range(4)] 57 | delta_box=np.array([delta_x1,delta_y1,delta_x2,delta_y2]) 58 | score=score_box[idx[0],idx[1]] 59 | 60 | return np.vstack([(idx[1]*stride/scale), 61 | (idx[0]*stride/scale), 62 | ((idx[1]*stride+img_size)/scale), 63 | ((idx[0]*stride+img_size)/scale), 64 | score, 65 | delta_box]).T 66 | 67 | 68 | def pad(self,t_box,w,h): 69 | """ 70 | used for padding t_box that out of range 71 | 72 | Parameters: 73 | ---------- 74 | t_box : numpy.array,format [x1,y1,x2,y2] 75 | w : int 76 | h : int 77 | 78 | Returns: 79 | ------- 80 | t_box : numpy.array,format [x1,y1,x2,y2] 81 | 82 | pad 83 | """ 84 | xl_idx=np.where((t_box[:,0]<0))[0] 85 | t_box[xl_idx]=0 86 | 87 | yl_idx=np.where((t_box[:,1]<0))[0] 88 | t_box[yl_idx]=0 89 | 90 | xr_idx=np.where((t_box[:,2]>w))[0] 91 | t_box[xr_idx]=w-1 92 | 93 | yr_idx=np.where((t_box[:,3]>h))[0] 94 | t_box[yr_idx]=h-1 95 | 96 | return t_box 97 | 98 | def convert_to_square(self,box): 99 | """ 100 | used for converting box to square 101 | 102 | Parameters: 103 | ---------- 104 | box : numpy.array,format [x1,y1,x2,y2] 105 | 106 | Returns: 107 | ------- 108 | square_box : numpy.array,format [x1,y1,x2,y2] 109 | 110 | pad 111 | """ 112 | square_box=box.copy() 113 | 114 | h=box[:,3]-box[:,1]+1 115 | w=box[:,2]-box[:,0]+1 116 | 117 | max_side=np.maximum(w,h) 118 | 119 | square_box[:,0]=box[:,0]+w*0.5-max_side*0.5 120 | square_box[:,1]=box[:,1]+h*0.5-max_side*0.5 121 | square_box[:,2]=square_box[:,0]+max_side-1 122 | square_box[:,3]=square_box[:,1]+max_side-1 123 | 124 | return square_box 125 | 126 | 127 | def calibrate_box(self,img,NMS_box,model_name="default"): 128 | """ 129 | used for calibrating NMS_box 130 | 131 | Parameters: 132 | ---------- 133 | img : numpy.array 134 | NMS_box : numpy.array,format [x1,y1,x2,y2,score,offset_x1,offset_y1,offset_x2,offset_y2,5*(landmark_x,landmark_y)] 135 | model_name : str 136 | 137 | Returns: 138 | ------- 139 | score_box : numpy.array, shape(n,1 ) 140 | net_box : numpy.array, shape(n,4 ) 141 | landmark_box : numpy.array, shape(n,10 ) 142 | 143 | calibrate_box 144 | """ 145 | landmark_box=np.array([]) 146 | h,w,c=img.shape 147 | 148 | t_box=np.zeros((NMS_box.shape[0],4)) 149 | boxes=np.vstack(NMS_box) 150 | 151 | bounding_box=boxes[:,0:4] 152 | delta_box=boxes[:,5:9] 153 | 154 | t_w=bounding_box[:,2]-bounding_box[:,0]+1 155 | t_w=np.expand_dims(t_w,1) 156 | t_h=bounding_box[:,3]-bounding_box[:,1]+1 157 | t_h=np.expand_dims(t_h,1) 158 | 159 | w_h=np.hstack([t_w,t_h,t_w,t_h]) 160 | t_box=bounding_box+delta_box*w_h 161 | 162 | if(model_name!="Onet"): 163 | t_box=self.convert_to_square(t_box) 164 | 165 | t_box=self.pad(t_box,w,h) 166 | idx=np.where((t_box[:,2]-t_box[:,0]>=self.min_face_size)&(t_box[:,3]-t_box[:,1]>=self.min_face_size))[0] 167 | net_box=t_box[idx] 168 | 169 | if(model_name=="Onet"): 170 | boxes=boxes[idx] 171 | onet_box=np.vstack(net_box) 172 | score_box=boxes[:,4] 173 | landmark_box=np.zeros((boxes.shape[0],5,2)) 174 | 175 | for i in range(5): 176 | landmark_box[:,i,0],landmark_box[:,i,1]=(boxes[:,9+i*2]*(onet_box[:,2]-onet_box[:,0])+onet_box[:,0],boxes[:,9+i*2+1]*(onet_box[:,3]-onet_box[:,1])+onet_box[:,1]) 177 | else: 178 | score_box=boxes[:,4][idx] 179 | 180 | return score_box,net_box,landmark_box 181 | 182 | 183 | def detect_Pnet(self,pnet_detector,img): 184 | """ 185 | used for detect_Pnet 186 | 187 | Parameters: 188 | ---------- 189 | img : numpy.array 190 | pnet_detector : class detector 191 | 192 | 193 | Returns: 194 | ------- 195 | score_box : numpy.array, shape(n,1 ) 196 | pnet_box : numpy.array, shape(n,4 ) 197 | [] 198 | 199 | detect_Pnet 200 | """ 201 | factor=self.factor 202 | pro=12/self.min_face_size 203 | scales=[] 204 | total_box=[] 205 | small=min(img.shape[0:2])*pro 206 | 207 | while small>=12: 208 | scales.append(pro) 209 | pro*=factor 210 | small*=factor 211 | p=0 212 | for scale in scales: 213 | 214 | crop_img=img 215 | scale_img=cv2.resize(crop_img,((int(crop_img.shape[1]*scale)),(int(crop_img.shape[0]*scale)))) 216 | scale_img1=np.reshape(scale_img,(-1,scale_img.shape[0],scale_img.shape[1],scale_img.shape[2])) 217 | 218 | score_boxes,delta_boxes,_=pnet_detector.predict(scale_img1) 219 | 220 | bounding_boxes=self.generate_box(score_box=score_boxes[:,:,1],bounding_box=delta_boxes,img_size=12,scale=scale,stride=2,threshold=self.threshold[0]) 221 | 222 | a=time.time() 223 | if(len(bounding_boxes)!=0): 224 | idx=NMS(bounding_boxes[:,0:5],0.5) 225 | NMS_bounding_boxes=bounding_boxes[idx] 226 | total_box.append(NMS_bounding_boxes) 227 | p+=time.time()-a 228 | a=time.time() 229 | if(len(total_box)==0): 230 | return [],[],[] 231 | total_box=np.vstack(total_box) 232 | idx=NMS(total_box,0.7) 233 | NMS_box=total_box[idx] 234 | p+=time.time()-a 235 | #print("NMS: ",p) 236 | 237 | 238 | score_box,pnet_box,_=self.calibrate_box(img,NMS_box) 239 | 240 | return score_box,pnet_box,[] 241 | 242 | 243 | def detect_Rnet(self,rnet_detector,img,bounding_box): 244 | """ 245 | used for detect_Rnet 246 | 247 | Parameters: 248 | ---------- 249 | img : numpy.array 250 | rnet_detector : class detector 251 | bounding_box : numpy.array, shape(n,4 ) 252 | 253 | Returns: 254 | ------- 255 | score_box : numpy.array, shape(n,1 ) 256 | pnet_box : numpy.array, shape(n,4 ) 257 | [] 258 | 259 | detect_Rnet 260 | """ 261 | scale_img=np.zeros((len(bounding_box),24,24,3)) 262 | for idx,box in enumerate(bounding_box): 263 | scale_img[idx,:,:,:] = cv2.resize(img[int(box[1]):int(box[3]),int(box[0]):int(box[2]),:], (24, 24)) 264 | 265 | score_boxes,delta_boxes,_=rnet_detector.predict(scale_img) 266 | 267 | idx=np.where(score_boxes[:,1]>self.threshold[1])[0] 268 | 269 | if(len(idx)==0): 270 | return [],[],[] 271 | delta_boxes=delta_boxes[idx] 272 | bounding_box=bounding_box[idx] 273 | score_boxes=np.expand_dims(score_boxes[idx,1],1) 274 | bounding_box=np.hstack([bounding_box,score_boxes]) 275 | 276 | idx=NMS(bounding_box,0.6) 277 | bounding_box=bounding_box[idx] 278 | delta_boxes=delta_boxes[idx] 279 | 280 | NMS_box=np.hstack([bounding_box,delta_boxes]) 281 | 282 | score_box,rnet_box,_=self.calibrate_box(img,NMS_box) 283 | 284 | return score_box,rnet_box,[] 285 | 286 | 287 | def detect_Onet(self,onet_detector,img,bounding_box): 288 | """ 289 | used for detect_Onet 290 | 291 | Parameters: 292 | ---------- 293 | img : numpy.array 294 | onet_detector : class detector 295 | bounding_box : numpy.array, shape(n,4 ) 296 | 297 | Returns: 298 | ------- 299 | score_box : numpy.array, shape(n,1 ) 300 | pnet_box : numpy.array, shape(n,4 ) 301 | landmark_box : numpy.array, shape(n,10 ) 302 | 303 | detect_Onet 304 | """ 305 | scale_img=np.zeros((len(bounding_box),48,48,3)) 306 | for idx,box in enumerate(bounding_box): 307 | scale_img[idx,:,:,:] = cv2.resize(img[int(box[1]):int(box[3]),int(box[0]):int(box[2]),:], (48, 48)) 308 | 309 | score_boxes,delta_boxes,landmark_boxes=onet_detector.predict(scale_img) 310 | idx=np.where(score_boxes[:,1]>self.threshold[1])[0] 311 | 312 | if(len(idx)==0): 313 | return [],[],[] 314 | delta_boxes=delta_boxes[idx] 315 | bounding_box=bounding_box[idx] 316 | score_boxes=np.expand_dims(score_boxes[idx,1],1) 317 | bounding_box=np.hstack([bounding_box,score_boxes]) 318 | landmark_boxes=landmark_boxes[idx] 319 | 320 | idx=NMS(bounding_box,0.6,"Minimum") 321 | bounding_box=bounding_box[idx] 322 | delta_boxes=delta_boxes[idx] 323 | landmark_boxes=landmark_boxes[idx] 324 | 325 | NMS_box=np.hstack([bounding_box,delta_boxes,landmark_boxes]) 326 | 327 | score_box,onet_box,landmark_box=self.calibrate_box(img,NMS_box,"Onet") 328 | 329 | return score_box,onet_box,landmark_box 330 | 331 | 332 | def detect_face(self,images): 333 | """ 334 | used for detecting face in both batch images and single image 335 | 336 | Parameters: 337 | ---------- 338 | img : numpy.array, format[batch_size,img] 339 | 340 | Returns: 341 | ------- 342 | face_boxes : list of face_box batch_size*[face_x1,face_x2,face_y1,face_y2] 343 | landmark_boxes : list of landmark_box batch_size*[5*(landmark_x,landmark_y)] 344 | 345 | detect_face 346 | """ 347 | sign=False 348 | bounding_box=[] 349 | landmark_box=[] 350 | face_boxes=[] 351 | landmark_boxes=[] 352 | detect_begin=time.time() 353 | 354 | if(np.size(images.shape)==3): 355 | sign=True 356 | img=np.zeros((1,images.shape[0],images.shape[1],images.shape[2])) 357 | img[0,:,:,:]=images 358 | images=img 359 | 360 | for img in images: 361 | 362 | if(img is None): 363 | face_boxes.append([]) 364 | landmark_boxes.append([]) 365 | continue 366 | 367 | img=(img-127.5)/128 368 | 369 | if self.pnet_model: 370 | pt=time.time() 371 | score_box,bounding_box,landmark_box=self.detect_Pnet(self.pnet_detector,img) 372 | 373 | print("pnet-time: ",time.time()-pt) 374 | if(len(bounding_box)==0): 375 | face_boxes.append([]) 376 | landmark_boxes.append([]) 377 | continue 378 | 379 | if self.rnet_model: 380 | rt=time.time() 381 | score_box,bounding_box,landmark_box=self.detect_Rnet(self.rnet_detector,img,bounding_box) 382 | 383 | print("rnet-time: ",time.time()-rt) 384 | if(len(bounding_box)==0): 385 | face_boxes.append([]) 386 | landmark_boxes.append([]) 387 | continue 388 | 389 | if self.onet_model: 390 | ot=time.time() 391 | score_box,bounding_box,landmark_box=self.detect_Onet(self.onet_detector,img,bounding_box) 392 | 393 | print("onet-time: ",time.time()-ot) 394 | if(len(bounding_box)==0): 395 | face_boxes.append([]) 396 | landmark_boxes.append([]) 397 | continue 398 | 399 | face_boxes.append(bounding_box) 400 | landmark_boxes.append(landmark_box) 401 | 402 | print("detect-time: ",time.time()-detect_begin) 403 | if(sign): 404 | return face_boxes[0],landmark_boxes[0] 405 | else: 406 | return face_boxes,landmark_boxes 407 | 408 | 409 | def detect_single_face(self,img,print_time=True): 410 | """ 411 | used for detecting single face or vidioe 412 | 413 | Parameters: 414 | ---------- 415 | img : numpy.array, format[batch_size,img] 416 | 417 | Returns: 418 | ------- 419 | bounding_box : list of box [face_x1,face_x2,face_y1,face_y2] 420 | landmark_box : list of box [5*(landmark_x,landmark_y)] 421 | 422 | detect_single_face 423 | """ 424 | bounding_box=[] 425 | landmark_box=[] 426 | detect_begin=time.time() 427 | 428 | if(img is None): 429 | return [],[] 430 | 431 | img=(img-127.5)/128 432 | 433 | if self.pnet_model: 434 | score_box,bounding_box,_=self.detect_Pnet(self.pnet_detector,img) 435 | 436 | if(len(bounding_box)==0): 437 | return [],[] 438 | 439 | if self.rnet_model: 440 | score_box,bounding_box,_=self.detect_Rnet(self.rnet_detector,img,bounding_box) 441 | 442 | if(len(bounding_box)==0): 443 | return [],[] 444 | 445 | if self.onet_model: 446 | score_box,bounding_box,landmark_box=self.detect_Onet(self.onet_detector,img,bounding_box) 447 | 448 | if(len(bounding_box)==0): 449 | return [],[] 450 | 451 | if print_time: 452 | print("detect-time: ",time.time()-detect_begin) 453 | 454 | return bounding_box,landmark_box -------------------------------------------------------------------------------- /version 2.0/MTCNN code/prepare_data/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 2.0/MTCNN code/prepare_data/__init__.py -------------------------------------------------------------------------------- /version 2.0/MTCNN code/prepare_data/gen_classify_regression_data.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | @author: friedhelm 4 | 5 | """ 6 | import sys 7 | sys.path.append("../") 8 | 9 | from core.tool import IoU 10 | import numpy as np 11 | from numpy.random import randint 12 | import cv2 13 | import os 14 | import time 15 | import argparse 16 | 17 | def arg_parse(): 18 | 19 | parser=argparse.ArgumentParser() 20 | parser.add_argument("--base_dir",default="../",type=str, help='base path to save TFRecord file') 21 | 22 | return parser 23 | 24 | 25 | def main(): 26 | 27 | f1 = open(os.path.join(save_dir, 'pos_%d.txt'%(img_size)), 'w') 28 | f2 = open(os.path.join(save_dir, 'neg_%d.txt'%(img_size)), 'w') 29 | f3 = open(os.path.join(save_dir, 'par_%d.txt'%(img_size)), 'w') 30 | 31 | with open(WIDER_spilt_dir) as filenames: 32 | p=0 33 | neg_idx=0 34 | pos_idx=0 35 | par_idx=0 36 | for line in filenames.readlines(): 37 | line=line.strip().split(' ') 38 | if(p==0): 39 | pic_dir=line[0] 40 | p=1 41 | boxes=[] 42 | elif(p==1): 43 | k=int(line[0]) 44 | p=2 45 | elif(p==2): 46 | b=[] 47 | k=k-1 48 | if(k==0): 49 | p=0 50 | for i in range(4): 51 | b.append(int(line[i])) 52 | boxes.append(b) 53 | # format of boxes is [x,y,w,h] 54 | if(p==0): 55 | img=cv2.imread(os.path.join(WIDER_dir,pic_dir)) 56 | h,w,c=img.shape 57 | 58 | #save num negative pics whose IoU less than 0.3 59 | num=50 60 | while(num): 61 | size=randint(12,min(w,h)/2) 62 | x=randint(0,w-size) 63 | y=randint(0,h-size) 64 | if(np.max(IoU(np.array([x,y,x+size,y+size]),np.array(boxes)))<0.3): 65 | resized_img = cv2.resize(img[y:y+size,x:x+size,:], (img_size, img_size)) 66 | cv2.imwrite(os.path.join(negative_dir,'neg_%d.jpg'%(neg_idx)),resized_img) 67 | f2.write(os.path.join(negative_dir,'neg_%d.jpg'%(neg_idx)) + ' 0\n') 68 | neg_idx=neg_idx+1 69 | num=num-1 70 | 71 | for box in boxes: 72 | if((box[0]<0)|(box[1]<0)|(max(box[2],box[3])<20)|(min(box[2],box[3])<=5)): 73 | continue 74 | x1, y1, w1, h1 = box 75 | 76 | # crop images near the bounding box if IoU less than 0.3, save as negative samples 77 | for i in range(20): 78 | size = randint(12, min(w, h) / 2) 79 | delta_x = randint(max(-size, -x1), w1) 80 | delta_y = randint(max(-size, -y1), h1) 81 | nx1 = int(max(0, x1 + delta_x)) 82 | ny1 = int(max(0, y1 + delta_y)) 83 | if((nx1 + size > w1)|(ny1 + size > h1)): 84 | continue 85 | if(np.max(IoU(np.array([nx1,ny1,nx1+size,ny1+size]),np.array(boxes)))<0.3): 86 | resized_img = cv2.resize(img[y:y+size,x:x+size,:], (img_size, img_size)) 87 | cv2.imwrite(os.path.join(negative_dir,'neg_%d.jpg'%(neg_idx)),resized_img) 88 | f2.write(os.path.join(negative_dir,'neg_%d.jpg'%(neg_idx)) + ' 0\n') 89 | neg_idx=neg_idx+1 90 | 91 | #save num positive&part face whose IoU more than 0.65|0.4 92 | box_ = np.array(box).reshape(1, -1) 93 | for i in range(15): 94 | size=randint(np.floor(0.8*min(w1,h1)),np.ceil(1.25*max(w1,h1))+1) 95 | 96 | delta_w = randint(-w1 * 0.2, w1 * 0.2 + 1) 97 | delta_h = randint(-h1 * 0.2, h1 * 0.2 + 1) 98 | # random face box 99 | nx1 = int(max(x1 + w1 / 2 + delta_w - size / 2, 0)) 100 | ny1 = int(max(y1 + h1 / 2 + delta_h - size / 2, 0)) 101 | nx2 = nx1 + size 102 | ny2 = ny1 + size 103 | 104 | if( nx2 > w | ny2 > h): 105 | continue 106 | 107 | offset_x1 = (x1 - nx1) / float(size) 108 | offset_y1 = (y1 - ny1) / float(size) 109 | offset_x2 = (x1+w1 - nx2) / float(size) 110 | offset_y2 = (y1+h1 - ny2) / float(size) 111 | 112 | if(IoU(np.array([nx1,ny1,nx2,ny2]),box_)>0.65): 113 | resized_img = cv2.resize(img[ny1:ny2,nx1:nx2,:], (img_size, img_size)) 114 | cv2.imwrite(os.path.join(positive_dir,'pos_%d.jpg'%(pos_idx)),resized_img) 115 | f1.write(os.path.join(positive_dir,'pos_%d.jpg'%(pos_idx)) + ' 1 %.2f %.2f %.2f %.2f\n'%(offset_x1,offset_y1,offset_x2,offset_y2)) 116 | pos_idx=pos_idx+1 117 | 118 | elif(IoU(np.array([nx1,ny1,nx2,ny2]),box_)>0.4): 119 | resized_img = cv2.resize(img[ny1:ny2,nx1:nx2,:], (img_size, img_size)) 120 | cv2.imwrite(os.path.join(par_dir,'par_%d.jpg'%(par_idx)),resized_img) 121 | f3.write(os.path.join(par_dir,'par_%d.jpg'%(par_idx)) + ' -1 %.2f %.2f %.2f %.2f\n'%(offset_x1,offset_y1,offset_x2,offset_y2)) 122 | par_idx=par_idx+1 123 | print("pics all done,neg_pics %d in total,pos_pics %d in total,par_pics %d in total"%(neg_idx,pos_idx,par_idx)) 124 | 125 | f1.close() 126 | f2.close() 127 | f3.close() 128 | 129 | 130 | if __name__=="__main__": 131 | 132 | parser=arg_parse() 133 | base_dir=parser.base_dir 134 | 135 | img_size=12 136 | #base_dir="/home/dell/Desktop/MTCNN" 137 | 138 | WIDER_dir=os.path.join(base_dir,"prepared_data/WIDER_train/images") 139 | WIDER_spilt_dir=os.path.join(base_dir,"prepared_data/wider_face_split/wider_face_train_bbx_gt.txt") 140 | negative_dir=os.path.join(base_dir,"DATA/%d/negative"%(img_size)) 141 | positive_dir=os.path.join(base_dir,"DATA/%d/positive"%(img_size)) 142 | par_dir=os.path.join(base_dir,"DATA/%d/part"%(img_size)) 143 | save_dir=os.path.join(base_dir,"DATA/%d"%(img_size)) 144 | 145 | if not os.path.exists(positive_dir): 146 | os.makedirs(positive_dir) 147 | if not os.path.exists(par_dir): 148 | os.makedirs(par_dir) 149 | if not os.path.exists(negative_dir): 150 | os.makedirs(negative_dir) 151 | 152 | begin=time.time() 153 | 154 | main() 155 | 156 | print(time.time()-begin) -------------------------------------------------------------------------------- /version 2.0/MTCNN code/prepare_data/gen_hard_sample.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | @author: friedhelm 4 | 5 | """ 6 | import sys 7 | sys.path.append("../") 8 | 9 | from detection.mtcnn_detector import MTCNN_Detector 10 | from core.MTCNN_model import Pnet_model,Rnet_model,Onet_model 11 | from core.tool import IoU 12 | import cv2 13 | import numpy as np 14 | import os 15 | import time 16 | import argparse 17 | 18 | def arg_parse(): 19 | 20 | parser=argparse.ArgumentParser() 21 | 22 | parser.add_argument("--img_size",default=12,type=int, help='img size to generate') 23 | parser.add_argument("--base_dir",default="../",type=str, help='base path to save TFRecord file') 24 | parser.add_argument("--threshold",default=[0.8,0.8,0.6],type=list, help='threshold of models') 25 | parser.add_argument("--min_face_size",default=10,type=int, help='min face size') 26 | parser.add_argument("--factor",default=0.79,type=int, help='factor of img') 27 | parser.add_argument("--model_path",type=list, help='model path') 28 | parser.add_argument("--model_name",default="Pnet",type=str, help='from which model to generate data') 29 | 30 | return parser 31 | 32 | 33 | def main(): 34 | 35 | if(model_name in ["Pnet","Rnet","Onet"]): 36 | model[0]=Pnet_model 37 | if(model_name in ["Rnet","Onet"]): 38 | model[1]=Rnet_model 39 | if(model_name=="Onet"): 40 | model[2]=Onet_model 41 | 42 | detector=MTCNN_Detector(model,model_path,batch_size,factor,min_face_size,threshold) 43 | 44 | with open(WIDER_spilt_dir) as filenames: 45 | p=0 46 | neg_idx=0 47 | pos_idx=0 48 | par_idx=0 49 | idx=0 50 | for line in filenames.readlines(): 51 | line=line.strip().split(' ') 52 | if(p==0): 53 | pic_dir=line[0] 54 | p=1 55 | boxes=[] 56 | elif(p==1): 57 | k=int(line[0]) 58 | p=2 59 | elif(p==2): 60 | b=[] 61 | k=k-1 62 | if(k==0): 63 | p=0 64 | for i in range(4): 65 | b.append(int(line[i])) 66 | boxes.append(b) 67 | # format of boxes is [x,y,w,h] 68 | if(p==0): 69 | 70 | img=cv2.imread(os.path.join(WIDER_dir,pic_dir)) 71 | 72 | face_box,_=detector.detect_single_face(img) 73 | neg_num=0 74 | for t_box in face_box: 75 | 76 | ti_box=t_box.copy() 77 | ti_box=[int(_) for _ in ti_box] 78 | 79 | Iou=IoU(np.array(t_box),np.array(boxes)) 80 | 81 | if((np.max(Iou)<0.3)&(neg_num<60)): 82 | resized_img = cv2.resize(img[ti_box[1]:ti_box[3],ti_box[0]:ti_box[2],:], (img_size,img_size)) 83 | cv2.imwrite(os.path.join(negative_dir,'neg_%d.jpg'%(neg_idx)),resized_img) 84 | f2.write(os.path.join(negative_dir,'neg_%d.jpg'%(neg_idx)) + ' 0\n') 85 | neg_idx=neg_idx+1 86 | neg_num=neg_num+1 87 | 88 | else: 89 | x1,y1,w1,h1=boxes[np.argmax(Iou)] 90 | 91 | offset_x1 = (x1 - t_box[0]) / float(t_box[2]-t_box[0]+1) 92 | offset_y1 = (y1 - t_box[1]) / float(t_box[3]-t_box[1]+1) 93 | offset_x2 = (x1+w1 - t_box[2]) / float(t_box[2]-t_box[0]+1) 94 | offset_y2 = (y1+h1 - t_box[3]) / float(t_box[3]-t_box[1]+1) 95 | 96 | if(np.max(Iou)>0.65): 97 | resized_img = cv2.resize(img[ti_box[1]:ti_box[3],ti_box[0]:ti_box[2],:], (img_size, img_size)) 98 | cv2.imwrite(os.path.join(positive_dir,'pos_%d.jpg'%(pos_idx)),resized_img) 99 | f1.write(os.path.join(positive_dir,'pos_%d.jpg'%(pos_idx)) + ' 1 %.2f %.2f %.2f %.2f\n'%(offset_x1,offset_y1,offset_x2,offset_y2)) 100 | pos_idx=pos_idx+1 101 | 102 | elif(np.max(Iou)>0.4): 103 | resized_img = cv2.resize(img[ti_box[1]:ti_box[3],ti_box[0]:ti_box[2],:], (img_size, img_size)) 104 | cv2.imwrite(os.path.join(par_dir,'par_%d.jpg'%(par_idx)),resized_img) 105 | f3.write(os.path.join(par_dir,'par_%d.jpg'%(par_idx)) + ' -1 %.2f %.2f %.2f %.2f\n'%(offset_x1,offset_y1,offset_x2,offset_y2)) 106 | par_idx=par_idx+1 107 | idx+=1 108 | if(idx%100==0): 109 | print('idx: ',idx," ;neg_idx: ",neg_idx," ;pos_idx: ",pos_idx," ;par_idx: ",par_idx) 110 | print(time.time()-begin) 111 | print("pics all done,neg_pics %d in total,pos_pics %d in total,par_pics %d in total"%(neg_idx,pos_idx,par_idx)) 112 | 113 | if __name__=="__main__": 114 | 115 | os.environ["TF_CPP_MIN_LOG_LEVEL"] = "2" 116 | 117 | parser=arg_parse() 118 | base_dir=parser.base_dir 119 | img_size=parser.img_size 120 | threshold=parser.threshold 121 | min_face_size=parser.min_face_size 122 | factor=parser.factor 123 | model_name=parser.model_name 124 | model_path=parser.model_path 125 | 126 | #parameters to modify 127 | #threshold=[0.8,0.8,0.6] 128 | #min_face_size=10 129 | #base=200000 130 | #img_size=12 131 | #base_dir="/home/dell/Desktop/MTCNN" 132 | #factor=0.79 133 | #model_name="Pnet" 134 | #model_path=[os.path.join(base_dir,"model/Pnet_model/Pnet_model.ckpt-20000"), 135 | # None, 136 | # None] 137 | #parameters to modify 138 | batch_size=1 139 | model=[None,None,None] 140 | 141 | WIDER_dir=os.path.join(base_dir,"prepared_data/WIDER_train/images") 142 | WIDER_spilt_dir=os.path.join(base_dir,"prepared_data/wider_face_split/wider_face_train_bbx_gt.txt") 143 | negative_dir=os.path.join(base_dir,"DATA/%d/negative"%(img_size)) 144 | positive_dir=os.path.join(base_dir,"DATA/%d/positive"%(img_size)) 145 | par_dir=os.path.join(base_dir,"DATA/%d/part"%(img_size)) 146 | save_dir=os.path.join(base_dir,"DATA/%d"%(img_size)) 147 | 148 | if not os.path.exists(positive_dir): 149 | os.makedirs(positive_dir) 150 | if not os.path.exists(par_dir): 151 | os.makedirs(par_dir) 152 | if not os.path.exists(negative_dir): 153 | os.makedirs(negative_dir) 154 | 155 | begin=time.time() 156 | 157 | f1 = open(os.path.join(save_dir, 'pos_%d.txt'%(img_size)), 'w') 158 | f2 = open(os.path.join(save_dir, 'neg_%d.txt'%(img_size)), 'w') 159 | f3 = open(os.path.join(save_dir, 'par_%d.txt'%(img_size)), 'w') 160 | 161 | main() 162 | 163 | f1.close() 164 | f2.close() 165 | f3.close() 166 | 167 | print(time.time()-begin) -------------------------------------------------------------------------------- /version 2.0/MTCNN code/prepare_data/gen_landmark_data.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | @author: friedhelm 4 | 5 | """ 6 | import sys 7 | sys.path.append("../") 8 | 9 | from core.tool import IoU,flip 10 | import numpy as np 11 | import random 12 | from numpy.random import randint 13 | import cv2 14 | import os 15 | import time 16 | import argparse 17 | 18 | def arg_parse(): 19 | 20 | parser=argparse.ArgumentParser() 21 | 22 | parser.add_argument("--img_size",default=12,type=int, help='img size to generate') 23 | parser.add_argument("--base_dir",default="../",type=str, help='base path to save TFRecord file') 24 | 25 | return parser 26 | 27 | 28 | def main(): 29 | 30 | f4 = open(os.path.join(save_dir, 'land_%d.txt'%(img_size)), 'w') 31 | 32 | with open(pic_spilt_dir) as filenames: 33 | land_idx=0 34 | for line in filenames: 35 | img_list=[] 36 | mark_list=[] 37 | line=line.strip().split(' ') 38 | img=cv2.imread(os.path.join(lfw_dir,line[0].replace("\\","/"))) 39 | box=(line[1],line[2],line[3],line[4]) 40 | box=[int(_) for _ in box] 41 | #format of box is [x,x+w,y,y+h] 42 | height,weight,channel=img.shape 43 | landmark=np.zeros((5,2)) 44 | for i in range(5): 45 | mark=(float(line[5+2*i]),float(line[5+2*i+1])) 46 | landmark[i]=mark 47 | 48 | facemark=np.zeros((5,2)) 49 | for i in range(5): 50 | mark=((landmark[i][0]-box[0])/(box[1]-box[0]),(landmark[i][1]-box[2])/(box[3]-box[2])) 51 | facemark[i]=mark 52 | img_list.append(cv2.resize(img[box[2]:box[3],box[0]:box[1]], (img_size, img_size))) 53 | mark_list.append(facemark.reshape(10)) 54 | 55 | box_=[box[0],box[2],box[1],box[3]] 56 | #format of box is [x,y,x+w,y+h] 57 | x1,y1,x2,y2=box_ 58 | w=x2-x1+1 59 | h=y2-y1+1 60 | 61 | if((x1<0)|(y1<0)|(max(w,h)<40)|(min(w,h)<=5)): 62 | continue 63 | num=50 64 | while(num): 65 | 66 | size=randint(np.floor(0.8*min(w,h)),np.ceil(1.25*max(w,h))+1) 67 | 68 | delta_w = randint(-w * 0.2, w * 0.2 + 1) 69 | delta_h = randint(-h * 0.2, h * 0.2 + 1) 70 | # random face box 71 | nx1 = int(max(x1 + w / 2 + delta_w - size / 2, 0)) 72 | ny1 = int(max(y1 + h / 2 + delta_h - size / 2, 0)) 73 | nx2 = nx1 + size 74 | ny2 = ny1 + size 75 | 76 | if( nx2 > weight | ny2 > height): 77 | continue 78 | 79 | _box=[x1,y1,w,h] 80 | _box=np.array(_box).reshape(1,-1) 81 | if(IoU(np.array([nx1,ny1,nx2,ny2]),_box)>0.65): 82 | facemark=np.zeros((5,2)) 83 | for i in range(5): 84 | mark=((landmark[i][0]-nx1)/size,(landmark[i][1]-ny1)/size) 85 | facemark[i]=mark 86 | img_list.append(cv2.resize(img[ny1:ny2,nx1:nx2,:], (img_size, img_size))) 87 | mark_list.append(facemark.reshape(10)) 88 | 89 | #mirro 90 | mirro_mark=facemark.copy() 91 | if(random.choice([0,1])): 92 | img1,mirro_mark=flip(img[ny1:ny2,nx1:nx2,:],mirro_mark) 93 | img_list.append(cv2.resize(img1, (img_size, img_size))) 94 | mark_list.append(mirro_mark.reshape(10)) 95 | 96 | num=num-1 97 | for i in range(len(img_list)): 98 | 99 | if np.sum(np.where(mark_list[i] <= 0, 1, 0)) > 0: 100 | continue 101 | 102 | if np.sum(np.where(mark_list[i] >= 1, 1, 0)) > 0: 103 | continue 104 | 105 | cv2.imwrite(os.path.join(landmark_dir,'land_%d.jpg'%(land_idx)),img_list[i]) 106 | mark=[str(_)for _ in mark_list[i]] 107 | f4.write(os.path.join(landmark_dir,'land_%d.jpg'%(land_idx)) +' -2 '+' '.join(mark)+'\n') 108 | land_idx=land_idx+1 109 | 110 | print("pics all done,land_pics %d in total"%(land_idx)) 111 | 112 | f4.close() 113 | 114 | if __name__=="__main__": 115 | 116 | parser=arg_parse() 117 | base_dir=parser.base_dir 118 | img_size=parser.img_size 119 | 120 | begin=time.time() 121 | 122 | #change img_size to P=12 R=24 O=48 net 123 | #img_size=12 124 | #base_dir="/home/dell/Desktop/MTCNN" 125 | 126 | lfw_dir=os.path.join(base_dir,"prepared_data/train") 127 | pic_spilt_dir=os.path.join(base_dir,"prepared_data/train/trainImageList.txt") 128 | landmark_dir=os.path.join(base_dir,"DATA/%d/landmark"%(img_size)) 129 | save_dir=os.path.join(base_dir,"DATA/%d"%(img_size)) 130 | 131 | if not os.path.exists(landmark_dir): 132 | os.makedirs(landmark_dir) 133 | 134 | main() 135 | 136 | print(time.time()-begin) -------------------------------------------------------------------------------- /version 2.0/MTCNN code/prepare_data/gen_tfrecord.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | @author: friedhelm 4 | 5 | """ 6 | import tensorflow as tf 7 | import cv2 8 | import random 9 | import time 10 | import os 11 | import argparse 12 | 13 | def arg_parse(): 14 | 15 | parser=argparse.ArgumentParser() 16 | 17 | parser.add_argument("--img_size",default=12 , type=int, help='img size to generate') 18 | parser.add_argument("--base_dir",default="../" , type=str, help='base path to save TFRecord file') 19 | parser.add_argument("--base_num",default=200000 , type=int, help='base num img to generate') 20 | 21 | return parser 22 | 23 | 24 | def main(): 25 | 26 | t_time=time.time() 27 | for index,term in enumerate(terms): 28 | num=0 29 | print("%s start"%(term)) 30 | tfr_addr=os.path.join(base_dir,"DATA/%d/%s_train.tfrecords"%(img_size,term)) 31 | with tf.python_io.TFRecordWriter(tfr_addr) as writer: 32 | file_addr=os.path.join(base_dir,"DATA/%d/%s.txt"%(img_size,term)) 33 | with open(file_addr) as readlines: 34 | readlines=[line.strip().split(' ') for line in readlines] 35 | random.shuffle(readlines) 36 | for i,line in enumerate(readlines): 37 | if(num%10000==0): 38 | print(i,time.time()-t_time) 39 | t_time=time.time() 40 | img=cv2.imread(line[0]) 41 | if(img is None): 42 | continue 43 | img_raw = img.tobytes() 44 | label=int(line[1]) 45 | roi=[0.0]*4 46 | landmark=[0.0]*10 47 | if(len(line)==6): 48 | roi=[float(_) for _ in line[2:6]] 49 | if(len(line)==12): 50 | landmark=[float(_) for _ in line[2:12]] 51 | example = tf.train.Example(features=tf.train.Features(feature={ 52 | 'img': tf.train.Feature(bytes_list=tf.train.BytesList(value=[img_raw])), 53 | "label": tf.train.Feature(int64_list=tf.train.Int64List(value=[label])), 54 | "roi": tf.train.Feature(float_list=tf.train.FloatList(value=roi)), 55 | "landmark": tf.train.Feature(float_list=tf.train.FloatList(value=landmark)), 56 | })) 57 | writer.write(example.SerializeToString()) #序列化为字符串 58 | num+=1 59 | if(num==base*scale[index]): 60 | print("%s finish"%(term)) 61 | break 62 | 63 | if __name__=="__main__": 64 | 65 | parser=arg_parse() 66 | base_dir=parser.base_dir 67 | img_size=parser.img_size 68 | base=parser.base_num 69 | 70 | terms=['neg_%d'%(img_size),'pos_%d'%(img_size),'par_%d'%(img_size),'land_%d'%(img_size)] 71 | scale=[3,1,1,2] 72 | 73 | #set base number of pos_pic 74 | #base=200000 75 | #img_size=12 76 | #base_dir="/home/dell/Desktop/MTCNN" 77 | 78 | begin=time.time() 79 | 80 | main() 81 | 82 | print(time.time()-begin) -------------------------------------------------------------------------------- /version 2.0/MTCNN code/prepare_data/test_TFRecord.py: -------------------------------------------------------------------------------- 1 | import tensorflow as tf 2 | import numpy as np 3 | import cv2 4 | 5 | 6 | filename_queue = tf.train.string_input_producer(["/home/dell/Desktop/prepared_data/DATA/12/par_12_train.tfrecords"],shuffle=True,num_epochs=1) 7 | 8 | reader = tf.TFRecordReader() 9 | _, serialized_example = reader.read(filename_queue) #返回文件名和文件 10 | 11 | features = tf.parse_single_example(serialized_example, 12 | features={ 13 | 'img':tf.FixedLenFeature([],tf.string), 14 | 'label':tf.FixedLenFeature([],tf.int64), 15 | 'roi':tf.FixedLenFeature([4],tf.float32), 16 | 'landmark':tf.FixedLenFeature([10],tf.float32), 17 | }) 18 | img=tf.decode_raw(features['img'],tf.uint8) 19 | label=tf.cast(features['label'],tf.int32) 20 | roi=tf.cast(features['roi'],tf.float32) 21 | landmark=tf.cast(features['landmark'],tf.float32) 22 | img = tf.reshape(img, [12,12,3]) 23 | # img=img_preprocess(img) 24 | min_after_dequeue = 10000 25 | batch_size = 64 26 | capacity = min_after_dequeue + 10 * batch_size 27 | image_batch, label_batch, roi_batch, landmark_batch = tf.train.shuffle_batch([img,label,roi,landmark], 28 | batch_size=batch_size, 29 | capacity=capacity, 30 | min_after_dequeue=min_after_dequeue, 31 | num_threads=7) 32 | 33 | 34 | i=0 35 | with tf.Session() as sess: 36 | sess.run((tf.global_variables_initializer(), 37 | tf.local_variables_initializer())) 38 | coord = tf.train.Coordinator() 39 | threads = tf.train.start_queue_runners(sess=sess,coord=coord) 40 | while(1): 41 | i=i+1 42 | if(i%9==1): 43 | print(sess.run(label_batch)) 44 | -------------------------------------------------------------------------------- /version 2.0/MTCNN code/train/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 2.0/MTCNN code/train/__init__.py -------------------------------------------------------------------------------- /version 2.0/MTCNN code/train/__pycache__/train_tool.cpython-36.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 2.0/MTCNN code/train/__pycache__/train_tool.cpython-36.pyc -------------------------------------------------------------------------------- /version 2.0/MTCNN code/train/train.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | @author: friedhelm 4 | 5 | """ 6 | import sys 7 | sys.path.append("../") 8 | 9 | import tensorflow as tf 10 | import time 11 | from core.tool import read_multi_tfrecords,image_color_distort 12 | from core.MTCNN_model import Pnet_model,Rnet_model,Onet_model 13 | from train.train_tool import label_los,roi_los,landmark_los,cal_accuracy 14 | import os 15 | import argparse 16 | 17 | def arg_parse(): 18 | 19 | parser=argparse.ArgumentParser() 20 | 21 | parser.add_argument("--img_size",default=12,type=int, help='img size to generate') 22 | parser.add_argument("--base_dir",default="../",type=str, help='base path to save TFRecord file') 23 | parser.add_argument("--batch_size",default=[192,64,64,128],type=list, help='batch size list of each tfrecord') 24 | parser.add_argument("--batch",default=448,type=int, help='total batch') 25 | parser.add_argument("--train_step",default=50001,type=int, help='train steps') 26 | parser.add_argument("--learning_rate",default=0.001,type=float, help='learning rate') 27 | parser.add_argument("--model_name",default="Pnet_model",type=str, help='from which model to generate data') 28 | 29 | return parser 30 | 31 | 32 | def train(image,label,roi,landmark,model,model_name): 33 | 34 | _label, _roi ,_landmark=model(image,batch) 35 | 36 | with tf.name_scope('output'): 37 | _label=tf.squeeze(_label,name='label') 38 | _roi=tf.squeeze(_roi,name='roi') 39 | _landmark=tf.squeeze(_landmark,name='landmark') 40 | 41 | _label_los=label_los(_label,label) 42 | _box_los=roi_los(label,_roi,roi) 43 | _landmark_los=landmark_los(label,_landmark,landmark) 44 | 45 | function_loss=_label_los*ratio[0]+_box_los*ratio[1]+_landmark_los*ratio[2] 46 | 47 | tf.add_to_collection("loss", function_loss) 48 | loss_all=tf.get_collection('loss') 49 | 50 | with tf.name_scope('loss'): 51 | loss=tf.reduce_sum(loss_all) 52 | tf.summary.scalar('loss',loss) 53 | 54 | opt=tf.train.AdamOptimizer(learning_rate).minimize(loss) 55 | 56 | with tf.name_scope('accuracy'): 57 | train_accuracy,truth_accuracy,false_accuracy=cal_accuracy(_label,label) 58 | tf.summary.scalar('accuracy',train_accuracy) 59 | tf.summary.scalar('ture_accuracy',truth_accuracy) 60 | tf.summary.scalar('false_accuracy',false_accuracy) 61 | 62 | saver=tf.train.Saver(max_to_keep=10) 63 | merged=tf.summary.merge_all() 64 | 65 | images,labels,rois,landmarks=read_multi_tfrecords(addr,batch_size,img_size) 66 | images=image_color_distort(images) 67 | 68 | with tf.Session() as sess: 69 | sess.run((tf.global_variables_initializer(), 70 | tf.local_variables_initializer())) 71 | coord = tf.train.Coordinator() 72 | threads = tf.train.start_queue_runners(sess=sess,coord=coord) 73 | image_batch,label_batch,roi_batch,landmark_batch=sess.run([images,labels,rois,landmarks]) 74 | 75 | writer_train=tf.summary.FileWriter(os.path.join(base_dir,"model/%s/"%(model_name)),sess.graph) 76 | try: 77 | 78 | for i in range(1,train_step): 79 | 80 | image_batch,label_batch,roi_batch,landmark_batch=sess.run([images,labels,rois,landmarks]) 81 | 82 | sess.run(opt,feed_dict={image:image_batch,label:label_batch,roi:roi_batch,landmark:landmark_batch}) 83 | if(i%100==0): 84 | summary=sess.run(merged,feed_dict={image:image_batch,label:label_batch,roi:roi_batch,landmark:landmark_batch}) 85 | writer_train.add_summary(summary,i) 86 | if(i%1000==0): 87 | print('次数',i) 88 | print('train_accuracy',sess.run(train_accuracy,feed_dict={image:image_batch,label:label_batch,roi:roi_batch,landmark:landmark_batch})) 89 | print('truth_accuracy',sess.run(truth_accuracy,feed_dict={image:image_batch,label:label_batch,roi:roi_batch,landmark:landmark_batch})) 90 | print('false_accuracy',sess.run(false_accuracy,feed_dict={image:image_batch,label:label_batch,roi:roi_batch,landmark:landmark_batch})) 91 | print('loss',sess.run(loss,{image:image_batch,label:label_batch,roi:roi_batch,landmark:landmark_batch})) 92 | print('_label_los',sess.run(_label_los,{image:image_batch,label:label_batch,roi:roi_batch,landmark:landmark_batch})) 93 | print('_box_los',sess.run(_box_los,{image:image_batch,label:label_batch,roi:roi_batch,landmark:landmark_batch})) 94 | print('_landmark_los',sess.run(_landmark_los,{image:image_batch,label:label_batch,roi:roi_batch,landmark:landmark_batch})) 95 | print('time',time.time()-begin) 96 | if(i%10000==0): 97 | saver.save(sess,os.path.join(base_dir,"model/%s/%s.ckpt"%(model_name,model_name)),global_step=i) 98 | except tf.errors.OutOfRangeError: 99 | print("finished") 100 | finally: 101 | coord.request_stop() 102 | writer_train.close() 103 | coord.join(threads) 104 | 105 | def main(model): 106 | 107 | with tf.name_scope('input'): 108 | image=tf.placeholder(tf.float32,[batch,img_size,img_size,3],name='image') 109 | label=tf.placeholder(tf.int32,[batch],name='label') 110 | roi=tf.placeholder(tf.float32,[batch,4],name='roi') 111 | landmark = tf.placeholder(tf.float32,[batch,10],name='landmark') 112 | 113 | train(image,label,roi,landmark,model,model_name) 114 | 115 | if __name__=='__main__': 116 | 117 | parser=arg_parse() 118 | base_dir=parser.base_dir 119 | img_size=parser.img_size 120 | batch_size=parser.batch_size 121 | batch=parser.batch 122 | train_step=parser.train_step 123 | learning_rate=parser.learning_rate 124 | model_name=parser.model_name 125 | 126 | #base_dir="/home/dell/Desktop/prepared_data" 127 | #img_size=48 128 | #batch=448 129 | #batch_size=[192,64,64,128] 130 | #model_name="Onet_model" 131 | #train_step=100001 132 | #learning_rate=0.001 133 | 134 | addr=[os.path.join(base_dir,"DATA/%d/neg_%d_train.tfrecords"%(img_size,img_size)), 135 | os.path.join(base_dir,"DATA/%d/pos_%d_train.tfrecords"%(img_size,img_size)), 136 | os.path.join(base_dir,"DATA/%d/par_%d_train.tfrecords"%(img_size,img_size)), 137 | os.path.join(base_dir,"DATA/%d/land_%d_train.tfrecords"%(img_size,img_size))] 138 | 139 | save_model_path=os.path.join(base_dir,"model/%s"%(model_name)) 140 | 141 | if not os.path.exists(save_model_path): 142 | os.makedirs(save_model_path) 143 | 144 | if(model_name=="Onet_model"): 145 | ratio=[1,0.5,1] 146 | model=Onet_model 147 | else: 148 | ratio=[1,0.5,0.5] 149 | if(model_name=="Rnet_model"): 150 | model=Rnet_model 151 | else: model=Pnet_model 152 | 153 | begin=time.time() 154 | main(model) 155 | 156 | # tensorboard --logdir=/home/dell/Desktop/prepared_data/model/Onet_model/ -------------------------------------------------------------------------------- /version 2.0/MTCNN code/train/train_tool.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | @author: friedhelm 4 | 5 | """ 6 | import tensorflow as tf 7 | 8 | def label_los(pre_label,act_label): 9 | 10 | ratio=tf.constant(0.7) 11 | zeros=tf.zeros_like(act_label,dtype=tf.int32) 12 | valid_label=tf.where(tf.less(act_label,0),zeros,act_label) 13 | 14 | column_num=tf.shape(pre_label,out_type=tf.int32)[0] 15 | pre_label=tf.squeeze(tf.reshape(pre_label,(1,-1))) 16 | column=tf.range(0,column_num)*2 17 | column_to_stay=column+valid_label 18 | 19 | pre_label=tf.squeeze(tf.gather(pre_label,column_to_stay)) 20 | loss = -tf.log(pre_label+1e-10) 21 | ones=tf.ones_like(act_label,dtype=tf.float32) 22 | zero=tf.zeros_like(act_label,dtype=tf.float32) 23 | valid_colunm = tf.where(act_label < zeros,zero,ones) 24 | 25 | num_column=tf.reduce_sum(valid_colunm) 26 | num=tf.cast(num_column*ratio,dtype=tf.int32) 27 | loss=tf.multiply(loss,valid_colunm,'label_los') 28 | loss,_=tf.nn.top_k(loss,num) 29 | 30 | return tf.reduce_mean(loss) 31 | 32 | 33 | def roi_los(label,pre_box,act_box) : 34 | 35 | zeros=tf.zeros_like(label,dtype=tf.float32) 36 | ones=tf.ones_like(label,dtype=tf.float32) 37 | valid_label=tf.where(tf.equal(abs(label),1),ones,zeros) 38 | loss=tf.reduce_sum(tf.square(act_box-pre_box),axis=1) 39 | loss=tf.multiply(loss,valid_label,'roi_los') 40 | return tf.reduce_mean(loss) 41 | 42 | 43 | def landmark_los(label,pre_landmark,act_landmark): 44 | 45 | zeros=tf.zeros_like(label,dtype=tf.float32) 46 | ones = tf.ones_like(label,dtype=tf.float32) 47 | valid_label=tf.where(tf.equal(label,-2),ones,zeros) 48 | loss=tf.reduce_sum(tf.square(act_landmark-pre_landmark),axis=1) 49 | loss=tf.multiply(loss,valid_label,'landmark_los') 50 | return tf.reduce_mean(loss) 51 | 52 | 53 | def cal_accuracy(cls_prob,label): 54 | 55 | pred = tf.argmax(cls_prob,axis=1) 56 | label_int = tf.cast(label,tf.int64) 57 | cond = tf.where(tf.greater_equal(label_int,0)) 58 | picked = tf.squeeze(cond) 59 | label_picked = tf.gather(label_int,picked) 60 | pred_picked = tf.gather(pred,picked) 61 | accuracy_op = tf.reduce_mean(tf.cast(tf.equal(label_picked,pred_picked),tf.float32)) 62 | 63 | idx=tf.where(tf.greater(label_picked,0)) 64 | label_picked_true = tf.gather(label_int,idx) 65 | pred_picked_true = tf.gather(pred,idx) 66 | accuracy_true=tf.reduce_mean(tf.cast(tf.equal(label_picked_true,pred_picked_true),tf.float32)) 67 | 68 | idx=tf.where(tf.equal(label_picked,0)) 69 | label_picked_false = tf.gather(label_int,idx) 70 | pred_picked_false = tf.gather(pred,idx) 71 | accuracy_false=tf.reduce_mean(tf.cast(tf.equal(label_picked_false,pred_picked_false),tf.float32)) 72 | 73 | return accuracy_op,accuracy_true,accuracy_false -------------------------------------------------------------------------------- /version 2.0/README.md: -------------------------------------------------------------------------------- 1 | # version 2.0更新文档 2 | 3 | ## 更新原因 4 | 5 | * 1、加速MTCNN运行速度; 6 | * 2、修补若干致命bug; 7 | * 3、增强MTCNN鲁棒性; 8 | 9 | ## 更新概要 10 | 11 | * 1、废除滑窗法; 12 | * 2、MTCNN_detector下引入convert_to_square、pad、generate_box函数,加速且增强MTCNN鲁棒性; 13 | * 3、修复linux下路径报错bug、修复landmark镜像bug、关键点计算错误bug、修复fc正则化bug; 14 | 15 | ## 更新细节 16 | 17 | * 1、修复Detector在Linux系统下路径报错的bug; 18 | * 2、取消MTCNN_detector.detect_single_face 内显示单个网络预测时间; 19 | * 3、MTCNN_detector.calibrate_box加入参量model_name,取消box限制条件; 20 | * 4、Pnet每个scale中加入NMS,阈值0.5; 21 | * 5、引入入pad函数,修复因box越界导致边界人脸漏识别问题,越界则直接调整到边界; 22 | * 6、修改detect_P/R/Onet的空返回值为[]; 23 | * 7、引入convert_to_square 函数,去重复人脸; 24 | * 8、引入bounding_box函数,修改Detector滑窗法为矩阵法; 25 | * 9、修改Detector预测landmark通道; 26 | * 10、在MTCNN_detector初始化时初始化Detector; 27 | * 11、修复关键点镜像计算错误的bug; 28 | * 12、修复fc正则化loss图加载错误的bug; 29 | * 13、修复Detector中,Rnet与Onet对未知batch的鲁棒性; 30 | 31 | ## 更新结果 32 | 33 | * 1、MTCNN 平均预测时间提高约6倍以上; 34 | * 2、对困难样本鲁棒性提升,landmark预测效果提升; 35 | 36 | ## 未来更新 37 | 38 | * 1、进一步提升MTCNN运行速度,提升准确性; 39 | -------------------------------------------------------------------------------- /version 2.0/model/Onet_model/Onet_model.ckpt-40000.data-00000-of-00001: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 2.0/model/Onet_model/Onet_model.ckpt-40000.data-00000-of-00001 -------------------------------------------------------------------------------- /version 2.0/model/Onet_model/Onet_model.ckpt-40000.index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 2.0/model/Onet_model/Onet_model.ckpt-40000.index -------------------------------------------------------------------------------- /version 2.0/model/Onet_model/Onet_model.ckpt-40000.meta: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 2.0/model/Onet_model/Onet_model.ckpt-40000.meta -------------------------------------------------------------------------------- /version 2.0/model/Onet_model/checkpoint: -------------------------------------------------------------------------------- 1 | model_checkpoint_path: "/home/dell/Desktop/prepared_data/model/Onet_model/Onet_model.ckpt-80000" 2 | all_model_checkpoint_paths: "/home/dell/Desktop/prepared_data/model/Onet_model/Onet_model.ckpt-10000" 3 | all_model_checkpoint_paths: "/home/dell/Desktop/prepared_data/model/Onet_model/Onet_model.ckpt-20000" 4 | all_model_checkpoint_paths: "/home/dell/Desktop/prepared_data/model/Onet_model/Onet_model.ckpt-30000" 5 | all_model_checkpoint_paths: "/home/dell/Desktop/prepared_data/model/Onet_model/Onet_model.ckpt-40000" 6 | all_model_checkpoint_paths: "/home/dell/Desktop/prepared_data/model/Onet_model/Onet_model.ckpt-50000" 7 | all_model_checkpoint_paths: "/home/dell/Desktop/prepared_data/model/Onet_model/Onet_model.ckpt-60000" 8 | all_model_checkpoint_paths: "/home/dell/Desktop/prepared_data/model/Onet_model/Onet_model.ckpt-70000" 9 | all_model_checkpoint_paths: "/home/dell/Desktop/prepared_data/model/Onet_model/Onet_model.ckpt-80000" 10 | -------------------------------------------------------------------------------- /version 2.0/model/Onet_model/events.out.tfevents.1552807428.XABC-T7910: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 2.0/model/Onet_model/events.out.tfevents.1552807428.XABC-T7910 -------------------------------------------------------------------------------- /version 2.0/model/Pnet_model/Pnet_model.ckpt-20000.data-00000-of-00001: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 2.0/model/Pnet_model/Pnet_model.ckpt-20000.data-00000-of-00001 -------------------------------------------------------------------------------- /version 2.0/model/Pnet_model/Pnet_model.ckpt-20000.index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 2.0/model/Pnet_model/Pnet_model.ckpt-20000.index -------------------------------------------------------------------------------- /version 2.0/model/Pnet_model/Pnet_model.ckpt-20000.meta: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 2.0/model/Pnet_model/Pnet_model.ckpt-20000.meta -------------------------------------------------------------------------------- /version 2.0/model/Pnet_model/checkpoint: -------------------------------------------------------------------------------- 1 | model_checkpoint_path: "/home/dell/Desktop/prepared_data/model/Pnet_model/Pnet_model.ckpt-50000" 2 | all_model_checkpoint_paths: "/home/dell/Desktop/prepared_data/model/Pnet_model/Pnet_model.ckpt-10000" 3 | all_model_checkpoint_paths: "/home/dell/Desktop/prepared_data/model/Pnet_model/Pnet_model.ckpt-20000" 4 | all_model_checkpoint_paths: "/home/dell/Desktop/prepared_data/model/Pnet_model/Pnet_model.ckpt-30000" 5 | all_model_checkpoint_paths: "/home/dell/Desktop/prepared_data/model/Pnet_model/Pnet_model.ckpt-40000" 6 | all_model_checkpoint_paths: "/home/dell/Desktop/prepared_data/model/Pnet_model/Pnet_model.ckpt-50000" 7 | -------------------------------------------------------------------------------- /version 2.0/model/Pnet_model/events.out.tfevents.1552552955.XABC-T7910: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 2.0/model/Pnet_model/events.out.tfevents.1552552955.XABC-T7910 -------------------------------------------------------------------------------- /version 2.0/model/Rnet_model/Rnet_model.ckpt-40000.data-00000-of-00001: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 2.0/model/Rnet_model/Rnet_model.ckpt-40000.data-00000-of-00001 -------------------------------------------------------------------------------- /version 2.0/model/Rnet_model/Rnet_model.ckpt-40000.index: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 2.0/model/Rnet_model/Rnet_model.ckpt-40000.index -------------------------------------------------------------------------------- /version 2.0/model/Rnet_model/Rnet_model.ckpt-40000.meta: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 2.0/model/Rnet_model/Rnet_model.ckpt-40000.meta -------------------------------------------------------------------------------- /version 2.0/model/Rnet_model/checkpoint: -------------------------------------------------------------------------------- 1 | model_checkpoint_path: "/home/dell/Desktop/prepared_data/model/Rnet_model/Rnet_model.ckpt-50000" 2 | all_model_checkpoint_paths: "/home/dell/Desktop/prepared_data/model/Rnet_model/Rnet_model.ckpt-10000" 3 | all_model_checkpoint_paths: "/home/dell/Desktop/prepared_data/model/Rnet_model/Rnet_model.ckpt-20000" 4 | all_model_checkpoint_paths: "/home/dell/Desktop/prepared_data/model/Rnet_model/Rnet_model.ckpt-30000" 5 | all_model_checkpoint_paths: "/home/dell/Desktop/prepared_data/model/Rnet_model/Rnet_model.ckpt-40000" 6 | all_model_checkpoint_paths: "/home/dell/Desktop/prepared_data/model/Rnet_model/Rnet_model.ckpt-50000" 7 | -------------------------------------------------------------------------------- /version 2.0/model/Rnet_model/events.out.tfevents.1552708237.XABC-T7910: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 2.0/model/Rnet_model/events.out.tfevents.1552708237.XABC-T7910 -------------------------------------------------------------------------------- /version 2.0/result/MTCNN_test_0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 2.0/result/MTCNN_test_0.jpg -------------------------------------------------------------------------------- /version 2.0/result/MTCNN_test_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 2.0/result/MTCNN_test_1.jpg -------------------------------------------------------------------------------- /version 2.0/result/MTCNN_test_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/friedhelm739/MTCNN-tensorflow/697258649a945fb1f53440b728f86b14c7ba4a47/version 2.0/result/MTCNN_test_2.jpg --------------------------------------------------------------------------------