mirror of
https://github.com/serengil/deepface.git
synced 2025-06-06 11:35:21 +00:00
Merge pull request #1296 from serengil/feat-task-0408-managing-global-variables
manage global variables in single place
This commit is contained in:
commit
62055d09d2
@ -48,17 +48,23 @@ if tf_version == 2:
|
||||
folder_utils.initialize_folder()
|
||||
|
||||
|
||||
def build_model(model_name: str) -> Any:
|
||||
def build_model(model_name: str, task: str = "facial_recognition") -> Any:
|
||||
"""
|
||||
This function builds a deepface model
|
||||
This function builds a pre-trained model
|
||||
Args:
|
||||
model_name (string): face recognition or facial attribute model
|
||||
VGG-Face, Facenet, OpenFace, DeepFace, DeepID for face recognition
|
||||
Age, Gender, Emotion, Race for facial attributes
|
||||
model_name (str): model identifier
|
||||
- VGG-Face, Facenet, Facenet512, OpenFace, DeepFace, DeepID, Dlib,
|
||||
ArcFace, SFace, GhostFaceNet for face recognition
|
||||
- Age, Gender, Emotion, Race for facial attributes
|
||||
- opencv, mtcnn, ssd, dlib, retinaface, mediapipe, yolov8, yunet,
|
||||
fastmtcnn or centerface for face detectors
|
||||
- Fasnet for spoofing
|
||||
task (str): facial_recognition, facial_attribute, face_detector, spoofing
|
||||
default is facial_recognition
|
||||
Returns:
|
||||
built_model
|
||||
"""
|
||||
return modeling.build_model(model_name=model_name)
|
||||
return modeling.build_model(task=task, model_name=model_name)
|
||||
|
||||
|
||||
def verify(
|
||||
|
@ -1 +1 @@
|
||||
__version__ = "0.0.92"
|
||||
__version__ = "0.0.93"
|
||||
|
@ -1,64 +1,13 @@
|
||||
from typing import Any, List, Tuple
|
||||
from typing import List, Tuple
|
||||
import numpy as np
|
||||
import cv2
|
||||
from deepface.modules import detection
|
||||
from deepface.modules import detection, modeling
|
||||
from deepface.models.Detector import Detector, DetectedFace, FacialAreaRegion
|
||||
from deepface.detectors import (
|
||||
FastMtCnn,
|
||||
MediaPipe,
|
||||
MtCnn,
|
||||
OpenCv,
|
||||
Dlib,
|
||||
RetinaFace,
|
||||
Ssd,
|
||||
Yolo,
|
||||
YuNet,
|
||||
CenterFace,
|
||||
)
|
||||
from deepface.commons.logger import Logger
|
||||
|
||||
logger = Logger()
|
||||
|
||||
|
||||
def build_model(detector_backend: str) -> Any:
|
||||
"""
|
||||
Build a face detector model
|
||||
Args:
|
||||
detector_backend (str): backend detector name
|
||||
Returns:
|
||||
built detector (Any)
|
||||
"""
|
||||
global face_detector_obj # singleton design pattern
|
||||
|
||||
backends = {
|
||||
"opencv": OpenCv.OpenCvClient,
|
||||
"mtcnn": MtCnn.MtCnnClient,
|
||||
"ssd": Ssd.SsdClient,
|
||||
"dlib": Dlib.DlibClient,
|
||||
"retinaface": RetinaFace.RetinaFaceClient,
|
||||
"mediapipe": MediaPipe.MediaPipeClient,
|
||||
"yolov8": Yolo.YoloClient,
|
||||
"yunet": YuNet.YuNetClient,
|
||||
"fastmtcnn": FastMtCnn.FastMtCnnClient,
|
||||
"centerface": CenterFace.CenterFaceClient,
|
||||
}
|
||||
|
||||
if not "face_detector_obj" in globals():
|
||||
face_detector_obj = {}
|
||||
|
||||
built_models = list(face_detector_obj.keys())
|
||||
if detector_backend not in built_models:
|
||||
face_detector = backends.get(detector_backend)
|
||||
|
||||
if face_detector:
|
||||
face_detector = face_detector()
|
||||
face_detector_obj[detector_backend] = face_detector
|
||||
else:
|
||||
raise ValueError("invalid detector_backend passed - " + detector_backend)
|
||||
|
||||
return face_detector_obj[detector_backend]
|
||||
|
||||
|
||||
def detect_faces(
|
||||
detector_backend: str, img: np.ndarray, align: bool = True, expand_percentage: int = 0
|
||||
) -> List[DetectedFace]:
|
||||
@ -87,7 +36,9 @@ def detect_faces(
|
||||
"""
|
||||
height, width, _ = img.shape
|
||||
|
||||
face_detector: Detector = build_model(detector_backend)
|
||||
face_detector: Detector = modeling.build_model(
|
||||
task="face_detector", model_name=detector_backend
|
||||
)
|
||||
|
||||
# validate expand percentage score
|
||||
if expand_percentage < 0:
|
||||
|
@ -158,7 +158,9 @@ def analyze(
|
||||
pbar.set_description(f"Action: {action}")
|
||||
|
||||
if action == "emotion":
|
||||
emotion_predictions = modeling.build_model("Emotion").predict(img_content)
|
||||
emotion_predictions = modeling.build_model(
|
||||
task="facial_attribute", model_name="Emotion"
|
||||
).predict(img_content)
|
||||
sum_of_predictions = emotion_predictions.sum()
|
||||
|
||||
obj["emotion"] = {}
|
||||
@ -169,12 +171,16 @@ def analyze(
|
||||
obj["dominant_emotion"] = Emotion.labels[np.argmax(emotion_predictions)]
|
||||
|
||||
elif action == "age":
|
||||
apparent_age = modeling.build_model("Age").predict(img_content)
|
||||
apparent_age = modeling.build_model(
|
||||
task="facial_attribute", model_name="Age"
|
||||
).predict(img_content)
|
||||
# int cast is for exception - object of type 'float32' is not JSON serializable
|
||||
obj["age"] = int(apparent_age)
|
||||
|
||||
elif action == "gender":
|
||||
gender_predictions = modeling.build_model("Gender").predict(img_content)
|
||||
gender_predictions = modeling.build_model(
|
||||
task="facial_attribute", model_name="Gender"
|
||||
).predict(img_content)
|
||||
obj["gender"] = {}
|
||||
for i, gender_label in enumerate(Gender.labels):
|
||||
gender_prediction = 100 * gender_predictions[i]
|
||||
@ -183,7 +189,9 @@ def analyze(
|
||||
obj["dominant_gender"] = Gender.labels[np.argmax(gender_predictions)]
|
||||
|
||||
elif action == "race":
|
||||
race_predictions = modeling.build_model("Race").predict(img_content)
|
||||
race_predictions = modeling.build_model(
|
||||
task="facial_attribute", model_name="Race"
|
||||
).predict(img_content)
|
||||
sum_of_predictions = race_predictions.sum()
|
||||
|
||||
obj["race"] = {}
|
||||
|
@ -25,7 +25,7 @@ def extract_faces(
|
||||
align: bool = True,
|
||||
expand_percentage: int = 0,
|
||||
grayscale: bool = False,
|
||||
color_face: str = 'rgb',
|
||||
color_face: str = "rgb",
|
||||
normalize_face: bool = True,
|
||||
anti_spoofing: bool = False,
|
||||
) -> List[Dict[str, Any]]:
|
||||
@ -126,16 +126,14 @@ def extract_faces(
|
||||
logger.warn("Parameter grayscale is deprecated. Use color_face instead.")
|
||||
current_img = cv2.cvtColor(current_img, cv2.COLOR_BGR2GRAY)
|
||||
else:
|
||||
if color_face == 'rgb':
|
||||
if color_face == "rgb":
|
||||
current_img = current_img[:, :, ::-1]
|
||||
elif color_face == 'bgr':
|
||||
elif color_face == "bgr":
|
||||
pass # image is in BGR
|
||||
elif color_face == 'gray':
|
||||
elif color_face == "gray":
|
||||
current_img = cv2.cvtColor(current_img, cv2.COLOR_BGR2GRAY)
|
||||
else:
|
||||
raise ValueError(
|
||||
f"The color_face can be rgb, bgr or gray, but it is {color_face}."
|
||||
)
|
||||
raise ValueError(f"The color_face can be rgb, bgr or gray, but it is {color_face}.")
|
||||
|
||||
if normalize_face:
|
||||
current_img = current_img / 255 # normalize input in [0, 1]
|
||||
@ -159,7 +157,7 @@ def extract_faces(
|
||||
}
|
||||
|
||||
if anti_spoofing is True:
|
||||
antispoof_model = modeling.build_model(model_name="Fasnet")
|
||||
antispoof_model = modeling.build_model(task="spoofing", model_name="Fasnet")
|
||||
is_real, antispoof_score = antispoof_model.analyze(img=img, facial_area=(x, y, w, h))
|
||||
resp_obj["is_real"] = is_real
|
||||
resp_obj["antispoof_score"] = antispoof_score
|
||||
|
@ -13,51 +13,88 @@ from deepface.basemodels import (
|
||||
Facenet,
|
||||
GhostFaceNet,
|
||||
)
|
||||
from deepface.detectors import (
|
||||
FastMtCnn,
|
||||
MediaPipe,
|
||||
MtCnn,
|
||||
OpenCv,
|
||||
Dlib as DlibDetector,
|
||||
RetinaFace,
|
||||
Ssd,
|
||||
Yolo,
|
||||
YuNet,
|
||||
CenterFace,
|
||||
)
|
||||
from deepface.extendedmodels import Age, Gender, Race, Emotion
|
||||
from deepface.spoofmodels import FasNet
|
||||
|
||||
|
||||
def build_model(model_name: str) -> Any:
|
||||
def build_model(task: str, model_name: str) -> Any:
|
||||
"""
|
||||
This function builds a deepface model
|
||||
This function loads a pre-trained models as singletonish way
|
||||
Parameters:
|
||||
model_name (string): face recognition or facial attribute model
|
||||
VGG-Face, Facenet, OpenFace, DeepFace, DeepID for face recognition
|
||||
Age, Gender, Emotion, Race for facial attributes
|
||||
|
||||
task (str): facial_recognition, facial_attribute, face_detector, spoofing
|
||||
model_name (str): model identifier
|
||||
- VGG-Face, Facenet, Facenet512, OpenFace, DeepFace, DeepID, Dlib,
|
||||
ArcFace, SFace, GhostFaceNet for face recognition
|
||||
- Age, Gender, Emotion, Race for facial attributes
|
||||
- opencv, mtcnn, ssd, dlib, retinaface, mediapipe, yolov8, yunet,
|
||||
fastmtcnn or centerface for face detectors
|
||||
- Fasnet for spoofing
|
||||
Returns:
|
||||
built model class
|
||||
"""
|
||||
|
||||
# singleton design pattern
|
||||
global model_obj
|
||||
global cached_models
|
||||
|
||||
models = {
|
||||
"VGG-Face": VGGFace.VggFaceClient,
|
||||
"OpenFace": OpenFace.OpenFaceClient,
|
||||
"Facenet": Facenet.FaceNet128dClient,
|
||||
"Facenet512": Facenet.FaceNet512dClient,
|
||||
"DeepFace": FbDeepFace.DeepFaceClient,
|
||||
"DeepID": DeepID.DeepIdClient,
|
||||
"Dlib": Dlib.DlibClient,
|
||||
"ArcFace": ArcFace.ArcFaceClient,
|
||||
"SFace": SFace.SFaceClient,
|
||||
"GhostFaceNet": GhostFaceNet.GhostFaceNetClient,
|
||||
"Emotion": Emotion.EmotionClient,
|
||||
"Age": Age.ApparentAgeClient,
|
||||
"Gender": Gender.GenderClient,
|
||||
"Race": Race.RaceClient,
|
||||
"Fasnet": FasNet.Fasnet,
|
||||
"facial_recognition": {
|
||||
"VGG-Face": VGGFace.VggFaceClient,
|
||||
"OpenFace": OpenFace.OpenFaceClient,
|
||||
"Facenet": Facenet.FaceNet128dClient,
|
||||
"Facenet512": Facenet.FaceNet512dClient,
|
||||
"DeepFace": FbDeepFace.DeepFaceClient,
|
||||
"DeepID": DeepID.DeepIdClient,
|
||||
"Dlib": Dlib.DlibClient,
|
||||
"ArcFace": ArcFace.ArcFaceClient,
|
||||
"SFace": SFace.SFaceClient,
|
||||
"GhostFaceNet": GhostFaceNet.GhostFaceNetClient,
|
||||
},
|
||||
"spoofing": {
|
||||
"Fasnet": FasNet.Fasnet,
|
||||
},
|
||||
"facial_attribute": {
|
||||
"Emotion": Emotion.EmotionClient,
|
||||
"Age": Age.ApparentAgeClient,
|
||||
"Gender": Gender.GenderClient,
|
||||
"Race": Race.RaceClient,
|
||||
},
|
||||
"face_detector": {
|
||||
"opencv": OpenCv.OpenCvClient,
|
||||
"mtcnn": MtCnn.MtCnnClient,
|
||||
"ssd": Ssd.SsdClient,
|
||||
"dlib": DlibDetector.DlibClient,
|
||||
"retinaface": RetinaFace.RetinaFaceClient,
|
||||
"mediapipe": MediaPipe.MediaPipeClient,
|
||||
"yolov8": Yolo.YoloClient,
|
||||
"yunet": YuNet.YuNetClient,
|
||||
"fastmtcnn": FastMtCnn.FastMtCnnClient,
|
||||
"centerface": CenterFace.CenterFaceClient,
|
||||
},
|
||||
}
|
||||
|
||||
if not "model_obj" in globals():
|
||||
model_obj = {}
|
||||
if models.get(task) is None:
|
||||
raise ValueError(f"unimplemented task - {task}")
|
||||
|
||||
if not model_name in model_obj.keys():
|
||||
model = models.get(model_name)
|
||||
if not "cached_models" in globals():
|
||||
cached_models = {current_task: {} for current_task in models.keys()}
|
||||
|
||||
if cached_models[task].get(model_name) is None:
|
||||
model = models[task].get(model_name)
|
||||
if model:
|
||||
model_obj[model_name] = model()
|
||||
cached_models[task][model_name] = model()
|
||||
else:
|
||||
raise ValueError(f"Invalid model_name passed - {model_name}")
|
||||
raise ValueError(f"Invalid model_name passed - {task}/{model_name}")
|
||||
|
||||
return model_obj[model_name]
|
||||
return cached_models[task][model_name]
|
||||
|
@ -65,7 +65,9 @@ def represent(
|
||||
"""
|
||||
resp_objs = []
|
||||
|
||||
model: FacialRecognition = modeling.build_model(model_name)
|
||||
model: FacialRecognition = modeling.build_model(
|
||||
task="facial_recognition", model_name=model_name
|
||||
)
|
||||
|
||||
# ---------------------------------
|
||||
# we have run pre-process in verification. so, this can be skipped if it is coming from verify.
|
||||
|
@ -171,7 +171,7 @@ def build_facial_recognition_model(model_name: str) -> None:
|
||||
Returns
|
||||
input_shape (tuple): input shape of given facial recognitio n model.
|
||||
"""
|
||||
_ = DeepFace.build_model(model_name=model_name)
|
||||
_ = DeepFace.build_model(task="facial_recognition", model_name=model_name)
|
||||
logger.info(f"{model_name} is built")
|
||||
|
||||
|
||||
@ -267,11 +267,11 @@ def build_demography_models(enable_face_analysis: bool) -> None:
|
||||
"""
|
||||
if enable_face_analysis is False:
|
||||
return
|
||||
DeepFace.build_model(model_name="Age")
|
||||
DeepFace.build_model(task="facial_attribute", model_name="Age")
|
||||
logger.info("Age model is just built")
|
||||
DeepFace.build_model(model_name="Gender")
|
||||
DeepFace.build_model(task="facial_attribute", model_name="Gender")
|
||||
logger.info("Gender model is just built")
|
||||
DeepFace.build_model(model_name="Emotion")
|
||||
DeepFace.build_model(task="facial_attribute", model_name="Emotion")
|
||||
logger.info("Emotion model is just built")
|
||||
|
||||
|
||||
|
@ -100,7 +100,9 @@ def verify(
|
||||
|
||||
tic = time.time()
|
||||
|
||||
model: FacialRecognition = modeling.build_model(model_name)
|
||||
model: FacialRecognition = modeling.build_model(
|
||||
task="facial_recognition", model_name=model_name
|
||||
)
|
||||
dims = model.output_shape
|
||||
|
||||
# extract faces from img1
|
||||
|
@ -1,3 +1,3 @@
|
||||
{
|
||||
"version": "0.0.92"
|
||||
"version": "0.0.93"
|
||||
}
|
@ -16,7 +16,7 @@ logger = Logger()
|
||||
|
||||
model_name = "VGG-Face"
|
||||
|
||||
model: FacialRecognition = DeepFace.build_model(model_name=model_name)
|
||||
model: FacialRecognition = DeepFace.build_model(task="facial_recognition", model_name=model_name)
|
||||
|
||||
target_size = model.input_shape
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user