video-face-swap / DeepFakeAI /face_analyser.py
tonyassi's picture
Upload 96 files
9ae3d29
raw
history blame
3.5 kB
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))