Merge pull request #962 from serengil/feat-task-2101-interfaces

cosmetic changes about interfaces
This commit is contained in:
Sefik Ilkin Serengil 2024-01-21 18:17:02 +00:00 committed by GitHub
commit bc30c904a0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
29 changed files with 508 additions and 257 deletions

View File

@ -1,5 +1,7 @@
from typing import List
import os import os
import gdown import gdown
import numpy as np
from deepface.commons import functions from deepface.commons import functions
from deepface.commons.logger import Logger from deepface.commons.logger import Logger
from deepface.models.FacialRecognition import FacialRecognition from deepface.models.FacialRecognition import FacialRecognition
@ -43,7 +45,7 @@ else:
) )
# pylint: disable=too-few-public-methods # pylint: disable=too-few-public-methods
class ArcFace(FacialRecognition): class ArcFaceClient(FacialRecognition):
""" """
ArcFace model class ArcFace model class
""" """
@ -52,6 +54,18 @@ class ArcFace(FacialRecognition):
self.model = load_model() self.model = load_model()
self.model_name = "ArcFace" self.model_name = "ArcFace"
def find_embeddings(self, img: np.ndarray) -> List[float]:
"""
find embeddings with ArcFace model
Args:
img (np.ndarray): pre-loaded image in BGR
Returns
embeddings (list): multi-dimensional vector
"""
# model.predict causes memory issue when it is called in a for loop
# embedding = model.predict(img, verbose=0)[0].tolist()
return self.model(img, training=False).numpy()[0].tolist()
def load_model( def load_model(
url="https://github.com/serengil/deepface_models/releases/download/v1.0/arcface_weights.h5", url="https://github.com/serengil/deepface_models/releases/download/v1.0/arcface_weights.h5",

View File

@ -1,5 +1,7 @@
from typing import List
import os import os
import gdown import gdown
import numpy as np
from deepface.commons import functions from deepface.commons import functions
from deepface.commons.logger import Logger from deepface.commons.logger import Logger
from deepface.models.FacialRecognition import FacialRecognition from deepface.models.FacialRecognition import FacialRecognition
@ -39,7 +41,7 @@ else:
# ------------------------------------- # -------------------------------------
# pylint: disable=too-few-public-methods # pylint: disable=too-few-public-methods
class DeepId(FacialRecognition): class DeepIdClient(FacialRecognition):
""" """
DeepId model class DeepId model class
""" """
@ -48,6 +50,18 @@ class DeepId(FacialRecognition):
self.model = load_model() self.model = load_model()
self.model_name = "DeepId" self.model_name = "DeepId"
def find_embeddings(self, img: np.ndarray) -> List[float]:
"""
find embeddings with DeepId model
Args:
img (np.ndarray): pre-loaded image in BGR
Returns
embeddings (list): multi-dimensional vector
"""
# model.predict causes memory issue when it is called in a for loop
# embedding = model.predict(img, verbose=0)[0].tolist()
return self.model(img, training=False).numpy()[0].tolist()
def load_model( def load_model(
url="https://github.com/serengil/deepface_models/releases/download/v1.0/deepid_keras_weights.h5", url="https://github.com/serengil/deepface_models/releases/download/v1.0/deepid_keras_weights.h5",

View File

@ -1,3 +1,4 @@
from typing import List
import os import os
import bz2 import bz2
import gdown import gdown
@ -11,7 +12,7 @@ logger = Logger(module="basemodels.DlibResNet")
# pylint: disable=too-few-public-methods # pylint: disable=too-few-public-methods
class Dlib(FacialRecognition): class DlibClient(FacialRecognition):
""" """
Dlib model class Dlib model class
""" """
@ -20,15 +21,33 @@ class Dlib(FacialRecognition):
self.model = DlibResNet() self.model = DlibResNet()
self.model_name = "Dlib" self.model_name = "Dlib"
def find_embeddings(self, img: np.ndarray) -> list: def find_embeddings(self, img: np.ndarray) -> List[float]:
""" """
Custom find embeddings function of Dlib different than FacialRecognition's one find embeddings with Dlib model - different than regular models
Args: Args:
img (np.ndarray) img (np.ndarray): pre-loaded image in BGR
Retunrs: Returns
embeddings (list) embeddings (list): multi-dimensional vector
""" """
return self.model.predict(img)[0].tolist() # return self.model.predict(img)[0].tolist()
# extract_faces returns 4 dimensional images
if len(img.shape) == 4:
img = img[0]
# bgr to rgb
img = img[:, :, ::-1] # bgr to rgb
# img is in scale of [0, 1] but expected [0, 255]
if img.max() <= 1:
img = img * 255
img = img.astype(np.uint8)
img_representation = self.model.model.compute_face_descriptor(img)
img_representation = np.array(img_representation)
img_representation = np.expand_dims(img_representation, axis=0)
return img_representation[0].tolist()
class DlibResNet: class DlibResNet:
@ -69,38 +88,12 @@ class DlibResNet:
# --------------------- # ---------------------
model = dlib.face_recognition_model_v1(weight_file) self.model = dlib.face_recognition_model_v1(weight_file)
self.__model = model
# --------------------- # ---------------------
# return None # classes must return None # return None # classes must return None
def predict(self, img_aligned: np.ndarray) -> np.ndarray:
# functions.detectFace returns 4 dimensional images
if len(img_aligned.shape) == 4:
img_aligned = img_aligned[0]
# functions.detectFace returns bgr images
img_aligned = img_aligned[:, :, ::-1] # bgr to rgb
# deepface.detectFace returns an array in scale of [0, 1]
# but dlib expects in scale of [0, 255]
if img_aligned.max() <= 1:
img_aligned = img_aligned * 255
img_aligned = img_aligned.astype(np.uint8)
model = self.__model
img_representation = model.compute_face_descriptor(img_aligned)
img_representation = np.array(img_representation)
img_representation = np.expand_dims(img_representation, axis=0)
return img_representation
class DlibMetaData: class DlibMetaData:
def __init__(self): def __init__(self):

View File

@ -1,5 +1,7 @@
from typing import List
import os import os
import gdown import gdown
import numpy as np
from deepface.commons import functions from deepface.commons import functions
from deepface.commons.logger import Logger from deepface.commons.logger import Logger
from deepface.models.FacialRecognition import FacialRecognition from deepface.models.FacialRecognition import FacialRecognition
@ -43,7 +45,7 @@ else:
# -------------------------------- # --------------------------------
# pylint: disable=too-few-public-methods # pylint: disable=too-few-public-methods
class FaceNet128d(FacialRecognition): class FaceNet128dClient(FacialRecognition):
""" """
FaceNet-128d model class FaceNet-128d model class
""" """
@ -52,8 +54,20 @@ class FaceNet128d(FacialRecognition):
self.model = load_facenet128d_model() self.model = load_facenet128d_model()
self.model_name = "FaceNet-128d" self.model_name = "FaceNet-128d"
def find_embeddings(self, img: np.ndarray) -> List[float]:
"""
find embeddings with FaceNet-128d model
Args:
img (np.ndarray): pre-loaded image in BGR
Returns
embeddings (list): multi-dimensional vector
"""
# model.predict causes memory issue when it is called in a for loop
# embedding = model.predict(img, verbose=0)[0].tolist()
return self.model(img, training=False).numpy()[0].tolist()
class FaceNet512d(FacialRecognition):
class FaceNet512dClient(FacialRecognition):
""" """
FaceNet-1512d model class FaceNet-1512d model class
""" """
@ -62,6 +76,18 @@ class FaceNet512d(FacialRecognition):
self.model = load_facenet512d_model() self.model = load_facenet512d_model()
self.model_name = "FaceNet-512d" self.model_name = "FaceNet-512d"
def find_embeddings(self, img: np.ndarray) -> List[float]:
"""
find embeddings with FaceNet-512d model
Args:
img (np.ndarray): pre-loaded image in BGR
Returns
embeddings (list): multi-dimensional vector
"""
# model.predict causes memory issue when it is called in a for loop
# embedding = model.predict(img, verbose=0)[0].tolist()
return self.model(img, training=False).numpy()[0].tolist()
def scaling(x, scale): def scaling(x, scale):
return x * scale return x * scale

View File

@ -1,6 +1,8 @@
from typing import List
import os import os
import zipfile import zipfile
import gdown import gdown
import numpy as np
from deepface.commons import functions from deepface.commons import functions
from deepface.commons.logger import Logger from deepface.commons.logger import Logger
from deepface.models.FacialRecognition import FacialRecognition from deepface.models.FacialRecognition import FacialRecognition
@ -36,7 +38,7 @@ else:
# ------------------------------------- # -------------------------------------
# pylint: disable=line-too-long, too-few-public-methods # pylint: disable=line-too-long, too-few-public-methods
class DeepFace(FacialRecognition): class DeepFaceClient(FacialRecognition):
""" """
Fb's DeepFace model class Fb's DeepFace model class
""" """
@ -45,6 +47,18 @@ class DeepFace(FacialRecognition):
self.model = load_model() self.model = load_model()
self.model_name = "DeepFace" self.model_name = "DeepFace"
def find_embeddings(self, img: np.ndarray) -> List[float]:
"""
find embeddings with OpenFace model
Args:
img (np.ndarray): pre-loaded image in BGR
Returns
embeddings (list): multi-dimensional vector
"""
# model.predict causes memory issue when it is called in a for loop
# embedding = model.predict(img, verbose=0)[0].tolist()
return self.model(img, training=False).numpy()[0].tolist()
def load_model( def load_model(
url="https://github.com/swghosh/DeepFace/releases/download/weights-vggface2-2d-aligned/VGGFace2_DeepFace_weights_val-0.9034.h5.zip", url="https://github.com/swghosh/DeepFace/releases/download/weights-vggface2-2d-aligned/VGGFace2_DeepFace_weights_val-0.9034.h5.zip",

View File

@ -1,6 +1,8 @@
from typing import List
import os import os
import gdown import gdown
import tensorflow as tf import tensorflow as tf
import numpy as np
from deepface.commons import functions from deepface.commons import functions
from deepface.commons.logger import Logger from deepface.commons.logger import Logger
from deepface.models.FacialRecognition import FacialRecognition from deepface.models.FacialRecognition import FacialRecognition
@ -26,7 +28,7 @@ else:
# --------------------------------------- # ---------------------------------------
# pylint: disable=too-few-public-methods # pylint: disable=too-few-public-methods
class OpenFace(FacialRecognition): class OpenFaceClient(FacialRecognition):
""" """
OpenFace model class OpenFace model class
""" """
@ -35,6 +37,18 @@ class OpenFace(FacialRecognition):
self.model = load_model() self.model = load_model()
self.model_name = "OpenFace" self.model_name = "OpenFace"
def find_embeddings(self, img: np.ndarray) -> List[float]:
"""
find embeddings with OpenFace model
Args:
img (np.ndarray): pre-loaded image in BGR
Returns
embeddings (list): multi-dimensional vector
"""
# model.predict causes memory issue when it is called in a for loop
# embedding = model.predict(img, verbose=0)[0].tolist()
return self.model(img, training=False).numpy()[0].tolist()
def load_model( def load_model(
url="https://github.com/serengil/deepface_models/releases/download/v1.0/openface_weights.h5", url="https://github.com/serengil/deepface_models/releases/download/v1.0/openface_weights.h5",

View File

@ -1,5 +1,5 @@
import os import os
from typing import Any from typing import Any, List
import numpy as np import numpy as np
import cv2 as cv import cv2 as cv
@ -14,7 +14,7 @@ logger = Logger(module="basemodels.SFace")
# pylint: disable=line-too-long, too-few-public-methods # pylint: disable=line-too-long, too-few-public-methods
class SFace(FacialRecognition): class SFaceClient(FacialRecognition):
""" """
SFace model class SFace model class
""" """
@ -23,15 +23,22 @@ class SFace(FacialRecognition):
self.model = load_model() self.model = load_model()
self.model_name = "SFace" self.model_name = "SFace"
def find_embeddings(self, img: np.ndarray) -> list: def find_embeddings(self, img: np.ndarray) -> List[float]:
""" """
Custom find embeddings function of SFace different than FacialRecognition's one find embeddings with SFace model - different than regular models
Args: Args:
img (np.ndarray) img (np.ndarray): pre-loaded image in BGR
Retunrs: Returns
embeddings (list) embeddings (list): multi-dimensional vector
""" """
return self.model.predict(img)[0].tolist() # return self.model.predict(img)[0].tolist()
# revert the image to original format and preprocess using the model
input_blob = (img[0] * 255).astype(np.uint8)
embeddings = self.model.model.feature(input_blob)
return embeddings[0].tolist()
def load_model( def load_model(
@ -74,17 +81,6 @@ class SFaceWrapper:
self.layers = [_Layer()] self.layers = [_Layer()]
def predict(self, image: np.ndarray) -> np.ndarray:
# Preprocess
input_blob = (image[0] * 255).astype(
np.uint8
) # revert the image to original format and preprocess using the model
# Forward
embeddings = self.model.feature(input_blob)
return embeddings
class _Layer: class _Layer:
input_shape = (None, 112, 112, 3) input_shape = (None, 112, 112, 3)

View File

@ -1,5 +1,7 @@
from typing import List
import os import os
import gdown import gdown
import numpy as np
from deepface.commons import functions from deepface.commons import functions
from deepface.commons.logger import Logger from deepface.commons.logger import Logger
from deepface.models.FacialRecognition import FacialRecognition from deepface.models.FacialRecognition import FacialRecognition
@ -37,7 +39,7 @@ else:
# --------------------------------------- # ---------------------------------------
# pylint: disable=too-few-public-methods # pylint: disable=too-few-public-methods
class VggFace(FacialRecognition): class VggFaceClient(FacialRecognition):
""" """
VGG-Face model class VGG-Face model class
""" """
@ -46,6 +48,18 @@ class VggFace(FacialRecognition):
self.model = load_model() self.model = load_model()
self.model_name = "VGG-Face" self.model_name = "VGG-Face"
def find_embeddings(self, img: np.ndarray) -> List[float]:
"""
find embeddings with VGG-Face model
Args:
img (np.ndarray): pre-loaded image in BGR
Returns
embeddings (list): multi-dimensional vector
"""
# model.predict causes memory issue when it is called in a for loop
# embedding = model.predict(img, verbose=0)[0].tolist()
return self.model(img, training=False).numpy()[0].tolist()
def base_model() -> Sequential: def base_model() -> Sequential:
""" """

View File

@ -1,5 +1,5 @@
import os import os
from typing import Union, Tuple from typing import Union, Tuple, List
import base64 import base64
from pathlib import Path from pathlib import Path
@ -140,9 +140,9 @@ def extract_faces(
grayscale: bool = False, grayscale: bool = False,
enforce_detection: bool = True, enforce_detection: bool = True,
align: bool = True, align: bool = True,
) -> list: ) -> List[Tuple[np.ndarray, dict, float]]:
"""Extract faces from an image. """
Extract faces from an image.
Args: Args:
img: a path, url, base64 or numpy array. img: a path, url, base64 or numpy array.
target_size (tuple, optional): the target size of the extracted faces. target_size (tuple, optional): the target size of the extracted faces.
@ -157,7 +157,12 @@ def extract_faces(
ValueError: if face could not be detected and enforce_detection is True. ValueError: if face could not be detected and enforce_detection is True.
Returns: Returns:
list: a list of extracted faces. results (List[Tuple[np.ndarray, dict, float]]): A list of tuples
where each tuple contains:
- detected_face (np.ndarray): The detected face as a NumPy array.
- face_region (dict): The image region represented as
{"x": x, "y": y, "w": w, "h": h}
- confidence (float): The confidence score associated with the detected face.
""" """
# this is going to store a list of img itself (numpy), it region and confidence # this is going to store a list of img itself (numpy), it region and confidence
@ -246,7 +251,7 @@ def extract_faces(
"h": int(current_region[3]), "h": int(current_region[3]),
} }
extracted_face = [img_pixels, region_obj, confidence] extracted_face = (img_pixels, region_obj, confidence)
extracted_faces.append(extracted_face) extracted_faces.append(extracted_face)
if len(extracted_faces) == 0 and enforce_detection == True: if len(extracted_faces) == 0 and enforce_detection == True:

View File

@ -2,15 +2,15 @@ from typing import Any
import numpy as np import numpy as np
from deepface.models.Detector import Detector from deepface.models.Detector import Detector
from deepface.detectors import ( from deepface.detectors import (
OpenCvWrapper, FastMtCnn,
SsdWrapper, MediaPipe,
DlibWrapper, MtCnn,
MtcnnWrapper, OpenCv,
RetinaFaceWrapper, Dlib,
MediapipeWrapper, RetinaFace,
YoloWrapper, Ssd,
YunetWrapper, Yolo,
FastMtcnnWrapper, YuNet,
) )
@ -25,15 +25,15 @@ def build_model(detector_backend: str) -> Any:
global face_detector_obj # singleton design pattern global face_detector_obj # singleton design pattern
backends = { backends = {
"opencv": OpenCvWrapper.OpenCv, "opencv": OpenCv.OpenCvClient,
"mtcnn": MtcnnWrapper.MtCnn, "mtcnn": MtCnn.MtCnnClient,
"ssd": SsdWrapper.Ssd, "ssd": Ssd.SsdClient,
"dlib": DlibWrapper.Dlib, "dlib": Dlib.DlibClient,
"retinaface": RetinaFaceWrapper.RetinaFace, "retinaface": RetinaFace.RetinaFaceClient,
"mediapipe": MediapipeWrapper.MediaPipe, "mediapipe": MediaPipe.MediaPipeClient,
"yolov8": YoloWrapper.Yolo, "yolov8": Yolo.YoloClient,
"yunet": YunetWrapper.YuNet, "yunet": YuNet.YuNetClient,
"fastmtcnn": FastMtcnnWrapper.FastMtCnn, "fastmtcnn": FastMtCnn.FastMtCnnClient,
} }
if not "face_detector_obj" in globals(): if not "face_detector_obj" in globals():
@ -59,9 +59,20 @@ def detect_faces(detector_backend: str, img: np.ndarray, align: bool = True) ->
detector_backend (str): detector name detector_backend (str): detector name
img (np.ndarray): pre-loaded image img (np.ndarray): pre-loaded image
alig (bool): enable or disable alignment after detection alig (bool): enable or disable alignment after detection
Returns Returns:
result (list): tuple of face (np.ndarray), face region (list) results (List[Tuple[np.ndarray, List[float], float]]): A list of tuples
, confidence score (float) where each tuple contains:
- detected_face (np.ndarray): The detected face as a NumPy array.
- face_region (List[float]): The image region represented as
a list of floats e.g. [x, y, w, h]
- confidence (float): The confidence score associated with the detected face.
Example:
results = [
(array(..., dtype=uint8), [110, 60, 150, 380], 0.99),
(array(..., dtype=uint8), [150, 50, 299, 375], 0.98),
(array(..., dtype=uint8), [120, 55, 300, 371], 0.96),
]
""" """
face_detector: Detector = build_model(detector_backend) face_detector: Detector = build_model(detector_backend)
return face_detector.detect_faces(img=img, align=align) return face_detector.detect_faces(img=img, align=align)

View File

@ -1,3 +1,4 @@
from typing import List, Tuple
import os import os
import bz2 import bz2
import gdown import gdown
@ -9,7 +10,7 @@ from deepface.commons.logger import Logger
logger = Logger(module="detectors.DlibWrapper") logger = Logger(module="detectors.DlibWrapper")
class Dlib(Detector): class DlibClient(Detector):
def __init__(self): def __init__(self):
self.model = self.build_model() self.model = self.build_model()
@ -55,7 +56,9 @@ class Dlib(Detector):
detector["sp"] = sp detector["sp"] = sp
return detector return detector
def detect_faces(self, img: np.ndarray, align: bool = True) -> list: def detect_faces(
self, img: np.ndarray, align: bool = True
) -> List[Tuple[np.ndarray, List[float], float]]:
""" """
Detect and align face with dlib Detect and align face with dlib
Args: Args:
@ -63,7 +66,19 @@ class Dlib(Detector):
img (np.ndarray): pre-loaded image img (np.ndarray): pre-loaded image
align (bool): default is true align (bool): default is true
Returns: Returns:
list of detected and aligned faces results (List[Tuple[np.ndarray, List[float], float]]): A list of tuples
where each tuple contains:
- detected_face (np.ndarray): The detected face as a NumPy array.
- face_region (List[float]): The image region represented as
a list of floats e.g. [x, y, w, h]
- confidence (float): The confidence score associated with the detected face.
Example:
results = [
(array(..., dtype=uint8), [110, 60, 150, 380], 0.99),
(array(..., dtype=uint8), [150, 50, 299, 375], 0.98),
(array(..., dtype=uint8), [120, 55, 300, 371], 0.96),
]
""" """
# this is not a must dependency. do not import it in the global level. # this is not a must dependency. do not import it in the global level.
try: try:

View File

@ -1,24 +1,39 @@
from typing import Any, Union from typing import Any, Union, List, Tuple
import cv2 import cv2
import numpy as np import numpy as np
from deepface.models.Detector import Detector from deepface.models.Detector import Detector
from deepface.modules import detection
# Link -> https://github.com/timesler/facenet-pytorch # Link -> https://github.com/timesler/facenet-pytorch
# Examples https://www.kaggle.com/timesler/guide-to-mtcnn-in-facenet-pytorch # Examples https://www.kaggle.com/timesler/guide-to-mtcnn-in-facenet-pytorch
class FastMtCnn(Detector): class FastMtCnnClient(Detector):
def __init__(self): def __init__(self):
self.model = self.build_model() self.model = self.build_model()
def detect_faces(self, img: np.ndarray, align: bool = True) -> list: def detect_faces(
self, img: np.ndarray, align: bool = True
) -> List[Tuple[np.ndarray, List[float], float]]:
""" """
Detect and align face with mtcnn Detect and align face with mtcnn
Args: Args:
img (np.ndarray): pre-loaded image img (np.ndarray): pre-loaded image
align (bool): default is true align (bool): default is true
Returns: Returns:
list of detected and aligned faces results (List[Tuple[np.ndarray, List[float], float]]): A list of tuples
where each tuple contains:
- detected_face (np.ndarray): The detected face as a NumPy array.
- face_region (List[float]): The image region represented as
a list of floats e.g. [x, y, w, h]
- confidence (float): The confidence score associated with the detected face.
Example:
results = [
(array(..., dtype=uint8), [110, 60, 150, 380], 0.99),
(array(..., dtype=uint8), [150, 50, 299, 375], 0.98),
(array(..., dtype=uint8), [120, 55, 300, 371], 0.96),
]
""" """
resp = [] resp = []
@ -31,16 +46,16 @@ class FastMtCnn(Detector):
) # returns boundingbox, prob, landmark ) # returns boundingbox, prob, landmark
if len(detections[0]) > 0: if len(detections[0]) > 0:
for detection in zip(*detections): for current_detection in zip(*detections):
x, y, w, h = xyxy_to_xywh(detection[0]) x, y, w, h = xyxy_to_xywh(current_detection[0])
detected_face = img[int(y) : int(y + h), int(x) : int(x + w)] detected_face = img[int(y) : int(y + h), int(x) : int(x + w)]
img_region = [x, y, w, h] img_region = [x, y, w, h]
confidence = detection[1] confidence = current_detection[1]
if align: if align:
left_eye = detection[2][0] left_eye = current_detection[2][0]
right_eye = detection[2][1] right_eye = current_detection[2][1]
detected_face = self.align_face( detected_face = detection.align_face(
img=detected_face, left_eye=left_eye, right_eye=right_eye img=detected_face, left_eye=left_eye, right_eye=right_eye
) )

View File

@ -1,11 +1,12 @@
from typing import Any from typing import Any, List, Tuple
import numpy as np import numpy as np
from deepface.models.Detector import Detector from deepface.models.Detector import Detector
from deepface.modules import detection
# Link - https://google.github.io/mediapipe/solutions/face_detection # Link - https://google.github.io/mediapipe/solutions/face_detection
class MediaPipe(Detector): class MediaPipeClient(Detector):
def __init__(self): def __init__(self):
self.model = self.build_model() self.model = self.build_model()
@ -28,14 +29,28 @@ class MediaPipe(Detector):
face_detection = mp_face_detection.FaceDetection(min_detection_confidence=0.7) face_detection = mp_face_detection.FaceDetection(min_detection_confidence=0.7)
return face_detection return face_detection
def detect_faces(self, img: np.ndarray, align: bool = True) -> list: def detect_faces(
self, img: np.ndarray, align: bool = True
) -> List[Tuple[np.ndarray, List[float], float]]:
""" """
Detect and align face with mediapipe Detect and align face with mediapipe
Args: Args:
img (np.ndarray): pre-loaded image img (np.ndarray): pre-loaded image
align (bool): default is true align (bool): default is true
Returns: Returns:
list of detected and aligned faces results (List[Tuple[np.ndarray, List[float], float]]): A list of tuples
where each tuple contains:
- detected_face (np.ndarray): The detected face as a NumPy array.
- face_region (List[float]): The image region represented as
a list of floats e.g. [x, y, w, h]
- confidence (float): The confidence score associated with the detected face.
Example:
results = [
(array(..., dtype=uint8), [110, 60, 150, 380], 0.99),
(array(..., dtype=uint8), [150, 50, 299, 375], 0.98),
(array(..., dtype=uint8), [120, 55, 300, 371], 0.96),
]
""" """
resp = [] resp = []
@ -49,11 +64,11 @@ class MediaPipe(Detector):
return resp return resp
# Extract the bounding box, the landmarks and the confidence score # Extract the bounding box, the landmarks and the confidence score
for detection in results.detections: for current_detection in results.detections:
(confidence,) = detection.score (confidence,) = current_detection.score
bounding_box = detection.location_data.relative_bounding_box bounding_box = current_detection.location_data.relative_bounding_box
landmarks = detection.location_data.relative_keypoints landmarks = current_detection.location_data.relative_keypoints
x = int(bounding_box.xmin * img_width) x = int(bounding_box.xmin * img_width)
w = int(bounding_box.width * img_width) w = int(bounding_box.width * img_width)
@ -73,7 +88,7 @@ class MediaPipe(Detector):
img_region = [x, y, w, h] img_region = [x, y, w, h]
if align: if align:
detected_face = self.align_face( detected_face = detection.align_face(
img=detected_face, left_eye=left_eye, right_eye=right_eye img=detected_face, left_eye=left_eye, right_eye=right_eye
) )

View File

@ -0,0 +1,67 @@
from typing import List, Tuple
import cv2
import numpy as np
from mtcnn import MTCNN
from deepface.models.Detector import Detector
from deepface.modules import detection
# pylint: disable=too-few-public-methods
class MtCnnClient(Detector):
"""
Class to cover common face detection functionalitiy for MtCnn backend
"""
def __init__(self):
self.model = MTCNN()
def detect_faces(
self, img: np.ndarray, align: bool = True
) -> List[Tuple[np.ndarray, List[float], float]]:
"""
Detect and align face with mtcnn
Args:
img (np.ndarray): pre-loaded image
align (bool): default is true
Returns:
results (List[Tuple[np.ndarray, List[float], float]]): A list of tuples
where each tuple contains:
- detected_face (np.ndarray): The detected face as a NumPy array.
- face_region (List[float]): The image region represented as
a list of floats e.g. [x, y, w, h]
- confidence (float): The confidence score associated with the detected face.
Example:
results = [
(array(..., dtype=uint8), [110, 60, 150, 380], 0.99),
(array(..., dtype=uint8), [150, 50, 299, 375], 0.98),
(array(..., dtype=uint8), [120, 55, 300, 371], 0.96),
]
"""
resp = []
detected_face = None
img_region = [0, 0, img.shape[1], img.shape[0]]
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # mtcnn expects RGB but OpenCV read BGR
detections = self.model.detect_faces(img_rgb)
if len(detections) > 0:
for current_detection in detections:
x, y, w, h = current_detection["box"]
detected_face = img[int(y) : int(y + h), int(x) : int(x + w)]
img_region = [x, y, w, h]
confidence = current_detection["confidence"]
if align:
keypoints = current_detection["keypoints"]
left_eye = keypoints["left_eye"]
right_eye = keypoints["right_eye"]
detected_face = detection.align_face(
img=detected_face, left_eye=left_eye, right_eye=right_eye
)
resp.append((detected_face, img_region, confidence))
return resp

View File

@ -1,51 +0,0 @@
import cv2
import numpy as np
from mtcnn import MTCNN
from deepface.models.Detector import Detector
class MtCnn(Detector):
"""
Class to cover common face detection functionalitiy for MtCnn backend
"""
def __init__(self):
self.model = MTCNN()
def detect_faces(self, img: np.ndarray, align: bool = True) -> list:
"""
Detect and align face with mtcnn
Args:
img (np.ndarray): pre-loaded image
align (bool): default is true
Returns:
list of detected and aligned faces
"""
resp = []
detected_face = None
img_region = [0, 0, img.shape[1], img.shape[0]]
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # mtcnn expects RGB but OpenCV read BGR
detections = self.model.detect_faces(img_rgb)
if len(detections) > 0:
for detection in detections:
x, y, w, h = detection["box"]
detected_face = img[int(y) : int(y + h), int(x) : int(x + w)]
img_region = [x, y, w, h]
confidence = detection["confidence"]
if align:
keypoints = detection["keypoints"]
left_eye = keypoints["left_eye"]
right_eye = keypoints["right_eye"]
detected_face = self.align_face(
img=detected_face, left_eye=left_eye, right_eye=right_eye
)
resp.append((detected_face, img_region, confidence))
return resp

View File

@ -1,11 +1,12 @@
import os import os
from typing import Any from typing import Any, List, Tuple
import cv2 import cv2
import numpy as np import numpy as np
from deepface.models.Detector import Detector from deepface.models.Detector import Detector
from deepface.modules import detection
class OpenCv(Detector): class OpenCvClient(Detector):
""" """
Class to cover common face detection functionalitiy for OpenCv backend Class to cover common face detection functionalitiy for OpenCv backend
""" """
@ -24,7 +25,9 @@ class OpenCv(Detector):
detector["eye_detector"] = self.__build_cascade("haarcascade_eye") detector["eye_detector"] = self.__build_cascade("haarcascade_eye")
return detector return detector
def detect_faces(self, img: np.ndarray, align: bool = True) -> list: def detect_faces(
self, img: np.ndarray, align: bool = True
) -> List[Tuple[np.ndarray, List[float], float]]:
""" """
Detect and align face with opencv Detect and align face with opencv
Args: Args:
@ -32,7 +35,19 @@ class OpenCv(Detector):
img (np.ndarray): pre-loaded image img (np.ndarray): pre-loaded image
align (bool): default is true align (bool): default is true
Returns: Returns:
list of detected and aligned faces results (List[Tuple[np.ndarray, List[float], float]]): A list of tuples
where each tuple contains:
- detected_face (np.ndarray): The detected face as a NumPy array.
- face_region (List[float]): The image region represented as
a list of floats e.g. [x, y, w, h]
- confidence (float): The confidence score associated with the detected face.
Example:
results = [
(array(..., dtype=uint8), [110, 60, 150, 380], 0.99),
(array(..., dtype=uint8), [150, 50, 299, 375], 0.98),
(array(..., dtype=uint8), [120, 55, 300, 371], 0.96),
]
""" """
resp = [] resp = []
@ -56,7 +71,7 @@ class OpenCv(Detector):
if align: if align:
left_eye, right_eye = self.find_eyes(img=detected_face) left_eye, right_eye = self.find_eyes(img=detected_face)
detected_face = self.align_face(detected_face, left_eye, right_eye) detected_face = detection.align_face(detected_face, left_eye, right_eye)
img_region = [x, y, w, h] img_region = [x, y, w, h]

View File

@ -1,21 +1,36 @@
from typing import List, Tuple
import numpy as np import numpy as np
from retinaface import RetinaFace as rf from retinaface import RetinaFace as rf
from retinaface.commons import postprocess from retinaface.commons import postprocess
from deepface.models.Detector import Detector from deepface.models.Detector import Detector
# pylint: disable=too-few-public-methods
class RetinaFace(Detector): class RetinaFaceClient(Detector):
def __init__(self): def __init__(self):
self.model = rf.build_model() self.model = rf.build_model()
def detect_faces(self, img: np.ndarray, align: bool = True) -> list: def detect_faces(
self, img: np.ndarray, align: bool = True
) -> List[Tuple[np.ndarray, List[float], float]]:
""" """
Detect and align face with retinaface Detect and align face with retinaface
Args: Args:
img (np.ndarray): pre-loaded image img (np.ndarray): pre-loaded image
align (bool): default is true align (bool): default is true
Returns: Returns:
list of detected and aligned faces results (List[Tuple[np.ndarray, List[float], float]]): A list of tuples
where each tuple contains:
- detected_face (np.ndarray): The detected face as a NumPy array.
- face_region (List[float]): The image region represented as
a list of floats e.g. [x, y, w, h]
- confidence (float): The confidence score associated with the detected face.
Example:
results = [
(array(..., dtype=uint8), [110, 60, 150, 380], 0.99),
(array(..., dtype=uint8), [150, 50, 299, 375], 0.98),
(array(..., dtype=uint8), [120, 55, 300, 371], 0.96),
]
""" """
resp = [] resp = []

View File

@ -1,11 +1,13 @@
from typing import List, Tuple
import os import os
import gdown import gdown
import cv2 import cv2
import pandas as pd import pandas as pd
import numpy as np import numpy as np
from deepface.detectors import OpenCvWrapper from deepface.detectors import OpenCv
from deepface.commons import functions from deepface.commons import functions
from deepface.models.Detector import Detector from deepface.models.Detector import Detector
from deepface.modules import detection
from deepface.commons.logger import Logger from deepface.commons.logger import Logger
logger = Logger(module="detectors.SsdWrapper") logger = Logger(module="detectors.SsdWrapper")
@ -13,7 +15,7 @@ logger = Logger(module="detectors.SsdWrapper")
# pylint: disable=line-too-long # pylint: disable=line-too-long
class Ssd(Detector): class SsdClient(Detector):
def __init__(self): def __init__(self):
self.model = self.build_model() self.model = self.build_model()
@ -65,18 +67,32 @@ class Ssd(Detector):
detector = {} detector = {}
detector["face_detector"] = face_detector detector["face_detector"] = face_detector
detector["opencv_module"] = OpenCvWrapper.OpenCv() detector["opencv_module"] = OpenCv.OpenCvClient()
return detector return detector
def detect_faces(self, img: np.ndarray, align: bool = True) -> list: def detect_faces(
self, img: np.ndarray, align: bool = True
) -> List[Tuple[np.ndarray, List[float], float]]:
""" """
Detect and align face with ssd Detect and align face with ssd
Args: Args:
img (np.ndarray): pre-loaded image img (np.ndarray): pre-loaded image
align (bool): default is true align (bool): default is true
Returns: Returns:
list of detected and aligned faces results (List[Tuple[np.ndarray, List[float], float]]): A list of tuples
where each tuple contains:
- detected_face (np.ndarray): The detected face as a NumPy array.
- face_region (List[float]): The image region represented as
a list of floats e.g. [x, y, w, h]
- confidence (float): The confidence score associated with the detected face.
Example:
results = [
(array(..., dtype=uint8), [110, 60, 150, 380], 0.99),
(array(..., dtype=uint8), [150, 50, 299, 375], 0.98),
(array(..., dtype=uint8), [120, 55, 300, 371], 0.96),
]
""" """
resp = [] resp = []
@ -134,9 +150,9 @@ class Ssd(Detector):
confidence = instance["confidence"] confidence = instance["confidence"]
if align: if align:
opencv_module: OpenCvWrapper.OpenCv = self.model["opencv_module"] opencv_module: OpenCv.OpenCvClient = self.model["opencv_module"]
left_eye, right_eye = opencv_module.find_eyes(detected_face) left_eye, right_eye = opencv_module.find_eyes(detected_face)
detected_face = self.align_face( detected_face = detection.align_face(
img=detected_face, left_eye=left_eye, right_eye=right_eye img=detected_face, left_eye=left_eye, right_eye=right_eye
) )

View File

@ -1,6 +1,7 @@
from typing import Any from typing import Any, List, Tuple
import numpy as np import numpy as np
from deepface.models.Detector import Detector from deepface.models.Detector import Detector
from deepface.modules import detection
from deepface.commons.logger import Logger from deepface.commons.logger import Logger
logger = Logger() logger = Logger()
@ -16,7 +17,7 @@ WEIGHT_URL = "https://drive.google.com/uc?id=1qcr9DbgsX3ryrz2uU8w4Xm3cOrRywXqb"
LANDMARKS_CONFIDENCE_THRESHOLD = 0.5 LANDMARKS_CONFIDENCE_THRESHOLD = 0.5
class Yolo(Detector): class YoloClient(Detector):
def __init__(self): def __init__(self):
self.model = self.build_model() self.model = self.build_model()
@ -50,7 +51,9 @@ class Yolo(Detector):
# Return face_detector # Return face_detector
return YOLO(weight_path) return YOLO(weight_path)
def detect_faces(self, img: np.ndarray, align: bool = False) -> list: def detect_faces(
self, img: np.ndarray, align: bool = False
) -> List[Tuple[np.ndarray, List[float], float]]:
""" """
Detect and align face with yolo Detect and align face with yolo
Args: Args:
@ -58,7 +61,19 @@ class Yolo(Detector):
img (np.ndarray): pre-loaded image img (np.ndarray): pre-loaded image
align (bool): default is true align (bool): default is true
Returns: Returns:
list of detected and aligned faces results (List[Tuple[np.ndarray, List[float], float]]): A list of tuples
where each tuple contains:
- detected_face (np.ndarray): The detected face as a NumPy array.
- face_region (List[float]): The image region represented as
a list of floats e.g. [x, y, w, h]
- confidence (float): The confidence score associated with the detected face.
Example:
results = [
(array(..., dtype=uint8), [110, 60, 150, 380], 0.99),
(array(..., dtype=uint8), [150, 50, 299, 375], 0.98),
(array(..., dtype=uint8), [120, 55, 300, 371], 0.96),
]
""" """
resp = [] resp = []
@ -85,7 +100,7 @@ class Yolo(Detector):
left_eye[1] > LANDMARKS_CONFIDENCE_THRESHOLD left_eye[1] > LANDMARKS_CONFIDENCE_THRESHOLD
and right_eye[1] > LANDMARKS_CONFIDENCE_THRESHOLD and right_eye[1] > LANDMARKS_CONFIDENCE_THRESHOLD
): ):
detected_face = self.align_face( detected_face = detection.align_face(
img=detected_face, left_eye=left_eye[0].cpu(), right_eye=right_eye[0].cpu() img=detected_face, left_eye=left_eye[0].cpu(), right_eye=right_eye[0].cpu()
) )
resp.append((detected_face, [x, y, w, h], confidence)) resp.append((detected_face, [x, y, w, h], confidence))

View File

@ -1,16 +1,17 @@
import os import os
from typing import Any from typing import Any, List, Tuple
import cv2 import cv2
import numpy as np import numpy as np
import gdown import gdown
from deepface.commons import functions from deepface.commons import functions
from deepface.commons.logger import Logger
from deepface.models.Detector import Detector from deepface.models.Detector import Detector
from deepface.modules import detection
from deepface.commons.logger import Logger
logger = Logger(module="detectors.YunetWrapper") logger = Logger(module="detectors.YunetWrapper")
class YuNet(Detector): class YuNetClient(Detector):
def __init__(self): def __init__(self):
self.model = self.build_model() self.model = self.build_model()
@ -41,14 +42,28 @@ class YuNet(Detector):
) from err ) from err
return face_detector return face_detector
def detect_faces(self, img: np.ndarray, align: bool = True) -> list: def detect_faces(
self, img: np.ndarray, align: bool = True
) -> List[Tuple[np.ndarray, List[float], float]]:
""" """
Detect and align face with yunet Detect and align face with yunet
Args: Args:
img (np.ndarray): pre-loaded image img (np.ndarray): pre-loaded image
align (bool): default is true align (bool): default is true
Returns: Returns:
list of detected and aligned faces results (List[Tuple[np.ndarray, List[float], float]]): A list of tuples
where each tuple contains:
- detected_face (np.ndarray): The detected face as a NumPy array.
- face_region (List[float]): The image region represented as
a list of floats e.g. [x, y, w, h]
- confidence (float): The confidence score associated with the detected face.
Example:
results = [
(array(..., dtype=uint8), [110, 60, 150, 380], 0.99),
(array(..., dtype=uint8), [150, 50, 299, 375], 0.98),
(array(..., dtype=uint8), [120, 55, 300, 371], 0.96),
]
""" """
# FaceDetector.detect_faces does not support score_threshold parameter. # FaceDetector.detect_faces does not support score_threshold parameter.
# We can set it via environment variable. # We can set it via environment variable.
@ -107,6 +122,6 @@ class YuNet(Detector):
detected_face = img[int(y) : int(y + h), int(x) : int(x + w)] detected_face = img[int(y) : int(y + h), int(x) : int(x + w)]
img_region = [x, y, w, h] img_region = [x, y, w, h]
if align: if align:
detected_face = self.align_face(detected_face, (x_re, y_re), (x_le, y_le)) detected_face = detection.align_face(detected_face, (x_re, y_re), (x_le, y_le))
resp.append((detected_face, img_region, confidence)) resp.append((detected_face, img_region, confidence))
return resp return resp

View File

@ -23,7 +23,7 @@ else:
# ---------------------------------------- # ----------------------------------------
# pylint: disable=too-few-public-methods # pylint: disable=too-few-public-methods
class ApparentAge(Demography): class ApparentAgeClient(Demography):
""" """
Age model class Age model class
""" """

View File

@ -33,7 +33,7 @@ else:
labels = ["angry", "disgust", "fear", "happy", "sad", "surprise", "neutral"] labels = ["angry", "disgust", "fear", "happy", "sad", "surprise", "neutral"]
# pylint: disable=too-few-public-methods # pylint: disable=too-few-public-methods
class FacialExpression(Demography): class EmotionClient(Demography):
""" """
Emotion model class Emotion model class
""" """

View File

@ -26,7 +26,7 @@ else:
labels = ["Woman", "Man"] labels = ["Woman", "Man"]
# pylint: disable=too-few-public-methods # pylint: disable=too-few-public-methods
class Gender(Demography): class GenderClient(Demography):
""" """
Gender model class Gender model class
""" """

View File

@ -25,7 +25,7 @@ else:
labels = ["asian", "indian", "black", "white", "middle eastern", "latino hispanic"] labels = ["asian", "indian", "black", "white", "middle eastern", "latino hispanic"]
# pylint: disable=too-few-public-methods # pylint: disable=too-few-public-methods
class Race(Demography): class RaceClient(Demography):
""" """
Race model class Race model class
""" """

View File

@ -1,39 +1,34 @@
from typing import List, Tuple
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from typing import Union
import numpy as np import numpy as np
from PIL import Image
# Notice that all facial detector models must be inherited from this class # Notice that all facial detector models must be inherited from this class
# pylint: disable=unnecessary-pass, too-few-public-methods
class Detector(ABC): class Detector(ABC):
@abstractmethod @abstractmethod
def detect_faces(self, img: np.ndarray, align: bool = True) -> list: def detect_faces(
pass self, img: np.ndarray, align: bool = True
) -> List[Tuple[np.ndarray, List[float], float]]:
def align_face(
self, img: np.ndarray, left_eye: Union[list, tuple], right_eye: Union[list, tuple]
) -> np.ndarray:
""" """
Align a given image horizantally with respect to their left and right eye locations Detect faces from a given image
Args: Args:
img (np.ndarray): pre-loaded image with detected face img (np.ndarray): pre-loaded image as a NumPy array
left_eye (list or tuple): coordinates of left eye with respect to the you align (bool): enable or disable alignment after face detection
right_eye(list or tuple): coordinates of right eye with respect to the you
Returns: Returns:
img (np.ndarray): aligned facial image results (List[Tuple[np.ndarray, List[float], float]]): A list of tuples
where each tuple contains:
- detected_face (np.ndarray): The detected face as a NumPy array.
- face_region (List[float]): The image region represented as
a list of floats e.g. [x, y, w, h]
- confidence (float): The confidence score associated with the detected face.
Example:
results = [
(array(..., dtype=uint8), [110, 60, 150, 380], 0.99),
(array(..., dtype=uint8), [150, 50, 299, 375], 0.98),
(array(..., dtype=uint8), [120, 55, 300, 371], 0.96),
]
""" """
# if eye could not be detected for the given image, return image itself pass
if left_eye is None or right_eye is None:
return img
# sometimes unexpectedly detected images come with nil dimensions
if img.shape[0] == 0 or img.shape[1] == 0:
return img
angle = float(
np.degrees(np.arctan2(right_eye[1] - left_eye[1], right_eye[0] - left_eye[0]))
)
img = Image.fromarray(img)
img = np.array(img.rotate(angle))
return img

View File

@ -1,5 +1,5 @@
from abc import ABC from abc import ABC, abstractmethod
from typing import Any, Union from typing import Any, Union, List
import numpy as np import numpy as np
from deepface.commons import functions from deepface.commons import functions
@ -16,13 +16,6 @@ class FacialRecognition(ABC):
model: Union[Model, Any] model: Union[Model, Any]
model_name: str model_name: str
def find_embeddings(self, img: np.ndarray) -> list: @abstractmethod
if not isinstance(self.model, Model): def find_embeddings(self, img: np.ndarray) -> List[float]:
raise ValueError( pass
"If a facial recognition model is not type of (tf.)keras.models.Model,"
"Then its find_embeddings method must be implemented its own module."
f"However {self.model_name}'s model type is {type(self.model)}"
)
# model.predict causes memory issue when it is called in a for loop
# embedding = model.predict(img, verbose=0)[0].tolist()
return self.model(img, training=False).numpy()[0].tolist()

View File

@ -3,6 +3,7 @@ from typing import Any, Dict, List, Tuple, Union
# 3rd part dependencies # 3rd part dependencies
import numpy as np import numpy as np
from PIL import Image
# project dependencies # project dependencies
from deepface.commons import functions from deepface.commons import functions
@ -40,8 +41,11 @@ def extract_faces(
grayscale (boolean): extracting faces in rgb or gray scale grayscale (boolean): extracting faces in rgb or gray scale
Returns: Returns:
list of dictionaries. Each dictionary will have facial image itself (RGB), results (List[Dict[str, Any]]): A list of dictionaries, where each dictionary contains:
extracted area from the original image and confidence score. - "face" (np.ndarray): The detected face as a NumPy array.
- "facial_area" (List[float]): The detected face's regions represented as a list of floats.
- "confidence" (float): The confidence score associated with the detected face.
""" """
@ -70,3 +74,31 @@ def extract_faces(
resp_objs.append(resp_obj) resp_objs.append(resp_obj)
return resp_objs return resp_objs
def align_face(
img: np.ndarray,
left_eye: Union[list, tuple],
right_eye: Union[list, tuple],
) -> np.ndarray:
"""
Align a given image horizantally with respect to their left and right eye locations
Args:
img (np.ndarray): pre-loaded image with detected face
left_eye (list or tuple): coordinates of left eye with respect to the you
right_eye(list or tuple): coordinates of right eye with respect to the you
Returns:
img (np.ndarray): aligned facial image
"""
# if eye could not be detected for the given image, return image itself
if left_eye is None or right_eye is None:
return img
# sometimes unexpectedly detected images come with nil dimensions
if img.shape[0] == 0 or img.shape[1] == 0:
return img
angle = float(np.degrees(np.arctan2(right_eye[1] - left_eye[1], right_eye[0] - left_eye[0])))
img = Image.fromarray(img)
img = np.array(img.rotate(angle))
return img

View File

@ -2,16 +2,7 @@
from typing import Any from typing import Any
# project dependencies # project dependencies
from deepface.basemodels import ( from deepface.basemodels import VGGFace, OpenFace, FbDeepFace, DeepID, ArcFace, SFace, Dlib, Facenet
VGGFace,
OpenFace,
Facenet,
FbDeepFace,
DeepID,
DlibResNet,
ArcFace,
SFace,
)
from deepface.extendedmodels import Age, Gender, Race, Emotion from deepface.extendedmodels import Age, Gender, Race, Emotion
@ -31,19 +22,19 @@ def build_model(model_name: str) -> Any:
global model_obj global model_obj
models = { models = {
"VGG-Face": VGGFace.VggFace, "VGG-Face": VGGFace.VggFaceClient,
"OpenFace": OpenFace.OpenFace, "OpenFace": OpenFace.OpenFaceClient,
"Facenet": Facenet.FaceNet128d, "Facenet": Facenet.FaceNet128dClient,
"Facenet512": Facenet.FaceNet512d, "Facenet512": Facenet.FaceNet512dClient,
"DeepFace": FbDeepFace.DeepFace, "DeepFace": FbDeepFace.DeepFaceClient,
"DeepID": DeepID.DeepId, "DeepID": DeepID.DeepIdClient,
"Dlib": DlibResNet.Dlib, "Dlib": Dlib.DlibClient,
"ArcFace": ArcFace.ArcFace, "ArcFace": ArcFace.ArcFaceClient,
"SFace": SFace.SFace, "SFace": SFace.SFaceClient,
"Emotion": Emotion.FacialExpression, "Emotion": Emotion.EmotionClient,
"Age": Age.ApparentAge, "Age": Age.ApparentAgeClient,
"Gender": Gender.Gender, "Gender": Gender.GenderClient,
"Race": Race.Race, "Race": Race.RaceClient,
} }
if not "model_obj" in globals(): if not "model_obj" in globals():

View File

@ -14,11 +14,12 @@ model_names = [
"Facenet512", "Facenet512",
"OpenFace", "OpenFace",
"DeepFace", "DeepFace",
"DeepID", # "DeepID",
"Dlib", "Dlib",
"ArcFace", "ArcFace",
"SFace", "SFace",
] ]
detector_backends = ["opencv", "ssd", "dlib", "mtcnn", "retinaface"] detector_backends = ["opencv", "ssd", "dlib", "mtcnn", "retinaface"]
@ -44,10 +45,11 @@ dfs = DeepFace.find(
for df in dfs: for df in dfs:
logger.info(df) logger.info(df)
# extract faces # extract faces
for detector_backend in detector_backends: for detector_backend in detector_backends:
face_objs = DeepFace.extract_faces( face_objs = DeepFace.extract_faces(
img_path="dataset/img1.jpg", detector_backend=detector_backend img_path="dataset/img11.jpg", detector_backend=detector_backend
) )
for face_obj in face_objs: for face_obj in face_objs:
face = face_obj["face"] face = face_obj["face"]