From 0fc1672c89aec4547d9b74b6719e01fa843c8217 Mon Sep 17 00:00:00 2001 From: Sefik Ilkin Serengil Date: Sat, 26 Jun 2021 23:13:46 +0300 Subject: [PATCH] lightweight api --- api/api.py | 155 +++++++++++++------------------------------ deepface/DeepFace.py | 43 +++++++----- 2 files changed, 71 insertions(+), 127 deletions(-) diff --git a/api/api.py b/api/api.py index 9d331ff..a907fb2 100644 --- a/api/api.py +++ b/api/api.py @@ -35,71 +35,6 @@ app = Flask(__name__) #------------------------------ -tic = time.time() - -print("Loading Face Recognition Models...") - -pbar = tqdm(range(0, 6), desc='Loading Face Recognition Models...') - -for index in pbar: - - if index == 0: - pbar.set_description("Loading VGG-Face") - vggface_model = DeepFace.build_model("VGG-Face") - elif index == 1: - pbar.set_description("Loading OpenFace") - openface_model = DeepFace.build_model("OpenFace") - elif index == 2: - pbar.set_description("Loading Google FaceNet") - facenet_model = DeepFace.build_model("Facenet") - elif index == 3: - pbar.set_description("Loading Facebook DeepFace") - deepface_model = DeepFace.build_model("DeepFace") - elif index == 4: - pbar.set_description("Loading DeepID DeepFace") - deepid_model = DeepFace.build_model("DeepID") - elif index == 5: - pbar.set_description("Loading ArcFace DeepFace") - arcface_model = DeepFace.build_model("ArcFace") - -toc = time.time() - -print("Face recognition models are built in ", toc-tic," seconds") - -#------------------------------ - -tic = time.time() - -print("Loading Facial Attribute Analysis Models...") - -pbar = tqdm(range(0,4), desc='Loading Facial Attribute Analysis Models...') - -for index in pbar: - if index == 0: - pbar.set_description("Loading emotion analysis model") - emotion_model = DeepFace.build_model('Emotion') - elif index == 1: - pbar.set_description("Loading age prediction model") - age_model = DeepFace.build_model('Age') - elif index == 2: - pbar.set_description("Loading gender prediction model") - gender_model = DeepFace.build_model('Gender') - elif index == 3: - pbar.set_description("Loading race prediction model") - race_model = DeepFace.build_model('Race') - -toc = time.time() - -facial_attribute_models = {} -facial_attribute_models["emotion"] = emotion_model -facial_attribute_models["age"] = age_model -facial_attribute_models["gender"] = gender_model -facial_attribute_models["race"] = race_model - -print("Facial attribute analysis models are built in ", toc-tic," seconds") - -#------------------------------ - if tf_version == 1: graph = tf.get_default_graph() @@ -153,15 +88,26 @@ def analyzeWrapper(req, trx_id = 0): #--------------------------- + detector_backend = 'opencv' + actions= ['emotion', 'age', 'gender', 'race'] + if "actions" in list(req.keys()): actions = req["actions"] + if "detector_backend" in list(req.keys()): + detector_backend = req["detector_backend"] + #--------------------------- - #resp_obj = DeepFace.analyze(instances, actions=actions) - resp_obj = DeepFace.analyze(instances, actions=actions, models=facial_attribute_models) + try: + resp_obj = DeepFace.analyze(instances, actions = actions) + except Exception as err: + print("Exception: ", str(err)) + return jsonify({'success': False, 'error': str(err)}), 205 + #--------------- + #print(resp_obj) return resp_obj @app.route('/verify', methods=['POST']) @@ -194,11 +140,13 @@ def verifyWrapper(req, trx_id = 0): resp_obj = jsonify({'success': False}) - model_name = "VGG-Face"; distance_metric = "cosine" + model_name = "VGG-Face"; distance_metric = "cosine"; detector_backend = "opencv" if "model_name" in list(req.keys()): model_name = req["model_name"] if "distance_metric" in list(req.keys()): distance_metric = req["distance_metric"] + if "detector_backend" in list(req.keys()): + detector_backend = req["detector_backend"] #---------------------- @@ -233,31 +181,19 @@ def verifyWrapper(req, trx_id = 0): #-------------------------- - if model_name == "VGG-Face": - resp_obj = DeepFace.verify(instances, model_name = model_name, distance_metric = distance_metric, model = vggface_model) - elif model_name == "Facenet": - resp_obj = DeepFace.verify(instances, model_name = model_name, distance_metric = distance_metric, model = facenet_model) - elif model_name == "OpenFace": - resp_obj = DeepFace.verify(instances, model_name = model_name, distance_metric = distance_metric, model = openface_model) - elif model_name == "DeepFace": - resp_obj = DeepFace.verify(instances, model_name = model_name, distance_metric = distance_metric, model = deepface_model) - elif model_name == "DeepID": - resp_obj = DeepFace.verify(instances, model_name = model_name, distance_metric = distance_metric, model = deepid_model) - elif model_name == "ArcFace": - resp_obj = DeepFace.verify(instances, model_name = model_name, distance_metric = distance_metric, model = arcface_model) - elif model_name == "Ensemble": - models = {} - models["VGG-Face"] = vggface_model - models["Facenet"] = facenet_model - models["OpenFace"] = openface_model - models["DeepFace"] = deepface_model - resp_obj = DeepFace.verify(instances, model_name = model_name, model = models) + try: + resp_obj = DeepFace.verify(instances + , model_name = model_name + , distance_metric = distance_metric + , detector_backend = detector_backend + ) - for key in resp_obj: #issue 198. - resp_obj[key]['verified'] = bool(resp_obj[key]['verified']) + if model_name == "Ensemble": #issue 198. + for key in resp_obj: #issue 198. + resp_obj[key]['verified'] = bool(resp_obj[key]['verified']) - else: - resp_obj = jsonify({'success': False, 'error': 'You must pass a valid model name. You passed %s' % (model_name)}), 205 + except Exception as err: + resp_obj = jsonify({'success': False, 'error': str(err)}), 205 return resp_obj @@ -281,7 +217,7 @@ def represent(): #-------------------------- toc = time.time() - + resp_obj["trx_id"] = trx_id resp_obj["seconds"] = toc-tic @@ -294,11 +230,14 @@ def representWrapper(req, trx_id = 0): #------------------------------------- #find out model - model_name = "VGG-Face"; distance_metric = "cosine" + model_name = "VGG-Face"; distance_metric = "cosine"; detector_backend = 'opencv' if "model_name" in list(req.keys()): model_name = req["model_name"] + if "detector_backend" in list(req.keys()): + detector_backend = req["detector_backend"] + #------------------------------------- #retrieve images from request @@ -316,27 +255,25 @@ def representWrapper(req, trx_id = 0): return jsonify({'success': False, 'error': 'you must pass img as base64 encoded string'}), 205 #------------------------------------- - #cal represent function from the interface + #call represent function from the interface - embedding = [] - if model_name == "VGG-Face": - embedding = DeepFace.represent(img, model_name = model_name, model = vggface_model) - elif model_name == "Facenet": - embedding = DeepFace.represent(img, model_name = model_name, model = facenet_model) - elif model_name == "OpenFace": - embedding = DeepFace.represent(img, model_name = model_name, model = openface_model) - elif model_name == "DeepFace": - embedding = DeepFace.represent(img, model_name = model_name, model = deepface_model) - elif model_name == "DeepID": - embedding = DeepFace.represent(img, model_name = model_name, model = deepid_model) - elif model_name == "ArcFace": - embedding = DeepFace.represent(img, model_name = model_name, model = arcface_model) - else: - resp_obj = jsonify({'success': False, 'error': 'You must pass a valid model name. You passed %s' % (model_name)}), 205 + try: + + embedding = DeepFace.represent(img + , model_name = model_name + , detector_backend = detector_backend + ) + + except Exception as err: + print("Exception: ",str(err)) + resp_obj = jsonify({'success': False, 'error': str(err)}), 205 + + #------------------------------------- #print("embedding is ", len(embedding)," dimensional vector") resp_obj = {} resp_obj["embedding"] = embedding + #------------------------------------- return resp_obj diff --git a/deepface/DeepFace.py b/deepface/DeepFace.py index fc4c988..bb62e45 100644 --- a/deepface/DeepFace.py +++ b/deepface/DeepFace.py @@ -360,13 +360,15 @@ def analyze(img_path, actions = ['emotion', 'age', 'gender', 'race'] , models = disable_option = False if len(actions) > 1 else True - pbar = tqdm(range(0,len(actions)), desc='Finding actions', disable = disable_option) + pbar = tqdm(range(0, len(actions)), desc='Finding actions', disable = disable_option) img_224 = None # Set to prevent re-detection region = [] # x, y, w, h of the detected face region region_labels = ['x', 'y', 'w', 'h'] + is_region_set = False + #facial attribute analysis for index in pbar: action = actions[index] @@ -376,10 +378,11 @@ def analyze(img_path, actions = ['emotion', 'age', 'gender', 'race'] , models = emotion_labels = ['angry', 'disgust', 'fear', 'happy', 'sad', 'surprise', 'neutral'] img, region = functions.preprocess_face(img = img_path, target_size = (48, 48), grayscale = True, enforce_detection = enforce_detection, detector_backend = detector_backend, return_region = True) - resp_obj["region"] = {} - - for i, parameter in enumerate(region_labels): - resp_obj["region"][parameter] = region[i] + if is_region_set != True: + resp_obj["region"] = {} + is_region_set = True + for i, parameter in enumerate(region_labels): + resp_obj["region"][parameter] = int(region[i]) #int cast is for the exception - object of type 'float32' is not JSON serializable emotion_predictions = models['emotion'].predict(img)[0,:] @@ -398,24 +401,27 @@ def analyze(img_path, actions = ['emotion', 'age', 'gender', 'race'] , models = if img_224 is None: img_224, region = functions.preprocess_face(img = img_path, target_size = (224, 224), grayscale = False, enforce_detection = enforce_detection, detector_backend = detector_backend, return_region = True) - resp_obj["region"] = {} - - for i, parameter in enumerate(region_labels): - resp_obj["region"][parameter] = region[i] + if is_region_set != True: + resp_obj["region"] = {} + is_region_set = True + for i, parameter in enumerate(region_labels): + resp_obj["region"][parameter] = int(region[i]) # #int cast is for the exception - object of type 'float32' is not JSON serializable age_predictions = models['age'].predict(img_224)[0,:] apparent_age = Age.findApparentAge(age_predictions) resp_obj["age"] = int(apparent_age) + #int cast is for the exception - object of type 'float32' is not JSON serializable elif action == 'gender': if img_224 is None: img_224, region = functions.preprocess_face(img = img_path, target_size = (224, 224), grayscale = False, enforce_detection = enforce_detection, detector_backend = detector_backend, return_region = True) - resp_obj["region"] = {} - - for i, parameter in enumerate(region_labels): - resp_obj["region"][parameter] = region[i] + if is_region_set != True: + resp_obj["region"] = {} + is_region_set = True + for i, parameter in enumerate(region_labels): + resp_obj["region"][parameter] = int(region[i]) ##int cast is for the exception - object of type 'float32' is not JSON serializable gender_prediction = models['gender'].predict(img_224)[0,:] @@ -432,10 +438,11 @@ def analyze(img_path, actions = ['emotion', 'age', 'gender', 'race'] , models = race_predictions = models['race'].predict(img_224)[0,:] race_labels = ['asian', 'indian', 'black', 'white', 'middle eastern', 'latino hispanic'] - resp_obj["region"] = {} - - for i, parameter in enumerate(region_labels): - resp_obj["region"][parameter] = region[i] + if is_region_set != True: + resp_obj["region"] = {} + is_region_set = True + for i, parameter in enumerate(region_labels): + resp_obj["region"][parameter] = int(region[i]) ##int cast is for the exception - object of type 'float32' is not JSON serializable sum_of_predictions = race_predictions.sum() @@ -794,7 +801,7 @@ def detectFace(img_path, detector_backend = 'opencv', enforce_detection = True): Returns: deteced and aligned face in numpy format """ - + img = functions.preprocess_face(img = img_path, detector_backend = detector_backend , enforce_detection = enforce_detection)[0] #preprocess_face returns (1, 224, 224, 3) return img[:, :, ::-1] #bgr to rgb