上一篇文章中搭建了facenet人脸识别环境,并且运行compare.py比较两张人脸的欧氏距离,本文介绍实时人脸识别的方法。首先收集需要识别的人脸,然后通过opencv读取摄像头数据,计算两张人脸的欧式距离。
收集人脸
通过手机或者摄像头拍摄人像照片,要求一张照片只有一张脸,最好正面照,然后通过mtcnn识别人脸并将人脸裁剪出来。数据集的格式参照lfw,即文件夹名为人名(label),文件夹包含该label的人脸
| 1 2 3 4 5 6 7 | $ ls data/faces Huang_Zhen/ Li_Long/ Zhang_Wenjie/ # mtcnn performs face alignment and stores face thumbnails $ python src/align/align_dataset_mtcnn.py --image_size 160 --margin 32 data/faces data/faces_160 # 将 data/faces_160 目录下保存的人脸拷贝到 data/input_faces目录 $ ls data/input_faces/ Huang_Zhen.png Li_Long.png Zhang_Wenjie.png | 
读取摄像头
使用python-opencv读取摄像头frame
| 1 2 3 4 5 6 7 8 | # open local camera
capture = cv2.VideoCapture(0)
while True:
    ret, frame = capture.read()
    if not ret:
    	break
    rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) | 
计算人脸向量
输入人脸的路径,返回该人脸的向量embedding
| 1 2 3 4 5 6 7 8 9 10 | def generate_image_embedding(self, images):
    # Get input and output tensors
    images_placeholder = tf.get_default_graph().get_tensor_by_name("input:0")
    embeddings = tf.get_default_graph().get_tensor_by_name("embeddings:0")
    phase_train_placeholder = tf.get_default_graph().get_tensor_by_name("phase_train:0")
    stack_images = np.stack(images)
    feed_dict = {images_placeholder: stack_images,
                 phase_train_placeholder: False}
    return self.sess.run(embeddings, feed_dict=feed_dict) | 
计算欧式距离
| 1 2 3 4 5 6 7 8 | def compare(self, face, compare_emb, face_labels):
    dist_list = []
    for i in range(len(compare_emb)):
        dist = np.sqrt(np.sum(np.square(np.subtract(face.embedding, compare_emb[i, :]))))
        dist_list.append(dist)
    min_dist = min(dist_list)
    index = dist_list.index(min_dist)
    return face_labels[index] |