我一直在研究人脸识别考勤管理系统。我从头开始构建了管道,但是最后,脚本识别出10个类中的错误面孔。
我已经使用Tensorflow和Python实现了以下管道。

  • 捕获图像,调整大小,使用dlib的形状预测器将其对齐,并将它们存储在命名文件夹中,以便以后进行比较时进行识别。
  • 将图像腌制到data.pickle文件中,以便稍后反序列化。
  • 使用OpenCV实施MTCNN算法以检测网络摄像头捕获的帧中的面部
  • 将这些帧传递到Facenet网络中以创建128-D嵌入,并相应地与pickle数据库中存在的嵌入进行比较。

  • 下面给出的是运行第3步和第4步的主文件:
    from keras import backend as K
    import time
    from multiprocessing.dummy import Pool
    K.set_image_data_format('channels_first')
    import cv2
    import os
    import glob
    import numpy as np
    from numpy import genfromtxt
    import tensorflow as tf
    from keras.models import load_model
    from fr_utils import *
    from inception_blocks_v2 import *
    from mtcnn.mtcnn import MTCNN
    import dlib
    from imutils import face_utils
    import imutils
    import pickle
    from sklearn.neighbors import KNeighborsClassifier
    from sklearn.model_selection import train_test_split
    
    
    FRmodel = load_model('face-rec_Google.h5')
    # detector = dlib.get_frontal_face_detector()
    detector = MTCNN()
    # FRmodel = faceRecoModel(input_shape=(3, 96, 96))
    #
    # # detector = dlib.get_frontal_face_detector()
    # # predictor = dlib.shape_predictor("shape_predictor_68_face_landmarks.dat")
    # def triplet_loss(y_true, y_pred, alpha = 0.3):
    #     """
    #     Implementation of the triplet loss as defined by formula (3)
    #
    #     Arguments:
    #     y_pred -- python list containing three objects:
    #             anchor -- the encodings for the anchor images, of shape (None, 128)
    #             positive -- the encodings for the positive images, of shape (None, 128)
    #             negative -- the encodings for the negative images, of shape (None, 128)
    #
    #     Returns:
    #     loss -- real number, value of the loss
    #     """
    #
    #     anchor, positive, negative = y_pred[0], y_pred[1], y_pred[2]
    #
    #     pos_dist = tf.reduce_sum(tf.square(tf.subtract(anchor, positive)), axis=-1)
    #     neg_dist = tf.reduce_sum(tf.square(tf.subtract(anchor, negative)), axis=-1)
    #     basic_loss = tf.add(tf.subtract(pos_dist, neg_dist), alpha)
    #     loss = tf.reduce_sum(tf.maximum(basic_loss, 0.0))
    #
    #     return loss
    #
    # FRmodel.compile(optimizer = 'adam', loss = triplet_loss, metrics = ['accuracy'])
    # load_weights_from_FaceNet(FRmodel)
    def ret_model():
        return FRmodel
    
    def prepare_database():
        pickle_in = open("data.pickle","rb")
        database =  pickle.load(pickle_in)
        return database
    
    def unpickle_something(pickle_file):
        pickle_in = open(pickle_file,"rb")
        unpickled_file =  pickle.load(pickle_in)
        return unpickled_file
    
    
    def webcam_face_recognizer(database):
    
        cv2.namedWindow("preview")
        vc = cv2.VideoCapture(0)
    
        while vc.isOpened():
            ret, frame = vc.read()
            img_rgb = cv2.cvtColor(frame,cv2.COLOR_BGR2RGB)
            img = frame
            # We do not want to detect a new identity while the program is in the process of identifying another person
            img = process_frame(img,img)
    
            cv2.imshow("Preview", img)
            cv2.waitKey(1)
    
        vc.release()
    
    def process_frame(img, frame):
        """
        Determine whether the current frame contains the faces of people from our database
        """
        # rects = detector(img)
        rects = detector.detect_faces(img)
        # Loop through all the faces detected and determine whether or not they are in the database
        identities = []
        for (i,rect) in enumerate(rects):
            (x,y,w,h) = rect['box'][0],rect['box'][1],rect['box'][2],rect['box'][3]
            img = cv2.rectangle(frame,(x, y),(x+w, y+h),(255,0,0),2)
    
            identity = find_identity(frame, x-50, y-50, x+w+50, y+h+50)
            cv2.putText(img, identity,(10,500), cv2.FONT_HERSHEY_SIMPLEX , 4,(255,255,255),2,cv2.LINE_AA)
    
            if identity is not None:
                identities.append(identity)
    
        if identities != []:
            cv2.imwrite('example.png',img)
    
        return img
    
    def find_identity(frame, x,y,w,h):
        """
        Determine whether the face contained within the bounding box exists in our database
    
        x1,y1_____________
        |                 |
        |                 |
        |_________________x2,y2
    
        """
        height, width, channels = frame.shape
        # The padding is necessary since the OpenCV face detector creates the bounding box around the face and not the head
        part_image = frame[y:y+h, x:x+w]
    
        return who_is_it(part_image, database, FRmodel)
    
    def who_is_it(image, database, model):
    
        encoding = img_to_encoding(image, model)
    
    
        min_dist = 100
        # Loop over the database dictionary's names and encodings.
        for (name, db_enc) in database.items():
    
            # Compute L2 distance between the target "encoding" and the current "emb" from the database.
            dist = np.linalg.norm(db_enc.flatten() - encoding.flatten())
    
            print('distance for %s is %s' %(name, dist))
    
            # If this distance is less than the min_dist, then set min_dist to dist, and identity to name
            if dist < min_dist:
                min_dist = dist
                identity = name
    
            if min_dist >0.1:
                print('Unknown person')
            else:
                print(identity)
        return identity
    
    
    if __name__ == "__main__":
        database = prepare_database()
        webcam_face_recognizer(database)
    

    我在这里做错了什么?
    这里的FRmodel是经过facenet训练的模型

    最佳答案

    几点:

  • 我看不到输入到网络中的输入面部图像的大小,对齐和变白。
  • 您不能将50的固定边距添加到尺寸可变的面孔上。必须进行缩放,以使面部区域填充每个输入图像中几乎相同的区域。
  • 我不确定您使用的模型是什么,但是如果使用FaceNet,则您接受的匹配阈值0.1似乎很低。除非它是相同的精确图像(距离为0.0),或者与图库图像的差异很小,否则它将不接受任何匹配。
  • 09-07 10:46