Skip to content

Commit

Permalink
yolov11n and yolov11m added to model selection
Browse files Browse the repository at this point in the history
  • Loading branch information
roberto-corno-nttdata committed Dec 7, 2024
1 parent 2c2dc7b commit 38261e0
Show file tree
Hide file tree
Showing 15 changed files with 173 additions and 86 deletions.
4 changes: 2 additions & 2 deletions benchmarks/Evaluate-Results.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@
"outputs": [],
"source": [
"alignment = [False, True]\n",
"models = [\"Facenet512\", \"Facenet\", \"VGG-Face\", \"ArcFace\", \"Dlib\", \"GhostFaceNet\", \"SFace\", \"OpenFace\", \"DeepFace\", \"DeepID\"]\n",
"detectors = [\"retinaface\", \"mtcnn\", \"fastmtcnn\", \"dlib\", \"yolov8\", \"yolov11n\", \"yolov11m\", \"yunet\", \"centerface\", \"mediapipe\", \"ssd\", \"opencv\", \"skip\"]\n",
"models = [\"Facenet512\", \"Facenet\", \"VGG-Face\", \"ArcFace\", \"Dlib\", \"GhostFaceNet\", \"SFace\", \"OpenFace\", \"DeepFace\", \"DeepID\", \"yolov8\", \"yolov11n\", \"yolov11s\", \"yolov11m\"]\n",
"detectors = [\"retinaface\", \"mtcnn\", \"fastmtcnn\", \"dlib\", \"yolov8\", \"yolov11n\", \"yolov11s\", \"yolov11m\", \"yunet\", \"centerface\", \"mediapipe\", \"ssd\", \"opencv\", \"skip\"]\n",
"distance_metrics = [\"euclidean\", \"euclidean_l2\", \"cosine\"]"
]
},
Expand Down
16 changes: 8 additions & 8 deletions deepface/DeepFace.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def build_model(model_name: str, task: str = "facial_recognition") -> Any:
- 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, 'yolov11n', 'yolov11m', yunet,
- opencv, mtcnn, ssd, dlib, retinaface, mediapipe, yolov8, 'yolov11n', 'yolov11s','yolov11m', yunet,
fastmtcnn or centerface for face detectors
- Fasnet for spoofing
task (str): facial_recognition, facial_attribute, face_detector, spoofing
Expand Down Expand Up @@ -96,7 +96,7 @@ def verify(
OpenFace, DeepFace, DeepID, Dlib, ArcFace, SFace and GhostFaceNet (default is VGG-Face).
detector_backend (string): face detector backend. Options: 'opencv', 'retinaface',
'mtcnn', 'ssd', 'dlib', 'mediapipe', 'yolov8', 'yolov11n', 'yolov11m', 'centerface' or 'skip'
'mtcnn', 'ssd', 'dlib', 'mediapipe', 'yolov8', 'yolov11n', 'yolov11s', 'yolov11m', 'centerface' or 'skip'
(default is opencv).
distance_metric (string): Metric for measuring similarity. Options: 'cosine',
Expand Down Expand Up @@ -187,7 +187,7 @@ def analyze(
Set to False to avoid the exception for low-resolution images (default is True).
detector_backend (string): face detector backend. Options: 'opencv', 'retinaface',
'mtcnn', 'ssd', 'dlib', 'mediapipe', 'yolov8', 'yolov11n', 'yolov11m', 'centerface' or 'skip'
'mtcnn', 'ssd', 'dlib', 'mediapipe', 'yolov8', 'yolov11n', 'yolov11s', 'yolov11m', 'centerface' or 'skip'
(default is opencv).
distance_metric (string): Metric for measuring similarity. Options: 'cosine',
Expand Down Expand Up @@ -298,7 +298,7 @@ def find(
Set to False to avoid the exception for low-resolution images (default is True).
detector_backend (string): face detector backend. Options: 'opencv', 'retinaface',
'mtcnn', 'ssd', 'dlib', 'mediapipe', 'yolov8', 'yolov11n', 'yolov11m', 'centerface' or 'skip'
'mtcnn', 'ssd', 'dlib', 'mediapipe', 'yolov8', 'yolov11n', 'yolov11s', 'yolov11m', 'centerface' or 'skip'
(default is opencv).
align (boolean): Perform alignment based on the eye positions (default is True).
Expand Down Expand Up @@ -396,7 +396,7 @@ def represent(
(default is True).
detector_backend (string): face detector backend. Options: 'opencv', 'retinaface',
'mtcnn', 'ssd', 'dlib', 'mediapipe', 'yolov8', 'yolov11n', 'yolov11m', 'centerface' or 'skip'
'mtcnn', 'ssd', 'dlib', 'mediapipe', 'yolov8', 'yolov11n', 'yolov11s', 'yolov11m', 'centerface' or 'skip'
(default is opencv).
align (boolean): Perform alignment based on the eye positions (default is True).
Expand Down Expand Up @@ -462,7 +462,7 @@ def stream(
OpenFace, DeepFace, DeepID, Dlib, ArcFace, SFace and GhostFaceNet (default is VGG-Face).
detector_backend (string): face detector backend. Options: 'opencv', 'retinaface',
'mtcnn', 'ssd', 'dlib', 'mediapipe', 'yolov8', 'yolov11n', 'yolov11m', 'centerface' or 'skip'
'mtcnn', 'ssd', 'dlib', 'mediapipe', 'yolov8', 'yolov11n', 'yolov11s', 'yolov11m', 'centerface' or 'skip'
(default is opencv).
distance_metric (string): Metric for measuring similarity. Options: 'cosine',
Expand Down Expand Up @@ -517,7 +517,7 @@ def extract_faces(
as a string, numpy array (BGR), or base64 encoded images.
detector_backend (string): face detector backend. Options: 'opencv', 'retinaface',
'mtcnn', 'ssd', 'dlib', 'mediapipe', 'yolov8', 'yolov11n', 'yolov11m', 'centerface' or 'skip'
'mtcnn', 'ssd', 'dlib', 'mediapipe', 'yolov8', 'yolov11n', 'yolov11s', 'yolov11m', 'centerface' or 'skip'
(default is opencv).
enforce_detection (boolean): If no face is detected in an image, raise an exception.
Expand Down Expand Up @@ -601,7 +601,7 @@ def detectFace(
added to resize the image (default is (224, 224)).
detector_backend (string): face detector backend. Options: 'opencv', 'retinaface',
'mtcnn', 'ssd', 'dlib', 'mediapipe', 'yolov8', 'yolov11n', 'yolov11m', 'centerface' or 'skip'
'mtcnn', 'ssd', 'dlib', 'mediapipe', 'yolov8', 'yolov11n', 'yolov11s', 'yolov11m', 'centerface' or 'skip'
(default is opencv).
enforce_detection (boolean): If no face is detected in an image, raise an exception.
Expand Down
6 changes: 5 additions & 1 deletion deepface/commons/weight_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ def download_all_models_in_one_shot() -> None:
MODEL_URL as SSD_MODEL,
WEIGHTS_URL as SSD_WEIGHTS,
)
from deepface.models.face_detection.Yolo import (
from deepface.models.YoloModel import (
WEIGHT_URLS as YOLO_WEIGHTS,
WEIGHT_NAMES as YOLO_WEIGHT_NAMES,
YoloModel
Expand Down Expand Up @@ -170,6 +170,10 @@ def download_all_models_in_one_shot() -> None:
"filename": YOLO_WEIGHT_NAMES[YoloModel.V11N.value],
"url": YOLO_WEIGHTS[YoloModel.V11N.value],
},
{
"filename": YOLO_WEIGHT_NAMES[YoloModel.V11S.value],
"url": YOLO_WEIGHTS[YoloModel.V11S.value],
},
{
"filename": YOLO_WEIGHT_NAMES[YoloModel.V11M.value],
"url": YOLO_WEIGHTS[YoloModel.V11M.value],
Expand Down
37 changes: 37 additions & 0 deletions deepface/models/YoloClientBase.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# built-in dependencies
from typing import Any

# project dependencies
from deepface.models.YoloModel import YoloModel, WEIGHT_URLS, WEIGHT_NAMES
from deepface.commons import weight_utils
from deepface.commons.logger import Logger

logger = Logger()


class YoloClientBase:
def __init__(self, model: YoloModel):
self.model = self.build_model(model)

def build_model(self, model: YoloModel) -> Any:
"""
Build a yolo detector model
Returns:
model (Any)
"""

# Import the optional Ultralytics YOLO model
try:
from ultralytics import YOLO
except ModuleNotFoundError as e:
raise ImportError(
"Yolo is an optional detector, ensure the library is installed. "
"Please install using 'pip install ultralytics'"
) from e

weight_file = weight_utils.download_weights_if_necessary(
file_name=WEIGHT_NAMES[model.value], source_url=WEIGHT_URLS[model.value]
)

# Return face_detector
return YOLO(weight_file)
21 changes: 21 additions & 0 deletions deepface/models/YoloModel.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
from enum import Enum


class YoloModel(Enum):
V8N = 0
V11N = 1
V11S = 2
V11M = 3


# Model's weights paths
WEIGHT_NAMES = ["yolov8n-face.pt",
"yolov11n-face.pt",
"yolov11s-face.pt",
"yolov11m-face.pt"]

# Google Drive URL from repo (https://github.com/derronqi/yolov8-face) ~6MB
WEIGHT_URLS = ["https://drive.google.com/uc?id=1qcr9DbgsX3ryrz2uU8w4Xm3cOrRywXqb",
"https://github.com/akanametov/yolo-face/releases/download/v0.0.0/yolov11n-face.pt",
"https://github.com/akanametov/yolo-face/releases/download/v0.0.0/yolov11s-face.pt",
"https://github.com/akanametov/yolo-face/releases/download/v0.0.0/yolov11m-face.pt"]
79 changes: 24 additions & 55 deletions deepface/models/face_detection/Yolo.py
Original file line number Diff line number Diff line change
@@ -1,61 +1,22 @@
# built-in dependencies
import os
from typing import Any, List
from enum import Enum
from typing import List

# 3rd party dependencies
import numpy as np

# project dependencies
from deepface.models.YoloClientBase import YoloClientBase
from deepface.models.YoloModel import YoloModel
from deepface.models.Detector import Detector, FacialAreaRegion
from deepface.commons import weight_utils
from deepface.commons.logger import Logger

logger = Logger()

# Model's weights paths
WEIGHT_NAMES = ["yolov8n-face.pt",
"yolov11n-face.pt",
"yolov11m-face.pt"]

# Google Drive URL from repo (https://github.com/derronqi/yolov8-face) ~6MB
WEIGHT_URLS = ["https://drive.google.com/uc?id=1qcr9DbgsX3ryrz2uU8w4Xm3cOrRywXqb",
"https://github.com/akanametov/yolo-face/releases/download/v0.0.0/yolov11n-face.pt",
"https://github.com/akanametov/yolo-face/releases/download/v0.0.0/yolov11m-face.pt"]


class YoloModel(Enum):
V8N = 0
V11N = 1
V11M = 2


class YoloClient(Detector):
class YoloDetectorClient(YoloClientBase, Detector):
def __init__(self, model: YoloModel):
self.model = self.build_model(model)

def build_model(self, model: YoloModel) -> Any:
"""
Build a yolo detector model
Returns:
model (Any)
"""

# Import the optional Ultralytics YOLO model
try:
from ultralytics import YOLO
except ModuleNotFoundError as e:
raise ImportError(
"Yolo is an optional detector, ensure the library is installed. "
"Please install using 'pip install ultralytics'"
) from e

weight_file = weight_utils.download_weights_if_necessary(
file_name=WEIGHT_NAMES[model.value], source_url=WEIGHT_URLS[model.value]
)

# Return face_detector
return YOLO(weight_file)
super().__init__(model)

def detect_faces(self, img: np.ndarray) -> List[FacialAreaRegion]:
"""
Expand All @@ -80,21 +41,24 @@ def detect_faces(self, img: np.ndarray) -> List[FacialAreaRegion]:
# For each face, extract the bounding box, the landmarks and confidence
for result in results:

if result.boxes is None or result.keypoints is None:
if result.boxes is None:
continue

# Extract the bounding box and the confidence
x, y, w, h = result.boxes.xywh.tolist()[0]
confidence = result.boxes.conf.tolist()[0]

# right_eye_conf = result.keypoints.conf[0][0]
# left_eye_conf = result.keypoints.conf[0][1]
right_eye = result.keypoints.xy[0][0].tolist()
left_eye = result.keypoints.xy[0][1].tolist()
right_eye = None
left_eye = None
if result.keypoints is not None:
# right_eye_conf = result.keypoints.conf[0][0]
# left_eye_conf = result.keypoints.conf[0][1]
right_eye = result.keypoints.xy[0][0].tolist()
left_eye = result.keypoints.xy[0][1].tolist()

# eyes are list of float, need to cast them tuple of int
left_eye = tuple(int(i) for i in left_eye)
right_eye = tuple(int(i) for i in right_eye)
# eyes are list of float, need to cast them tuple of int
left_eye = tuple(int(i) for i in left_eye)
right_eye = tuple(int(i) for i in right_eye)

x, y, w, h = int(x - w / 2), int(y - h / 2), int(w), int(h)
facial_area = FacialAreaRegion(
Expand All @@ -111,16 +75,21 @@ def detect_faces(self, img: np.ndarray) -> List[FacialAreaRegion]:
return resp


class YoloClientV8n(YoloClient):
class YoloDetectorClientV8n(YoloDetectorClient):
def __init__(self):
super().__init__(YoloModel.V8N)


class YoloClientV11n(YoloClient):
class YoloDetectorClientV11n(YoloDetectorClient):
def __init__(self):
super().__init__(YoloModel.V11N)


class YoloClientV11m(YoloClient):
class YoloDetectorClientV11s(YoloDetectorClient):
def __init__(self):
super().__init__(YoloModel.V11S)


class YoloDetectorClientV11m(YoloDetectorClient):
def __init__(self):
super().__init__(YoloModel.V11M)
44 changes: 44 additions & 0 deletions deepface/models/facial_recognition/Yolo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# built-in dependencies
from typing import List

# 3rd party dependencies
import numpy as np

# project dependencies
from deepface.models.YoloClientBase import YoloClientBase
from deepface.models.YoloModel import YoloModel
from deepface.models.FacialRecognition import FacialRecognition
from deepface.commons.logger import Logger

logger = Logger()


class YoloFacialRecognitionClient(YoloClientBase, FacialRecognition):
def __init__(self, model: YoloModel):
super().__init__(model)
self.model_name = "Yolo"
self.input_shape = None
self.output_shape = 512

def forward(self, img: np.ndarray) -> List[float]:
return self.model.embed(img)[0].tolist()


class YoloFacialRecognitionClientV8n(YoloFacialRecognitionClient):
def __init__(self):
super().__init__(YoloModel.V8N)


class YoloFacialRecognitionClientV11n(YoloFacialRecognitionClient):
def __init__(self):
super().__init__(YoloModel.V11N)


class YoloFacialRecognitionClientV11s(YoloFacialRecognitionClient):
def __init__(self):
super().__init__(YoloModel.V11S)


class YoloFacialRecognitionClientV11m(YoloFacialRecognitionClient):
def __init__(self):
super().__init__(YoloModel.V11M)
2 changes: 1 addition & 1 deletion deepface/modules/demography.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def analyze(
Set to False to avoid the exception for low-resolution images (default is True).
detector_backend (string): face detector backend. Options: 'opencv', 'retinaface',
'mtcnn', 'ssd', 'dlib', 'mediapipe', 'yolov8', 'yolov11n', 'yolov11m', 'centerface' or 'skip'
'mtcnn', 'ssd', 'dlib', 'mediapipe', 'yolov8', 'yolov11n', 'yolov11s', 'yolov11m', 'centerface' or 'skip'
(default is opencv).
distance_metric (string): Metric for measuring similarity. Options: 'cosine',
Expand Down
2 changes: 1 addition & 1 deletion deepface/modules/detection.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def extract_faces(
as a string, numpy array (BGR), or base64 encoded images.
detector_backend (string): face detector backend. Options: 'opencv', 'retinaface',
'mtcnn', 'ssd', 'dlib', 'mediapipe', 'yolov8', 'yolov11n', 'yolov11m', 'centerface' or 'skip'
'mtcnn', 'ssd', 'dlib', 'mediapipe', 'yolov8', 'yolov11n', 'yolov11s', 'yolov11m', 'centerface' or 'skip'
(default is opencv)
enforce_detection (boolean): If no face is detected in an image, raise an exception.
Expand Down
Loading

0 comments on commit 38261e0

Please sign in to comment.