Spaces:
Sleeping
Sleeping
import threading | |
from typing import Any, Optional, List | |
import insightface | |
import numpy | |
import DeepFakeAI.globals | |
from DeepFakeAI.typing import Frame, Face, FaceAnalyserDirection, FaceAnalyserAge, FaceAnalyserGender | |
FACE_ANALYSER = None | |
THREAD_LOCK = threading.Lock() | |
def get_face_analyser() -> Any: | |
global FACE_ANALYSER | |
with THREAD_LOCK: | |
if FACE_ANALYSER is None: | |
FACE_ANALYSER = insightface.app.FaceAnalysis(name = 'buffalo_l', providers = DeepFakeAI.globals.execution_providers) | |
FACE_ANALYSER.prepare(ctx_id = 0) | |
return FACE_ANALYSER | |
def clear_face_analyser() -> Any: | |
global FACE_ANALYSER | |
FACE_ANALYSER = None | |
def get_one_face(frame : Frame, position : int = 0) -> Optional[Face]: | |
many_faces = get_many_faces(frame) | |
if many_faces: | |
try: | |
return many_faces[position] | |
except IndexError: | |
return many_faces[-1] | |
return None | |
def get_many_faces(frame : Frame) -> List[Face]: | |
try: | |
faces = get_face_analyser().get(frame) | |
if DeepFakeAI.globals.face_analyser_direction: | |
faces = sort_by_direction(faces, DeepFakeAI.globals.face_analyser_direction) | |
if DeepFakeAI.globals.face_analyser_age: | |
faces = filter_by_age(faces, DeepFakeAI.globals.face_analyser_age) | |
if DeepFakeAI.globals.face_analyser_gender: | |
faces = filter_by_gender(faces, DeepFakeAI.globals.face_analyser_gender) | |
return faces | |
except (AttributeError, ValueError): | |
return [] | |
def find_similar_faces(frame : Frame, reference_face : Face, face_distance : float) -> List[Face]: | |
many_faces = get_many_faces(frame) | |
similar_faces = [] | |
if many_faces: | |
for face in many_faces: | |
if hasattr(face, 'normed_embedding') and hasattr(reference_face, 'normed_embedding'): | |
current_face_distance = numpy.sum(numpy.square(face.normed_embedding - reference_face.normed_embedding)) | |
if current_face_distance < face_distance: | |
similar_faces.append(face) | |
return similar_faces | |
def sort_by_direction(faces : List[Face], direction : FaceAnalyserDirection) -> List[Face]: | |
if direction == 'left-right': | |
return sorted(faces, key = lambda face: face['bbox'][0]) | |
if direction == 'right-left': | |
return sorted(faces, key = lambda face: face['bbox'][0], reverse = True) | |
if direction == 'top-bottom': | |
return sorted(faces, key = lambda face: face['bbox'][1]) | |
if direction == 'bottom-top': | |
return sorted(faces, key = lambda face: face['bbox'][1], reverse = True) | |
if direction == 'small-large': | |
return sorted(faces, key = lambda face: (face['bbox'][2] - face['bbox'][0]) * (face['bbox'][3] - face['bbox'][1])) | |
if direction == 'large-small': | |
return sorted(faces, key = lambda face: (face['bbox'][2] - face['bbox'][0]) * (face['bbox'][3] - face['bbox'][1]), reverse = True) | |
return faces | |
def filter_by_age(faces : List[Face], age : FaceAnalyserAge) -> List[Face]: | |
filter_faces = [] | |
for face in faces: | |
if face['age'] < 13 and age == 'child': | |
filter_faces.append(face) | |
elif face['age'] < 19 and age == 'teen': | |
filter_faces.append(face) | |
elif face['age'] < 60 and age == 'adult': | |
filter_faces.append(face) | |
elif face['age'] > 59 and age == 'senior': | |
filter_faces.append(face) | |
return filter_faces | |
def filter_by_gender(faces : List[Face], gender : FaceAnalyserGender) -> List[Face]: | |
filter_faces = [] | |
for face in faces: | |
if face['gender'] == 1 and gender == 'male': | |
filter_faces.append(face) | |
if face['gender'] == 0 and gender == 'female': | |
filter_faces.append(face) | |
return filter_faces | |
def get_faces_total(frame : Frame) -> int: | |
return len(get_many_faces(frame)) | |