From c66804717cdec4e3f18597cdf9787e7ab3c1f5d1 Mon Sep 17 00:00:00 2001 From: Sefik Ilkin Serengil Date: Wed, 17 Jul 2024 17:00:55 +0100 Subject: [PATCH 1/2] adding max_faces argument to represent --- deepface/DeepFace.py | 6 +++++- deepface/api/src/modules/core/routes.py | 1 + deepface/api/src/modules/core/service.py | 3 +++ deepface/modules/representation.py | 22 +++++++++++++++------- 4 files changed, 24 insertions(+), 8 deletions(-) diff --git a/deepface/DeepFace.py b/deepface/DeepFace.py index a81f8f1..803616f 100644 --- a/deepface/DeepFace.py +++ b/deepface/DeepFace.py @@ -359,6 +359,7 @@ def represent( expand_percentage: int = 0, normalization: str = "base", anti_spoofing: bool = False, + max_faces: Optional[int] = None, ) -> List[Dict[str, Any]]: """ Represent facial images as multi-dimensional vector embeddings. @@ -390,6 +391,8 @@ def represent( anti_spoofing (boolean): Flag to enable anti spoofing (default is False). + max_faces (int): Set a limit on the number of faces to be processed (default is None). + Returns: results (List[Dict[str, Any]]): A list of dictionaries, each containing the following fields: @@ -415,6 +418,7 @@ def represent( expand_percentage=expand_percentage, normalization=normalization, anti_spoofing=anti_spoofing, + max_faces=max_faces, ) @@ -483,7 +487,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]]: diff --git a/deepface/api/src/modules/core/routes.py b/deepface/api/src/modules/core/routes.py index 98f624a..8d68acc 100644 --- a/deepface/api/src/modules/core/routes.py +++ b/deepface/api/src/modules/core/routes.py @@ -31,6 +31,7 @@ def represent(): enforce_detection=input_args.get("enforce_detection", True), align=input_args.get("align", True), anti_spoofing=input_args.get("anti_spoofing", False), + max_faces=input_args.get("max_faces"), ) logger.debug(obj) diff --git a/deepface/api/src/modules/core/service.py b/deepface/api/src/modules/core/service.py index 4188229..2994300 100644 --- a/deepface/api/src/modules/core/service.py +++ b/deepface/api/src/modules/core/service.py @@ -1,5 +1,6 @@ # built-in dependencies import traceback +from typing import Optional # project dependencies from deepface import DeepFace @@ -14,6 +15,7 @@ def represent( enforce_detection: bool, align: bool, anti_spoofing: bool, + max_faces: Optional[int] = None, ): try: result = {} @@ -24,6 +26,7 @@ def represent( enforce_detection=enforce_detection, align=align, anti_spoofing=anti_spoofing, + max_faces=max_faces, ) result["results"] = embedding_objs return result diff --git a/deepface/modules/representation.py b/deepface/modules/representation.py index b228288..0bba083 100644 --- a/deepface/modules/representation.py +++ b/deepface/modules/representation.py @@ -1,5 +1,5 @@ # built-in dependencies -from typing import Any, Dict, List, Union +from typing import Any, Dict, List, Union, Optional # 3rd party dependencies import numpy as np @@ -19,6 +19,7 @@ def represent( expand_percentage: int = 0, normalization: str = "base", anti_spoofing: bool = False, + max_faces: Optional[int] = None, ) -> List[Dict[str, Any]]: """ Represent facial images as multi-dimensional vector embeddings. @@ -46,6 +47,8 @@ def represent( anti_spoofing (boolean): Flag to enable anti spoofing (default is False). + max_faces (int): Set a limit on the number of faces to be processed (default is None). + Returns: results (List[Dict[str, Any]]): A list of dictionaries, each containing the following fields: @@ -94,7 +97,7 @@ def represent( ] # --------------------------------- - for img_obj in img_objs: + for idx, img_obj in enumerate(img_objs): if anti_spoofing is True and img_obj.get("is_real", True) is False: raise ValueError("Spoof detected in the given image.") img = img_obj["face"] @@ -117,10 +120,15 @@ def represent( embedding = model.forward(img) - resp_obj = {} - resp_obj["embedding"] = embedding - resp_obj["facial_area"] = region - resp_obj["face_confidence"] = confidence - resp_objs.append(resp_obj) + resp_objs.append( + { + "embedding": embedding, + "facial_area": region, + "face_confidence": confidence, + } + ) + + if max_faces is not None and max_faces > 0 and max_faces > idx + 1: + break return resp_objs From 010bb2b1f01d6045171fdb6504b9283329a4fcff Mon Sep 17 00:00:00 2001 From: Sefik Ilkin Serengil Date: Wed, 17 Jul 2024 17:23:23 +0100 Subject: [PATCH 2/2] get max_faces number faces from largest --- deepface/modules/representation.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/deepface/modules/representation.py b/deepface/modules/representation.py index 0bba083..5a1036b 100644 --- a/deepface/modules/representation.py +++ b/deepface/modules/representation.py @@ -97,7 +97,17 @@ def represent( ] # --------------------------------- - for idx, img_obj in enumerate(img_objs): + if max_faces is not None and max_faces < len(img_objs): + # sort as largest facial areas come first + img_objs = sorted( + img_objs, + key=lambda img_obj: img_obj["facial_area"]["w"] * img_obj["facial_area"]["h"], + reverse=True, + ) + # discard rest of the items + img_objs = img_objs[0:max_faces] + + for img_obj in img_objs: if anti_spoofing is True and img_obj.get("is_real", True) is False: raise ValueError("Spoof detected in the given image.") img = img_obj["face"] @@ -128,7 +138,4 @@ def represent( } ) - if max_faces is not None and max_faces > 0 and max_faces > idx + 1: - break - return resp_objs