pipeline_test.py 6.72 KB
import os
import numpy as np
import MNN
import cv2
import logging
from skimage import transform as trans

from src.face_landmark import Landmark_Detector
from src.face_detecter import Face_Detector
from src.face_id import Face_Recognizer


def preprocess(image, landmarks):
    src = np.array([[38.2946, 51.6963],
                    [73.5318, 51.6963],
                    [56.0252, 71.7366],
                    [41.5493, 92.3655],
                    [70.7299, 92.3655] ], dtype=np.float32)

    landmarks = np.array(landmarks)
    dst = landmarks.astype(np.float32)
    tform = trans.SimilarityTransform()
    tform.estimate(dst, src)
    M = tform.params[0:2,:]
    warped = cv2.warpAffine(image, M, (112, 112), borderValue=0.0)
    return warped

def get_face(image, bbox):
    face_area = image[bbox[1]:bbox[3], bbox[0]:bbox[2], ]
    norm_image = cv2.cvtColor(face_area, cv2.COLOR_BGR2RGB).astype(np.float32)
    norm_image = cv2.resize(norm_image, (112, 112))
    return norm_image

def get_norm_face(image, landmarks):
    norm_image = preprocess(image, landmarks)
    # norm_image = cv2.cvtColor(norm_image, cv2.COLOR_BGR2RGB).astype(np.float32)
    # norm_image = cv2.resize(norm_image, (112, 112))
    # norm_image = norm_image.transpose((2, 0, 1))
    # norm_image = norm_image.transpose((1,2,0))
    # norm_image = cv2.resize(norm_image, (112, 112))[:,:,::-1]
    return norm_image

def landmarks_process(all_landmarks, all_bboxes):
    processed_landmarks = []
    for l, landmarks in enumerate(all_landmarks):
        bbox = all_bboxes[l]
        face_w, face_h = bbox[3] - bbox[1], bbox[2] - bbox[0]
        w_r, h_r = face_w / 112, face_h / 112
        point_0 = ((landmarks[0][0] - bbox[0])/w_r, (landmarks[0][1] - bbox[1])/h_r) 
        point_1 = ((landmarks[1][0] - bbox[0])/w_r, (landmarks[1][1] - bbox[1])/h_r)
        point_2 = ((landmarks[2][0] - bbox[0])/w_r, (landmarks[2][1] - bbox[1])/h_r)
        point_3 = ((landmarks[3][0] - bbox[0])/w_r, (landmarks[3][1] - bbox[1])/h_r)
        point_4 = ((landmarks[4][0] - bbox[0])/w_r, (landmarks[4][1] - bbox[1])/h_r)
       
        processed_landmarks.append([point_0, point_1, point_2, point_3, point_4])

    return processed_landmarks


det_face_model_path = r'models/det_face_retina_mnn_1.0.0_v0.1.1.mnn'
# det_face_model_path = "/home/jwq/PycharmProjects/situ/src/face_det/Pytorch_Retinaface/FaceDetectorx1.mnn"
# reg_face_id_model_path = r'/home/jwq/PycharmProjects/situ/src/face_id/insightface/recognition/arcface_torch/work_dirs/ms1mv3_r18/ms1mv3_r18_0.96200/ms1mv3_r18.mnn'
reg_face_id_model_path = r'models/cls_face_mnn_1.0.0_v0.0.3.mnn'
# reg_face_id_model_path = "/home/jwq/PycharmProjects/situ/src/mobile_face_recognize/models/speak_det.mnn"
det_face_landmark_path = r'models/det_landmarks_106_v0.0.1.mnn'

image_dir = r'/data2/face_id/situ_other/pipeline_test/'
image_list_txt_path = r'/data2/face_id/situ_other/test2.txt'

face_detector = Face_Detector(det_face_model_path)
face_recognizer = Face_Recognizer(reg_face_id_model_path)
face_landmark_detector = Landmark_Detector(det_face_landmark_path)

image_list_txt = open(image_list_txt_path, 'r')
image_list_txt_lines = image_list_txt.readlines()

