diff --git a/deepface/DeepFace.py b/deepface/DeepFace.py index e9f6d9d21..c8920d80e 100644 --- a/deepface/DeepFace.py +++ b/deepface/DeepFace.py @@ -4,6 +4,11 @@ import logging from typing import Any, Dict, List, Tuple, Union, Optional +# this has to be set before importing tensorflow +os.environ["TF_USE_LEGACY_KERAS"] = "1" + +# pylint: disable=wrong-import-position + # 3rd party dependencies import numpy as np import pandas as pd @@ -28,6 +33,9 @@ # ----------------------------------- # configurations for dependencies +# users should install tf_keras package if they are using tf 2.16 or later versions +package_utils.validate_for_keras3() + warnings.filterwarnings("ignore") os.environ["TF_CPP_MIN_LOG_LEVEL"] = "3" tf_version = package_utils.get_tf_major_version() diff --git a/deepface/basemodels/FbDeepFace.py b/deepface/basemodels/FbDeepFace.py index 278f5cce9..5e41c7d2d 100644 --- a/deepface/basemodels/FbDeepFace.py +++ b/deepface/basemodels/FbDeepFace.py @@ -23,6 +23,7 @@ Flatten, Dense, Dropout, + LocallyConnected2D, ) else: from tensorflow.keras.models import Model, Sequential @@ -32,6 +33,7 @@ Flatten, Dense, Dropout, + LocallyConnected2D, ) @@ -43,14 +45,6 @@ class DeepFaceClient(FacialRecognition): """ def __init__(self): - # DeepFace requires tf 2.12 or less - if tf_major == 2 and tf_minor > 12: - # Ref: https://github.com/serengil/deepface/pull/1079 - raise ValueError( - "DeepFace model requires LocallyConnected2D but it is no longer supported" - f" after tf 2.12 but you have {tf_major}.{tf_minor}. You need to downgrade your tf." - ) - self.model = load_model() self.model_name = "DeepFace" self.input_shape = (152, 152) @@ -75,13 +69,6 @@ def load_model( """ Construct DeepFace model, download its weights and load """ - # we have some checks for this dependency in the init of client - # putting this in global causes library initialization - if tf_major == 1: - from keras.layers import LocallyConnected2D - else: - from tensorflow.keras.layers import LocallyConnected2D - base_model = Sequential() base_model.add( Convolution2D(32, (11, 11), activation="relu", name="C1", input_shape=(152, 152, 3)) diff --git a/deepface/commons/package_utils.py b/deepface/commons/package_utils.py index 20fa35e1b..1620732f9 100644 --- a/deepface/commons/package_utils.py +++ b/deepface/commons/package_utils.py @@ -50,3 +50,24 @@ def find_hash_of_file(file_path: str) -> str: hasher = hashlib.sha1() hasher.update(properties.encode("utf-8")) return hasher.hexdigest() + + +def validate_for_keras3(): + tf_major = get_tf_major_version() + tf_minor = get_tf_minor_version() + + # tf_keras is a must dependency after tf 2.16 + if tf_major == 1 or (tf_major == 2 and tf_minor < 16): + return + + try: + import tf_keras + + logger.debug(f"tf_keras is already available - {tf_keras.__version__}") + except ImportError as err: + # you may consider to install that package here + raise ValueError( + f"You have tensorflow {tf.__version__} and this requires " + "tf-keras package. Please run `pip install tf-keras` " + "or downgrade your tensorflow." + ) from err diff --git a/deepface/detectors/OpenCv.py b/deepface/detectors/OpenCv.py index cf0e8d7ff..93d2492e1 100644 --- a/deepface/detectors/OpenCv.py +++ b/deepface/detectors/OpenCv.py @@ -53,6 +53,14 @@ def detect_faces(self, img: np.ndarray) -> List[FacialAreaRegion]: for (x, y, w, h), confidence in zip(faces, scores): detected_face = img[int(y) : int(y + h), int(x) : int(x + w)] left_eye, right_eye = self.find_eyes(img=detected_face) + + # eyes found in the detected face instead image itself + # detected face's coordinates should be added + if left_eye is not None: + left_eye = (int(x + left_eye[0]), int(y + left_eye[1])) + if right_eye is not None: + right_eye = (int(x + right_eye[0]), int(y + right_eye[1])) + facial_area = FacialAreaRegion( x=x, y=y, diff --git a/deepface/detectors/Ssd.py b/deepface/detectors/Ssd.py index f21d44ca1..ae0a81921 100644 --- a/deepface/detectors/Ssd.py +++ b/deepface/detectors/Ssd.py @@ -132,6 +132,13 @@ def detect_faces(self, img: np.ndarray) -> List[FacialAreaRegion]: left_eye, right_eye = opencv_module.find_eyes(detected_face) + # eyes found in the detected face instead image itself + # detected face's coordinates should be added + if left_eye is not None: + left_eye = (int(x + left_eye[0]), int(y + left_eye[1])) + if right_eye is not None: + right_eye = (int(x + right_eye[0]), int(y + right_eye[1])) + facial_area = FacialAreaRegion( x=x, y=y,