diff --git a/deepface/DeepFace.py b/deepface/DeepFace.py index 34c83c2..13f870e 100644 --- a/deepface/DeepFace.py +++ b/deepface/DeepFace.py @@ -11,10 +11,9 @@ import numpy as np import pandas as pd from tqdm import tqdm import pickle - import fire -from deepface.basemodels import VGGFace, OpenFace, Facenet, Facenet512, FbDeepFace, DeepID, DlibWrapper, ArcFace, Boosting +from deepface.basemodels import VGGFace, OpenFace, Facenet, Facenet512, FbDeepFace, DeepID, DlibWrapper, ArcFace, Boosting, sface_opencv_wrapper from deepface.extendedmodels import Age, Gender, Race, Emotion from deepface.commons import functions, realtime, distance as dst @@ -48,6 +47,7 @@ def build_model(model_name): 'DeepID': DeepID.loadModel, 'Dlib': DlibWrapper.loadModel, 'ArcFace': ArcFace.loadModel, + 'SFace': sface_opencv_wrapper.load_model, 'Emotion': Emotion.loadModel, 'Age': Age.loadModel, 'Gender': Gender.loadModel, diff --git a/deepface/basemodels/sface_opencv_wrapper.py b/deepface/basemodels/sface_opencv_wrapper.py new file mode 100644 index 0000000..2cca4a1 --- /dev/null +++ b/deepface/basemodels/sface_opencv_wrapper.py @@ -0,0 +1,56 @@ +import os + +import numpy as np +import cv2 as cv +import gdown + +from deepface.commons import functions + +_url = "https://github.com/opencv/opencv_zoo/raw/master/models/face_recognition_sface/face_recognition_sface_2021dec.onnx" + + +class _Layer: + input_shape = (None, 112, 112, 3) + + +class SFace: + def __init__(self, model_path, backend_id=0, target_id=0): + self._modelPath = model_path + self._backendId = backend_id + self._targetId = target_id + self._model = cv.FaceRecognizerSF.create( + model=self._modelPath, + config="", + backend_id=self._backendId, + target_id=self._targetId) + + self.layers = [_Layer()] + + def _preprocess(self, image, bbox): + if bbox is None: + return image + else: + return self._model.alignCrop(image, bbox) + + def predict(self, image, bbox=None, **kwargs): + # Preprocess + image = (image[0] * 255).astype(np.uint8) # revert the image to original format and preprocess using the model + input_blob = self._preprocess(image, bbox) + + # Forward + features = self._model.feature(input_blob) + return features + + +def load_model(*args, **kwargs): + home = functions.get_deepface_home() + + file_name = home + '/.deepface/weights/face_recognition_sface_2021dec.onnx' + if not os.path.isfile(file_name): + print("sface weights will be downloaded...") + + output = file_name + gdown.download(_url, output, quiet=False) + + model = SFace(file_name, 0, 0) + return model diff --git a/requirements.txt b/requirements.txt index 543a276..1ca6168 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,7 +3,7 @@ pandas>=0.23.4 gdown>=3.10.1 tqdm>=4.30.0 Pillow>=5.2.0 -opencv-python>=4.2.0.34 +opencv-python>=4.5.0.34 opencv-contrib-python>=4.3.0.36 tensorflow>=1.9.0 keras>=2.2.0