hit = 0.01
hit_pos = 0.01
pre_pos = 0.01
pre_all = 0.01
positive_num = 0.01
for image_list_txt_line in image_list_txt_lines:
    arr = image_list_txt_line.strip().split(' ')
    label = arr[-1]
    
    pre_all += 1
    if label == '1':
        positive_num += 1    

    id_image_name_arr = arr[0].split('/')
    id_image_name = id_image_name_arr[-1]
    id_image_name = id_image_name[2:]
    id_image_dir = id_image_name_arr[-2]
    id_image_path = os.path.join(image_dir, id_image_dir, id_image_name)

    life_image_name_arr = arr[1].split('/')
    life_image_name = life_image_name_arr[-1]
    life_image_name = life_image_name[2:]
    life_image_dir = life_image_name_arr[-2]    
    life_image_path = os.path.join(image_dir, life_image_dir, life_image_name)

    face_det_thr = 0.5
    face_recongnize_thr = 0.15

    id_image = cv2.imread(id_image_path)
    life_image = cv2.imread(life_image_path)

    id_face_bboxes, _, id_max_idx = face_detector.detect(id_image, face_det_thr)
    life_face_bboxes, _, life_max_idx = face_detector.detect(life_image, face_det_thr)
    if len(id_face_bboxes) == 0 or len(life_face_bboxes) == 0:
        continue

    # id_faces = []
    # for id_bbox in id_face_bboxes:
    #     id_face = id_image[id_bbox[1]:id_bbox[3], id_bbox[0]:id_bbox[2], ]
    #     id_face = cv2.resize(id_face, (112, 112))
    #     id_faces.append(id_face)
    
    id_landmark, id_face = face_landmark_detector.detect(id_image, id_face_bboxes[id_max_idx])
    id_landmark = [id_landmark[104], id_landmark[105], id_landmark[46], id_landmark[84], id_landmark[90]]
    id_norm_image = get_norm_face(id_face, id_landmark)
    # cv2.imwrite('results/{}'.format(id_image_name), id_norm_image)
    # norm_images = [id_faces[id_max_idx]]
    norm_images = [id_norm_image]

    # life_faces = []
    # for life_bbox in life_face_bboxes:
    #     life_face = life_image[life_bbox[1]:life_bbox[3], life_bbox[0]:life_bbox[2], ]
    #     life_face = cv2.resize(life_face, (112, 112))
    #     life_faces.append(life_face)
        
    for f, life_face_bbox in enumerate(life_face_bboxes):
    #     life_norm_image = get_norm_face(life_faces[f], life_face_landmarks[f])
        life_landmark, life_face = face_landmark_detector.detect(life_image, life_face_bbox)
        life_landmark = [life_landmark[104], life_landmark[105], life_landmark[46], life_landmark[84], life_landmark[90]]
        life_norm_image = get_norm_face(life_face, life_landmark)
    #     cv2.imwrite('results/{}_{}'.format(f, life_image_name), life_norm_image)
    #     norm_images.append(life_faces[f])
        norm_images.append(life_norm_image)

    # id_face_landmarks = landmarks_process(id_face_landmarks, id_face_bboxes)
    # life_face_landmarks = landmarks_process(life_face_landmarks, life_face_bboxes)

    embeddings = face_recognizer.recognize(norm_images)
    gallery_vector = np.mat(embeddings[0])
    res = False
    sim = 0
    for p in range(1, len(embeddings)):
        compare_vector = np.mat(embeddings[p])

        dot = np.sum(np.multiply(gallery_vector, compare_vector), axis=1)
        norm = np.linalg.norm(gallery_vector, axis=1) * np.linalg.norm(compare_vector, axis=1)
        dist_1 = dot / norm

        sim = dist_1.tolist()
        sim = sim[0][0]

        if sim > face_recongnize_thr: res = True
        print('label: {}, sim {} : {}'.format(label, p, sim))
   
    if res:
        if label == '1':
            hit_pos += 1  
            hit += 1        
        pre_pos += 1
    else:
        if label == '0':
            hit += 1

print('precision:{}'.format(hit_pos/pre_pos)) 
print('recall:{}'.format(hit_pos/positive_num))
print('accuracy:{}'.format(hit/pre_all))