from typing import List, Optional import numpy from facefusion import state_manager from facefusion.common_helper import get_first from facefusion.face_classifier import detect_gender_age from facefusion.face_detector import detect_faces, detect_rotated_faces from facefusion.face_helper import apply_nms, convert_to_face_landmark_5, estimate_face_angle, get_nms_threshold from facefusion.face_landmarker import detect_face_landmarks, estimate_face_landmark_68_5 from facefusion.face_recognizer import calc_embedding from facefusion.face_store import get_static_faces, set_static_faces from facefusion.typing import BoundingBox, Face, FaceLandmark5, FaceLandmarkSet, FaceScoreSet, Score, VisionFrame def create_faces(vision_frame : VisionFrame, bounding_boxes : List[BoundingBox], face_scores : List[Score], face_landmarks_5 : List[FaceLandmark5]) -> List[Face]: faces = [] nms_threshold = get_nms_threshold(state_manager.get_item('face_detector_model'), state_manager.get_item('face_detector_angles')) keep_indices = apply_nms(bounding_boxes, face_scores, state_manager.get_item('face_detector_score'), nms_threshold) for index in keep_indices: bounding_box = bounding_boxes[index] face_score = face_scores[index] face_landmark_5 = face_landmarks_5[index] face_landmark_5_68 = face_landmark_5 face_landmark_68_5 = estimate_face_landmark_68_5(face_landmark_5_68) face_landmark_68 = face_landmark_68_5 face_landmark_score_68 = 0.0 face_angle = estimate_face_angle(face_landmark_68_5) if state_manager.get_item('face_landmarker_score') > 0: face_landmark_68, face_landmark_score_68 = detect_face_landmarks(vision_frame, bounding_box, face_angle) if face_landmark_score_68 > state_manager.get_item('face_landmarker_score'): face_landmark_5_68 = convert_to_face_landmark_5(face_landmark_68) face_landmark_set : FaceLandmarkSet =\ { '5': face_landmark_5, '5/68': face_landmark_5_68, '68': face_landmark_68, '68/5': face_landmark_68_5 } face_score_set : FaceScoreSet =\ { 'detector': face_score, 'landmarker': face_landmark_score_68 } embedding, normed_embedding = calc_embedding(vision_frame, face_landmark_set.get('5/68')) gender, age = detect_gender_age(vision_frame, bounding_box) faces.append(Face( bounding_box = bounding_box, score_set = face_score_set, landmark_set = face_landmark_set, angle = face_angle, embedding = embedding, normed_embedding = normed_embedding, gender = gender, age = age )) return faces def get_one_face(faces : List[Face], position : int = 0) -> Optional[Face]: if faces: position = min(position, len(faces) - 1) return faces[position] return None def get_average_face(faces : List[Face]) -> Optional[Face]: embeddings = [] normed_embeddings = [] if faces: first_face = get_first(faces) for face in faces: embeddings.append(face.embedding) normed_embeddings.append(face.normed_embedding) return Face( bounding_box = first_face.bounding_box, score_set = first_face.score_set, landmark_set = first_face.landmark_set, angle = first_face.angle, embedding = numpy.mean(embeddings, axis = 0), normed_embedding = numpy.mean(normed_embeddings, axis = 0), gender = first_face.gender, age = first_face.age ) return None def get_many_faces(vision_frames : List[VisionFrame]) -> List[Face]: many_faces : List[Face] = [] for vision_frame in vision_frames: if numpy.any(vision_frame): static_faces = get_static_faces(vision_frame) if static_faces: many_faces.extend(static_faces) else: all_bounding_boxes = [] all_face_scores = [] all_face_landmarks_5 = [] for face_detector_angle in state_manager.get_item('face_detector_angles'): if face_detector_angle == 0: bounding_boxes, face_scores, face_landmarks_5 = detect_faces(vision_frame) else: bounding_boxes, face_scores, face_landmarks_5 = detect_rotated_faces(vision_frame, face_detector_angle) all_bounding_boxes.extend(bounding_boxes) all_face_scores.extend(face_scores) all_face_landmarks_5.extend(face_landmarks_5) if all_bounding_boxes and all_face_scores and all_face_landmarks_5 and state_manager.get_item('face_detector_score') > 0: faces = create_faces(vision_frame, all_bounding_boxes, all_face_scores, all_face_landmarks_5) if faces: many_faces.extend(faces) set_static_faces(vision_frame, faces) return many_faces