From 3f29c6a606ca5fc0454595521c7c88ccb5aebbfe Mon Sep 17 00:00:00 2001 From: sasael Date: Sun, 12 Jun 2022 15:35:53 +0300 Subject: [PATCH 1/4] Added dominant_gender and probabilities for man / woman results in analyze function --- deepface/DeepFace.py | 23 ++++++++++++++++------- deepface/basemodels/ArcFace.py | 2 +- tests/test_nonbinary_gender.py | 32 ++++++++++++++++++++++++++++++++ tests/unit_tests.py | 10 +++++----- 4 files changed, 54 insertions(+), 13 deletions(-) create mode 100644 tests/test_nonbinary_gender.py diff --git a/deepface/DeepFace.py b/deepface/DeepFace.py index 3394a5f..02f563a 100644 --- a/deepface/DeepFace.py +++ b/deepface/DeepFace.py @@ -294,7 +294,11 @@ def analyze(img_path, actions = ('emotion', 'age', 'gender', 'race') , models = { "region": {'x': 230, 'y': 120, 'w': 36, 'h': 45}, "age": 28.66, - "gender": "woman", + "dominant_gender": "Woman", + "gender": { + 'Woman': 99.99407529830933, + 'Man': 0.005928758764639497, + } "dominant_emotion": "neutral", "emotion": { 'sad': 37.65260875225067, @@ -417,14 +421,19 @@ 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) - gender_prediction = models['gender'].predict(img_224)[0,:] + gender_predictions = models['gender'].predict(img_224)[0,:] - if np.argmax(gender_prediction) == 0: - gender = "Woman" - elif np.argmax(gender_prediction) == 1: - gender = "Man" + sum_of_predictions = gender_predictions.sum() + gender_labels = ["Woman", "Man"] + resp_obj["gender"] = {} + + for i in range(0, len(gender_labels)): + gender_label = gender_labels[i] + gender_prediction = 100 * gender_predictions[i] / sum_of_predictions + resp_obj["gender"][gender_label] = gender_prediction + + resp_obj["dominant_gender"] = gender_labels[np.argmax(gender_predictions)] - resp_obj["gender"] = gender elif action == 'race': if img_224 is None: diff --git a/deepface/basemodels/ArcFace.py b/deepface/basemodels/ArcFace.py index 9aa9d4d..d6fb38d 100644 --- a/deepface/basemodels/ArcFace.py +++ b/deepface/basemodels/ArcFace.py @@ -23,7 +23,7 @@ def loadModel(url = 'https://github.com/serengil/deepface_models/releases/downlo arcface_model = keras.layers.Flatten()(arcface_model) arcface_model = keras.layers.Dense(512, activation=None, use_bias=True, kernel_initializer="glorot_normal")(arcface_model) embedding = keras.layers.BatchNormalization(momentum=0.9, epsilon=2e-5, name="embedding", scale=True)(arcface_model) - model = keras.models.Model(inputs, embedding, name=base_model.name) + model = keras.detectors.Model(inputs, embedding, name=base_model.name) #--------------------------------------- #check the availability of pre-trained weights diff --git a/tests/test_nonbinary_gender.py b/tests/test_nonbinary_gender.py new file mode 100644 index 0000000..6b2ff69 --- /dev/null +++ b/tests/test_nonbinary_gender.py @@ -0,0 +1,32 @@ +from deepface import DeepFace + +dataset = [ + 'dataset/img1.jpg', + 'dataset/img5.jpg', + 'dataset/img6.jpg', + 'dataset/img8.jpg', + 'dataset/img7.jpg', + 'dataset/img9.jpg', + 'dataset/img11.jpg', + 'dataset/img11.jpg', +] + +detectors = ['opencv', 'ssd', 'retinaface', 'mtcnn'] # dlib not tested + + +def test_gender_prediction(): + for detector in detectors: + results = DeepFace.analyze(dataset, actions=('gender',), detector_backend=detector, prog_bar=False) + for key in results.keys(): + result = results[key] + assert 'gender' in result.keys() + assert 'dominant_gender' in result.keys() and result["dominant_gender"] in ["Man", "Woman"] + if result["dominant_gender"] == "Man": + assert result["gender"]["Man"] > result["gender"]["Woman"] + else: + assert result["gender"]["Man"] < result["gender"]["Woman"] + print(f'detector {detector} passed') + + +if __name__ == "__main__": + test_gender_prediction() diff --git a/tests/unit_tests.py b/tests/unit_tests.py index 57a71de..84656c2 100644 --- a/tests/unit_tests.py +++ b/tests/unit_tests.py @@ -96,7 +96,7 @@ def test_cases(): print(demography) evaluate(demography["age"] > 20 and demography["age"] < 40) - evaluate(demography["gender"] == "Woman") + evaluate(demography["dominant_gender"] == "Woman") print("-----------------------------------------") @@ -108,12 +108,12 @@ def test_cases(): #check response is a valid json print("Age: ", demography["age"]) - print("Gender: ", demography["gender"]) + print("Gender: ", demography["dominant_gender"]) print("Race: ", demography["dominant_race"]) print("Emotion: ", demography["dominant_emotion"]) evaluate(demography.get("age") is not None) - evaluate(demography.get("gender") is not None) + evaluate(demography.get("dominant_gender") is not None) evaluate(demography.get("dominant_race") is not None) evaluate(demography.get("dominant_emotion") is not None) @@ -123,12 +123,12 @@ def test_cases(): demography = DeepFace.analyze(img, ['age', 'gender']) print("Age: ", demography.get("age")) - print("Gender: ", demography.get("gender")) + print("Gender: ", demography.get("dominant_gender")) print("Race: ", demography.get("dominant_race")) print("Emotion: ", demography.get("dominant_emotion")) evaluate(demography.get("age") is not None) - evaluate(demography.get("gender") is not None) + evaluate(demography.get("dominant_gender") is not None) evaluate(demography.get("dominant_race") is None) evaluate(demography.get("dominant_emotion") is None) From 07220feb2d27191de1915d1a11cc28a686270f9a Mon Sep 17 00:00:00 2001 From: sasael Date: Sat, 18 Jun 2022 19:46:21 +0300 Subject: [PATCH 2/4] bugfixes --- deepface/DeepFace.py | 47 ++++++++++++++++++---------------- deepface/commons/functions.py | 2 +- tests/test_nonbinary_gender.py | 24 +++++++++-------- 3 files changed, 39 insertions(+), 34 deletions(-) diff --git a/deepface/DeepFace.py b/deepface/DeepFace.py index 02f563a..3e50ae2 100644 --- a/deepface/DeepFace.py +++ b/deepface/DeepFace.py @@ -418,23 +418,26 @@ def analyze(img_path, actions = ('emotion', 'age', 'gender', 'race') , models = 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) + try: + 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) - gender_predictions = models['gender'].predict(img_224)[0,:] + gender_predictions = models['gender'].predict(img_224)[0,:] - sum_of_predictions = gender_predictions.sum() - gender_labels = ["Woman", "Man"] - resp_obj["gender"] = {} - - for i in range(0, len(gender_labels)): - gender_label = gender_labels[i] - gender_prediction = 100 * gender_predictions[i] / sum_of_predictions - resp_obj["gender"][gender_label] = gender_prediction - - resp_obj["dominant_gender"] = gender_labels[np.argmax(gender_predictions)] + sum_of_predictions = gender_predictions.sum() + gender_labels = ["Woman", "Man"] + resp_obj["gender"] = {} + for i in range(0, len(gender_labels)): + gender_label = gender_labels[i] + gender_prediction = 100 * gender_predictions[i] / sum_of_predictions + resp_obj["gender"][gender_label] = gender_prediction + resp_obj["dominant_gender"] = gender_labels[np.argmax(gender_predictions)] + except Exception as e: + resp_obj["dominant_gender"] = None + resp_obj["gender"] = None + resp_obj["error"] = e elif action == 'race': 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) #just emotion model expects grayscale images @@ -453,7 +456,7 @@ def analyze(img_path, actions = ('emotion', 'age', 'gender', 'race') , models = #----------------------------- - if is_region_set != True: + if is_region_set != True and region: resp_obj["region"] = {} is_region_set = True for i, parameter in enumerate(region_labels): @@ -467,14 +470,14 @@ def analyze(img_path, actions = ('emotion', 'age', 'gender', 'race') , models = return resp_obj if bulkProcess == True: - - resp_obj = {} - - for i in range(0, len(resp_objects)): - resp_item = resp_objects[i] - resp_obj["instance_%d" % (i+1)] = resp_item - - return resp_obj + return resp_objects + # resp_obj = {} + # + # for i in range(0, len(resp_objects)): + # resp_item = resp_objects[i] + # resp_obj["instance_%d" % (i+1)] = resp_item + # + # return resp_obj def find(img_path, db_path, model_name ='VGG-Face', distance_metric = 'cosine', model = None, enforce_detection = True, detector_backend = 'opencv', align = True, prog_bar = True, normalization = 'base', silent=False): diff --git a/deepface/commons/functions.py b/deepface/commons/functions.py index 0acbf3f..ec034ad 100644 --- a/deepface/commons/functions.py +++ b/deepface/commons/functions.py @@ -83,7 +83,7 @@ def load_image(img): img = loadBase64Img(img) elif url_img: - img = np.array(Image.open(requests.get(img, stream=True).raw)) + img = np.array(Image.open(requests.get(img, stream=True).raw).convert('RGB')) elif exact_image != True: #image path passed as input if os.path.isfile(img) != True: diff --git a/tests/test_nonbinary_gender.py b/tests/test_nonbinary_gender.py index 6b2ff69..85d2a9f 100644 --- a/tests/test_nonbinary_gender.py +++ b/tests/test_nonbinary_gender.py @@ -1,14 +1,17 @@ from deepface import DeepFace dataset = [ - 'dataset/img1.jpg', - 'dataset/img5.jpg', - 'dataset/img6.jpg', - 'dataset/img8.jpg', - 'dataset/img7.jpg', - 'dataset/img9.jpg', - 'dataset/img11.jpg', - 'dataset/img11.jpg', + 'https://datasets-626827236627.s3.amazonaws.com/avatars/orly-hamzani-046368aa_06122022.jpg?AWSAccessKeyId=ASIAZD4OQSUJ3IBDFZUN&Signature=pnRMEwKHNA5PfwDgHNoGavUxZvM%3D&x-amz-security-token=IQoJb3JpZ2luX2VjEID%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEaCXVzLWVhc3QtMSJIMEYCIQCfwrDPDOtQ7qval0EdjUQEhah2PvnNeJmO3KqjRmSzzQIhALmpYTK%2BIGxCNwfBBqtqCvme8cAhS6S2LCc6ti4rHC6VKtsECIn%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEQARoMNjI2ODI3MjM2NjI3IgxmYcKEgfQcYn6Ktf0qrwSTcdMXW6jBfrKQn1FtoasmBah2JYCy2X%2Bb07cLFKKNrwH7YLFlCoXiKWP6ntzrm0R2wSsr%2BTmn6RH8WoiXnnaC%2BagFiyUdqPlTdBGy2L%2BO2EKBNA0FnRx%2FnHR0rLG%2Fmcv7cSVcG%2Bsthv5nVSafUgDlQ8dLlcW%2FiGk10eSSAM2tMcUOPyoOLlsSJ%2B0RiSppJEhy3%2F5S63p7RT2fVdlSE1XH%2BnQYvIoUEw0uB3rVywTMknFFi7h8teki%2BGE%2BuONqcHwxSjfnDE53DzZZmmZ%2F5yW2TiK3KbbV974PVgGxA4epRwFCGKqmf7%2FeQCxjmOhPpvXL%2FWiltAIIxtUxlx6IL6IfTsf8i0bVU9cO4Jj14r5%2BdGt96h%2FHGftm%2BdBp1v7JD0vBIxiwFFgv073YjBBmg4gUoryI%aqaaaaaaaa', + 'https://datasets-626827236627.s3.amazonaws.com/avatars/%25D7%25A9%25D7%2599-%25D7%259E%25D7%2595%25D7%25A2%25D7%259C%25D7%259D-011174120_06122022.jpg?AWSAccessKeyId=ASIAZD4OQSUJ3IBDFZUN&Signature=QPaXXLUwBvflmxMEcJ98TiSvMTk%3D&x-amz-security-token=IQoJb3JpZ2luX2VjEID%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEaCXVzLWVhc3QtMSJIMEYCIQCfwrDPDOtQ7qval0EdjUQEhah2PvnNeJmO3KqjRmSzzQIhALmpYTK%2BIGxCNwfBBqtqCvme8cAhS6S2LCc6ti4rHC6VKtsECIn%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEQARoMNjI2ODI3MjM2NjI3IgxmYcKEgfQcYn6Ktf0qrwSTcdMXW6jBfrKQn1FtoasmBah2JYCy2X%2Bb07cLFKKNrwH7YLFlCoXiKWP6ntzrm0R2wSsr%2BTmn6RH8WoiXnnaC%2BagFiyUdqPlTdBGy2L%2BO2EKBNA0FnRx%2FnHR0rLG%2Fmcv7cSVcG%2Bsthv5nVSafUgDlQ8dLlcW%2FiGk10eSSAM2tMcUOPyoOLlsSJ%2B0RiSppJEhy3%2F5S63p7RT2fVdlSE1XH%2BnQYvIoUEw0uB3rVywTMknFFi7h8teki%2BGE%2BuONqcHwxSjfnDE53DzZZmmZ%2F5yW2TiK3KbbV974PVgGxA4epRwFCGKqmf7%2FeQCxjmOhPpvXL%2FWiltAIIxtUxlx6IL6IfTsf8i0bVU9cO4Jj14r5%2BdGt96h%2FHGftm%2BdBp1v7JD0vBIxiwFFgv073YjBBmg4gUoryI%2BKaWwf8ISc%2FNtJEg5e2ouslYm4GYYkDFosaYv1WIPztmWybvGeERGlpJg4apsJMEp2McrL7bT1dRPYRSiK9IZYSLXiW3gUnN3KpV62xDD6x5Y1ZZOw92dri5YdHu%2FyPUtn2JaZGDsgKNsSu2QuxFnDK5kiJJjeykTJPGEmqoP7EynzBnD3uCDGj3pH8GBseU8MR2fkHn%2F8ARqpwx%2F8U34XMTUgFX%2BQSCw6qEuFbDCMngyMAngFR2aF6aAqq7Oms1A61bKaGjHCzsEEyEhamLbpvqbGwjN7vrQhuiU6VsKLSnozfUI9eiGFGdko4xmXxbJkuPJHHiAEEtJoKSMPf8oJUGOqgB%2BS48LRDY83OvX5W2mX%2FTqb9UvUdwE9VB2HBQ11mkE36LD9BtOyLhxaFuMYFOUqk1JBKatWSV49UlQUZuRnEFnNmlB4v2zLX3qQ6WjbkZsGIGUynNugAGbtoxqHW9wWklimJKha1nDv3JmF4vDlfWMLfCe42Kth0gxEpXmMkdjY%2BSdJm%2FeELOzTqFrp3yMm%2FziDttBzx3mZnHgz0qaZIEp0BVmn4kSRH5&Expires=1655198312', + 'https://datasets-626827236627.s3.amazonaws.com/avatars/orly-hamzani-046368aa_06122022.jpg?AWSAccessKeyId=ASIAZD4OQSUJ3IBDFZUN&Signature=pnRMEwKHNA5PfwDgHNoGavUxZvM%3D&x-amz-security-token=IQoJb3JpZ2luX2VjEID%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEaCXVzLWVhc3QtMSJIMEYCIQCfwrDPDOtQ7qval0EdjUQEhah2PvnNeJmO3KqjRmSzzQIhALmpYTK%2BIGxCNwfBBqtqCvme8cAhS6S2LCc6ti4rHC6VKtsECIn%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEQARoMNjI2ODI3MjM2NjI3IgxmYcKEgfQcYn6Ktf0qrwSTcdMXW6jBfrKQn1FtoasmBah2JYCy2X%2Bb07cLFKKNrwH7YLFlCoXiKWP6ntzrm0R2wSsr%2BTmn6RH8WoiXnnaC%2BagFiyUdqPlTdBGy2L%2BO2EKBNA0FnRx%2FnHR0rLG%2Fmcv7cSVcG%2Bsthv5nVSafUgDlQ8dLlcW%2FiGk10eSSAM2tMcUOPyoOLlsSJ%2B0RiSppJEhy3%2F5S63p7RT2fVdlSE1XH%2BnQYvIoUEw0uB3rVywTMknFFi7h8teki%2BGE%2BuONqcHwxSjfnDE53DzZZmmZ%2F5yW2TiK3KbbV974PVgGxA4epRwFCGKqmf7%2FeQCxjmOhPpvXL%2FWiltAIIxtUxlx6IL6IfTsf8i0bVU9cO4Jj14r5%2BdGt96h%2FHGftm%2BdBp1v7JD0vBIxiwFFgv073YjBBmg4gUoryI%2BKaWwf8ISc%2FNtJEg5e2ouslYm4GYYkDFosaYv1WIPztmWybvGeERGlpJg4apsJMEp2McrL7bT1dRPYRSiK9IZYSLXiW3gUnN3KpV62xDD6x5Y1ZZOw92dri5YdHu%2FyPUtn2JaZGDsgKNsSu2QuxFnDK5kiJJjeykTJPGEmqoP7EynzBnD3uCDGj3pH8GBseU8MR2fkHn%2F8ARqpwx%2F8U34XMTUgFX%2BQSCw6qEuFbDCMngyMAngFR2aF6aAqq7Oms1A61bKaGjHCzsEEyEhamLbpvqbGwjN7vrQhuiU6VsKLSnozfUI9eiGFGdko4xmXxbJkuPJHHiAEEtJoKSMPf8oJUGOqgB%2BS48LRDY83OvX5W2mX%2FTqb9UvUdwE9VB2HBQ11mkE36LD9BtOyLhxaFuMYFOUqk1JBKatWSV49UlQUZuRnEFnNmlB4v2zLX3qQ6WjbkZsGIGUynNugAGbtoxqHW9wWklimJKha1nDv3JmF4vDlfWMLfCe42Kth0gxEpXmMkdjY%2BSdJm%2FeELOzTqFrp3yMm%2FziDttBzx3mZnHgz0qaZIEp0BVmn4kSRH5&Expires=1655199524', + # 'dataset/img1.jpg', + # 'dataset/img5.jpg', + # 'dataset/img6.jpg', + # 'dataset/img8.jpg', + # 'dataset/img7.jpg', + # 'dataset/img9.jpg', + # 'dataset/img11.jpg', + # 'dataset/img11.jpg', ] detectors = ['opencv', 'ssd', 'retinaface', 'mtcnn'] # dlib not tested @@ -16,9 +19,8 @@ detectors = ['opencv', 'ssd', 'retinaface', 'mtcnn'] # dlib not tested def test_gender_prediction(): for detector in detectors: - results = DeepFace.analyze(dataset, actions=('gender',), detector_backend=detector, prog_bar=False) - for key in results.keys(): - result = results[key] + results = DeepFace.analyze(dataset, actions=('gender',), detector_backend=detector, prog_bar=False, enforce_detection=False) + for result in results: assert 'gender' in result.keys() assert 'dominant_gender' in result.keys() and result["dominant_gender"] in ["Man", "Woman"] if result["dominant_gender"] == "Man": From 2135941912a923bf1b8b1a219814f33dc088e319 Mon Sep 17 00:00:00 2001 From: sasael Date: Wed, 22 Jun 2022 15:34:39 +0300 Subject: [PATCH 3/4] - Added doReverted keras.models - Running test_nonbinary_gender.py in unit_tests.py --- deepface/basemodels/ArcFace.py | 2 +- deepface/extendedmodels/Gender.py | 1 + tests/test_nonbinary_gender.py | 45 ++++++++++++++++--------------- tests/unit_tests.py | 12 +++++++-- 4 files changed, 35 insertions(+), 25 deletions(-) diff --git a/deepface/basemodels/ArcFace.py b/deepface/basemodels/ArcFace.py index d6fb38d..9aa9d4d 100644 --- a/deepface/basemodels/ArcFace.py +++ b/deepface/basemodels/ArcFace.py @@ -23,7 +23,7 @@ def loadModel(url = 'https://github.com/serengil/deepface_models/releases/downlo arcface_model = keras.layers.Flatten()(arcface_model) arcface_model = keras.layers.Dense(512, activation=None, use_bias=True, kernel_initializer="glorot_normal")(arcface_model) embedding = keras.layers.BatchNormalization(momentum=0.9, epsilon=2e-5, name="embedding", scale=True)(arcface_model) - model = keras.detectors.Model(inputs, embedding, name=base_model.name) + model = keras.models.Model(inputs, embedding, name=base_model.name) #--------------------------------------- #check the availability of pre-trained weights diff --git a/deepface/extendedmodels/Gender.py b/deepface/extendedmodels/Gender.py index e831226..9fc91f1 100644 --- a/deepface/extendedmodels/Gender.py +++ b/deepface/extendedmodels/Gender.py @@ -18,6 +18,7 @@ elif tf_version == 2: #url = 'https://drive.google.com/uc?id=1wUXRVlbsni2FN9-jkS_f4UTUrm1bRLyk' + def loadModel(url = 'https://github.com/serengil/deepface_models/releases/download/v1.0/gender_model_weights.h5'): model = VGGFace.baseModel() diff --git a/tests/test_nonbinary_gender.py b/tests/test_nonbinary_gender.py index 85d2a9f..ec36566 100644 --- a/tests/test_nonbinary_gender.py +++ b/tests/test_nonbinary_gender.py @@ -1,33 +1,34 @@ from deepface import DeepFace dataset = [ - 'https://datasets-626827236627.s3.amazonaws.com/avatars/orly-hamzani-046368aa_06122022.jpg?AWSAccessKeyId=ASIAZD4OQSUJ3IBDFZUN&Signature=pnRMEwKHNA5PfwDgHNoGavUxZvM%3D&x-amz-security-token=IQoJb3JpZ2luX2VjEID%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEaCXVzLWVhc3QtMSJIMEYCIQCfwrDPDOtQ7qval0EdjUQEhah2PvnNeJmO3KqjRmSzzQIhALmpYTK%2BIGxCNwfBBqtqCvme8cAhS6S2LCc6ti4rHC6VKtsECIn%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEQARoMNjI2ODI3MjM2NjI3IgxmYcKEgfQcYn6Ktf0qrwSTcdMXW6jBfrKQn1FtoasmBah2JYCy2X%2Bb07cLFKKNrwH7YLFlCoXiKWP6ntzrm0R2wSsr%2BTmn6RH8WoiXnnaC%2BagFiyUdqPlTdBGy2L%2BO2EKBNA0FnRx%2FnHR0rLG%2Fmcv7cSVcG%2Bsthv5nVSafUgDlQ8dLlcW%2FiGk10eSSAM2tMcUOPyoOLlsSJ%2B0RiSppJEhy3%2F5S63p7RT2fVdlSE1XH%2BnQYvIoUEw0uB3rVywTMknFFi7h8teki%2BGE%2BuONqcHwxSjfnDE53DzZZmmZ%2F5yW2TiK3KbbV974PVgGxA4epRwFCGKqmf7%2FeQCxjmOhPpvXL%2FWiltAIIxtUxlx6IL6IfTsf8i0bVU9cO4Jj14r5%2BdGt96h%2FHGftm%2BdBp1v7JD0vBIxiwFFgv073YjBBmg4gUoryI%aqaaaaaaaa', - 'https://datasets-626827236627.s3.amazonaws.com/avatars/%25D7%25A9%25D7%2599-%25D7%259E%25D7%2595%25D7%25A2%25D7%259C%25D7%259D-011174120_06122022.jpg?AWSAccessKeyId=ASIAZD4OQSUJ3IBDFZUN&Signature=QPaXXLUwBvflmxMEcJ98TiSvMTk%3D&x-amz-security-token=IQoJb3JpZ2luX2VjEID%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEaCXVzLWVhc3QtMSJIMEYCIQCfwrDPDOtQ7qval0EdjUQEhah2PvnNeJmO3KqjRmSzzQIhALmpYTK%2BIGxCNwfBBqtqCvme8cAhS6S2LCc6ti4rHC6VKtsECIn%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEQARoMNjI2ODI3MjM2NjI3IgxmYcKEgfQcYn6Ktf0qrwSTcdMXW6jBfrKQn1FtoasmBah2JYCy2X%2Bb07cLFKKNrwH7YLFlCoXiKWP6ntzrm0R2wSsr%2BTmn6RH8WoiXnnaC%2BagFiyUdqPlTdBGy2L%2BO2EKBNA0FnRx%2FnHR0rLG%2Fmcv7cSVcG%2Bsthv5nVSafUgDlQ8dLlcW%2FiGk10eSSAM2tMcUOPyoOLlsSJ%2B0RiSppJEhy3%2F5S63p7RT2fVdlSE1XH%2BnQYvIoUEw0uB3rVywTMknFFi7h8teki%2BGE%2BuONqcHwxSjfnDE53DzZZmmZ%2F5yW2TiK3KbbV974PVgGxA4epRwFCGKqmf7%2FeQCxjmOhPpvXL%2FWiltAIIxtUxlx6IL6IfTsf8i0bVU9cO4Jj14r5%2BdGt96h%2FHGftm%2BdBp1v7JD0vBIxiwFFgv073YjBBmg4gUoryI%2BKaWwf8ISc%2FNtJEg5e2ouslYm4GYYkDFosaYv1WIPztmWybvGeERGlpJg4apsJMEp2McrL7bT1dRPYRSiK9IZYSLXiW3gUnN3KpV62xDD6x5Y1ZZOw92dri5YdHu%2FyPUtn2JaZGDsgKNsSu2QuxFnDK5kiJJjeykTJPGEmqoP7EynzBnD3uCDGj3pH8GBseU8MR2fkHn%2F8ARqpwx%2F8U34XMTUgFX%2BQSCw6qEuFbDCMngyMAngFR2aF6aAqq7Oms1A61bKaGjHCzsEEyEhamLbpvqbGwjN7vrQhuiU6VsKLSnozfUI9eiGFGdko4xmXxbJkuPJHHiAEEtJoKSMPf8oJUGOqgB%2BS48LRDY83OvX5W2mX%2FTqb9UvUdwE9VB2HBQ11mkE36LD9BtOyLhxaFuMYFOUqk1JBKatWSV49UlQUZuRnEFnNmlB4v2zLX3qQ6WjbkZsGIGUynNugAGbtoxqHW9wWklimJKha1nDv3JmF4vDlfWMLfCe42Kth0gxEpXmMkdjY%2BSdJm%2FeELOzTqFrp3yMm%2FziDttBzx3mZnHgz0qaZIEp0BVmn4kSRH5&Expires=1655198312', - 'https://datasets-626827236627.s3.amazonaws.com/avatars/orly-hamzani-046368aa_06122022.jpg?AWSAccessKeyId=ASIAZD4OQSUJ3IBDFZUN&Signature=pnRMEwKHNA5PfwDgHNoGavUxZvM%3D&x-amz-security-token=IQoJb3JpZ2luX2VjEID%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEaCXVzLWVhc3QtMSJIMEYCIQCfwrDPDOtQ7qval0EdjUQEhah2PvnNeJmO3KqjRmSzzQIhALmpYTK%2BIGxCNwfBBqtqCvme8cAhS6S2LCc6ti4rHC6VKtsECIn%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEQARoMNjI2ODI3MjM2NjI3IgxmYcKEgfQcYn6Ktf0qrwSTcdMXW6jBfrKQn1FtoasmBah2JYCy2X%2Bb07cLFKKNrwH7YLFlCoXiKWP6ntzrm0R2wSsr%2BTmn6RH8WoiXnnaC%2BagFiyUdqPlTdBGy2L%2BO2EKBNA0FnRx%2FnHR0rLG%2Fmcv7cSVcG%2Bsthv5nVSafUgDlQ8dLlcW%2FiGk10eSSAM2tMcUOPyoOLlsSJ%2B0RiSppJEhy3%2F5S63p7RT2fVdlSE1XH%2BnQYvIoUEw0uB3rVywTMknFFi7h8teki%2BGE%2BuONqcHwxSjfnDE53DzZZmmZ%2F5yW2TiK3KbbV974PVgGxA4epRwFCGKqmf7%2FeQCxjmOhPpvXL%2FWiltAIIxtUxlx6IL6IfTsf8i0bVU9cO4Jj14r5%2BdGt96h%2FHGftm%2BdBp1v7JD0vBIxiwFFgv073YjBBmg4gUoryI%2BKaWwf8ISc%2FNtJEg5e2ouslYm4GYYkDFosaYv1WIPztmWybvGeERGlpJg4apsJMEp2McrL7bT1dRPYRSiK9IZYSLXiW3gUnN3KpV62xDD6x5Y1ZZOw92dri5YdHu%2FyPUtn2JaZGDsgKNsSu2QuxFnDK5kiJJjeykTJPGEmqoP7EynzBnD3uCDGj3pH8GBseU8MR2fkHn%2F8ARqpwx%2F8U34XMTUgFX%2BQSCw6qEuFbDCMngyMAngFR2aF6aAqq7Oms1A61bKaGjHCzsEEyEhamLbpvqbGwjN7vrQhuiU6VsKLSnozfUI9eiGFGdko4xmXxbJkuPJHHiAEEtJoKSMPf8oJUGOqgB%2BS48LRDY83OvX5W2mX%2FTqb9UvUdwE9VB2HBQ11mkE36LD9BtOyLhxaFuMYFOUqk1JBKatWSV49UlQUZuRnEFnNmlB4v2zLX3qQ6WjbkZsGIGUynNugAGbtoxqHW9wWklimJKha1nDv3JmF4vDlfWMLfCe42Kth0gxEpXmMkdjY%2BSdJm%2FeELOzTqFrp3yMm%2FziDttBzx3mZnHgz0qaZIEp0BVmn4kSRH5&Expires=1655199524', - # 'dataset/img1.jpg', - # 'dataset/img5.jpg', - # 'dataset/img6.jpg', - # 'dataset/img8.jpg', - # 'dataset/img7.jpg', - # 'dataset/img9.jpg', - # 'dataset/img11.jpg', - # 'dataset/img11.jpg', + 'dataset/img1.jpg', + 'dataset/img5.jpg', + 'dataset/img6.jpg', + 'dataset/img7.jpg', + 'dataset/img9.jpg', + 'dataset/img11.jpg', + 'dataset/img11.jpg', ] -detectors = ['opencv', 'ssd', 'retinaface', 'mtcnn'] # dlib not tested - def test_gender_prediction(): + detectors = ['opencv', 'ssd', 'retinaface', 'mtcnn'] # dlib not tested for detector in detectors: - results = DeepFace.analyze(dataset, actions=('gender',), detector_backend=detector, prog_bar=False, enforce_detection=False) - for result in results: - assert 'gender' in result.keys() - assert 'dominant_gender' in result.keys() and result["dominant_gender"] in ["Man", "Woman"] - if result["dominant_gender"] == "Man": - assert result["gender"]["Man"] > result["gender"]["Woman"] - else: - assert result["gender"]["Man"] < result["gender"]["Woman"] - print(f'detector {detector} passed') + test_gender_prediction_with_detector(detector) + + +def test_gender_prediction_with_detector(detector): + results = DeepFace.analyze(dataset, actions=('gender',), detector_backend=detector, prog_bar=False, + enforce_detection=False) + for result in results: + assert 'gender' in result.keys() + assert 'dominant_gender' in result.keys() and result["dominant_gender"] in ["Man", "Woman"] + if result["dominant_gender"] == "Man": + assert result["gender"]["Man"] > result["gender"]["Woman"] + else: + assert result["gender"]["Man"] < result["gender"]["Woman"] + print(f'detector {detector} passed') + return True if __name__ == "__main__": diff --git a/tests/unit_tests.py b/tests/unit_tests.py index 84656c2..aa4739b 100644 --- a/tests/unit_tests.py +++ b/tests/unit_tests.py @@ -3,6 +3,7 @@ import os import tensorflow as tf import cv2 from deepface import DeepFace +from tests.test_nonbinary_gender import test_gender_prediction, test_gender_prediction_with_detector print("-----------------------------------------") @@ -114,7 +115,7 @@ def test_cases(): evaluate(demography.get("age") is not None) evaluate(demography.get("dominant_gender") is not None) - evaluate(demography.get("dominant_race") is not None) + evaluate(demography.get("dominant_race") is not None) evaluate(demography.get("dominant_emotion") is not None) print("-----------------------------------------") @@ -151,7 +152,7 @@ def test_cases(): distance = round(resp_obj["distance"], 2) threshold = resp_obj["threshold"] - passed = prediction == result + passed = prediction == result evaluate(passed) @@ -206,7 +207,14 @@ def test_cases(): print("--------------------------") + +def run_gender_prediction_test(): + for detector in detectors: + evaluate(test_gender_prediction_with_detector(detector)) + + test_cases() +run_gender_prediction_test() print("num of test cases run: " + str(num_cases)) print("succeeded test cases: " + str(succeed_cases)) From 3f2fa48bee9f112db60e686060493f6299828a68 Mon Sep 17 00:00:00 2001 From: sasael Date: Wed, 22 Jun 2022 15:36:20 +0300 Subject: [PATCH 4/4] Taking gender_prediction directly --- deepface/DeepFace.py | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/deepface/DeepFace.py b/deepface/DeepFace.py index 4a54a87..43cfb6b 100644 --- a/deepface/DeepFace.py +++ b/deepface/DeepFace.py @@ -424,13 +424,12 @@ def analyze(img_path, actions = ('emotion', 'age', 'gender', 'race') , models = gender_predictions = models['gender'].predict(img_224)[0,:] - sum_of_predictions = gender_predictions.sum() gender_labels = ["Woman", "Man"] resp_obj["gender"] = {} for i in range(0, len(gender_labels)): gender_label = gender_labels[i] - gender_prediction = 100 * gender_predictions[i] / sum_of_predictions + gender_prediction = 100 * gender_predictions[i] resp_obj["gender"][gender_label] = gender_prediction resp_obj["dominant_gender"] = gender_labels[np.argmax(gender_predictions)] @@ -471,13 +470,7 @@ def analyze(img_path, actions = ('emotion', 'age', 'gender', 'race') , models = if bulkProcess == True: return resp_objects - # resp_obj = {} - # - # for i in range(0, len(resp_objects)): - # resp_item = resp_objects[i] - # resp_obj["instance_%d" % (i+1)] = resp_item - # - # return resp_obj + def find(img_path, db_path, model_name ='VGG-Face', distance_metric = 'cosine', model = None, enforce_detection = True, detector_backend = 'opencv', align = True, prog_bar = True, normalization = 'base', silent=False):