mirror of
https://github.com/serengil/deepface.git
synced 2025-06-05 19:15:23 +00:00
modular tests
This commit is contained in:
parent
fda758a002
commit
308ab61b41
2
.github/workflows/tests.yml
vendored
2
.github/workflows/tests.yml
vendored
@ -42,7 +42,7 @@ jobs:
|
||||
- name: Test with pytest
|
||||
run: |
|
||||
cd tests
|
||||
pytest unit_tests.py
|
||||
python -m pytest . -s --disable-warnings
|
||||
linting:
|
||||
needs: unit-tests
|
||||
|
||||
|
2
Makefile
2
Makefile
@ -1,5 +1,5 @@
|
||||
test:
|
||||
cd tests && python -m pytest unit_tests.py -s --disable-warnings
|
||||
cd tests && python -m pytest . -s --disable-warnings
|
||||
|
||||
lint:
|
||||
python -m pylint deepface/ --fail-under=10
|
@ -31,7 +31,7 @@ from deepface.extendedmodels import Age, Gender, Race, Emotion
|
||||
from deepface.commons import functions, realtime, distance as dst
|
||||
from deepface.commons.logger import Logger
|
||||
|
||||
# pylint: disable=no-else-raise
|
||||
# pylint: disable=no-else-raise, simplifiable-if-expression
|
||||
|
||||
logger = Logger(module="DeepFace")
|
||||
|
||||
@ -221,7 +221,7 @@ def verify(
|
||||
toc = time.time()
|
||||
|
||||
resp_obj = {
|
||||
"verified": distance <= threshold,
|
||||
"verified": True if distance <= threshold else False,
|
||||
"distance": distance,
|
||||
"threshold": threshold,
|
||||
"model": model_name,
|
||||
@ -236,7 +236,7 @@ def verify(
|
||||
|
||||
def analyze(
|
||||
img_path: Union[str, np.ndarray],
|
||||
actions: Tuple[str, ...] = ("emotion", "age", "gender", "race"),
|
||||
actions: Union[tuple, list] = ("emotion", "age", "gender", "race"),
|
||||
enforce_detection: bool = True,
|
||||
detector_backend: str = "opencv",
|
||||
align: bool = True,
|
||||
@ -414,14 +414,14 @@ def analyze(
|
||||
|
||||
def find(
|
||||
img_path: Union[str, np.ndarray],
|
||||
db_path : str,
|
||||
model_name : str ="VGG-Face",
|
||||
distance_metric : str ="cosine",
|
||||
enforce_detection : bool =True,
|
||||
detector_backend : str ="opencv",
|
||||
align : bool = True,
|
||||
normalization : str ="base",
|
||||
silent : bool = False,
|
||||
db_path: str,
|
||||
model_name: str = "VGG-Face",
|
||||
distance_metric: str = "cosine",
|
||||
enforce_detection: bool = True,
|
||||
detector_backend: str = "opencv",
|
||||
align: bool = True,
|
||||
normalization: str = "base",
|
||||
silent: bool = False,
|
||||
) -> List[pd.DataFrame]:
|
||||
"""
|
||||
This function applies verification several times and find the identities in a database
|
||||
|
133
tests/test_analyze.py
Normal file
133
tests/test_analyze.py
Normal file
@ -0,0 +1,133 @@
|
||||
import cv2
|
||||
from deepface import DeepFace
|
||||
from deepface.commons.logger import Logger
|
||||
|
||||
logger = Logger("tests/test_analyze.py")
|
||||
|
||||
detectors = ["opencv", "mtcnn"]
|
||||
|
||||
|
||||
def test_standard_analyze():
|
||||
img = "dataset/img4.jpg"
|
||||
demography_objs = DeepFace.analyze(img, silent=True)
|
||||
for demography in demography_objs:
|
||||
logger.debug(demography)
|
||||
assert demography["age"] > 20 and demography["age"] < 40
|
||||
assert demography["dominant_gender"] == "Woman"
|
||||
logger.info("✅ test standard analyze done")
|
||||
|
||||
|
||||
def test_analyze_with_all_actions_as_tuple():
|
||||
img = "dataset/img4.jpg"
|
||||
demography_objs = DeepFace.analyze(
|
||||
img, actions=("age", "gender", "race", "emotion"), silent=True
|
||||
)
|
||||
|
||||
for demography in demography_objs:
|
||||
logger.debug(f"Demography: {demography}")
|
||||
age = demography["age"]
|
||||
gender = demography["dominant_gender"]
|
||||
race = demography["dominant_race"]
|
||||
emotion = demography["dominant_emotion"]
|
||||
logger.debug(f"Age: {age}")
|
||||
logger.debug(f"Gender: {gender}")
|
||||
logger.debug(f"Race: {race}")
|
||||
logger.debug(f"Emotion: {emotion}")
|
||||
assert demography.get("age") is not None
|
||||
assert demography.get("dominant_gender") is not None
|
||||
assert demography.get("dominant_race") is not None
|
||||
assert demography.get("dominant_emotion") is not None
|
||||
|
||||
logger.info("✅ test analyze for all actions as tuple done")
|
||||
|
||||
|
||||
def test_analyze_with_all_actions_as_list():
|
||||
img = "dataset/img4.jpg"
|
||||
demography_objs = DeepFace.analyze(
|
||||
img, actions=["age", "gender", "race", "emotion"], silent=True
|
||||
)
|
||||
|
||||
for demography in demography_objs:
|
||||
logger.debug(f"Demography: {demography}")
|
||||
age = demography["age"]
|
||||
gender = demography["dominant_gender"]
|
||||
race = demography["dominant_race"]
|
||||
emotion = demography["dominant_emotion"]
|
||||
logger.debug(f"Age: {age}")
|
||||
logger.debug(f"Gender: {gender}")
|
||||
logger.debug(f"Race: {race}")
|
||||
logger.debug(f"Emotion: {emotion}")
|
||||
assert demography.get("age") is not None
|
||||
assert demography.get("dominant_gender") is not None
|
||||
assert demography.get("dominant_race") is not None
|
||||
assert demography.get("dominant_emotion") is not None
|
||||
|
||||
logger.info("✅ test analyze for all actions as array done")
|
||||
|
||||
|
||||
def test_analyze_for_some_actions():
|
||||
img = "dataset/img4.jpg"
|
||||
demography_objs = DeepFace.analyze(img, ["age", "gender"], silent=True)
|
||||
|
||||
for demography in demography_objs:
|
||||
age = demography["age"]
|
||||
gender = demography["dominant_gender"]
|
||||
|
||||
logger.debug(f"Age: { age }")
|
||||
logger.debug(f"Gender: {gender}")
|
||||
|
||||
assert demography.get("age") is not None
|
||||
assert demography.get("dominant_gender") is not None
|
||||
|
||||
# these are not in actions
|
||||
assert demography.get("dominant_race") is None
|
||||
assert demography.get("dominant_emotion") is None
|
||||
|
||||
logger.info("✅ test analyze for some actions done")
|
||||
|
||||
|
||||
def test_analyze_for_preloaded_image():
|
||||
img = cv2.imread("dataset/img1.jpg")
|
||||
resp_objs = DeepFace.analyze(img, silent=True)
|
||||
for resp_obj in resp_objs:
|
||||
logger.debug(resp_obj)
|
||||
assert resp_obj["age"] > 20 and resp_obj["age"] < 40
|
||||
assert resp_obj["dominant_gender"] == "Woman"
|
||||
|
||||
logger.info("✅ test analyze for pre-loaded image done")
|
||||
|
||||
|
||||
def test_analyze_for_different_detectors():
|
||||
img_paths = [
|
||||
"dataset/img1.jpg",
|
||||
"dataset/img5.jpg",
|
||||
"dataset/img6.jpg",
|
||||
"dataset/img8.jpg",
|
||||
"dataset/img1.jpg",
|
||||
"dataset/img2.jpg",
|
||||
"dataset/img1.jpg",
|
||||
"dataset/img2.jpg",
|
||||
"dataset/img6.jpg",
|
||||
"dataset/img6.jpg",
|
||||
]
|
||||
|
||||
for img_path in img_paths:
|
||||
for detector in detectors:
|
||||
results = DeepFace.analyze(
|
||||
img_path, actions=("gender",), detector_backend=detector, enforce_detection=False
|
||||
)
|
||||
for result in results:
|
||||
logger.debug(result)
|
||||
|
||||
# validate keys
|
||||
assert "gender" in result.keys()
|
||||
assert "dominant_gender" in result.keys() and result["dominant_gender"] in [
|
||||
"Man",
|
||||
"Woman",
|
||||
]
|
||||
|
||||
# validate probabilities
|
||||
if result["dominant_gender"] == "Man":
|
||||
assert result["gender"]["Man"] > result["gender"]["Woman"]
|
||||
else:
|
||||
assert result["gender"]["Man"] < result["gender"]["Woman"]
|
46
tests/test_enforce_detection.py
Normal file
46
tests/test_enforce_detection.py
Normal file
@ -0,0 +1,46 @@
|
||||
import pytest
|
||||
import numpy as np
|
||||
from deepface import DeepFace
|
||||
from deepface.commons.logger import Logger
|
||||
|
||||
logger = Logger("tests/test_enforce_detection.py")
|
||||
|
||||
|
||||
def test_enabled_enforce_detection_for_non_facial_input():
|
||||
black_img = np.zeros([224, 224, 3])
|
||||
|
||||
with pytest.raises(ValueError, match="Face could not be detected."):
|
||||
DeepFace.represent(img_path=black_img)
|
||||
|
||||
with pytest.raises(ValueError, match="Face could not be detected."):
|
||||
DeepFace.verify(img1_path=black_img, img2_path=black_img)
|
||||
|
||||
logger.info("✅ enabled enforce detection with non facial input tests done")
|
||||
|
||||
|
||||
def test_disabled_enforce_detection_for_non_facial_input_on_represent():
|
||||
black_img = np.zeros([224, 224, 3])
|
||||
objs = DeepFace.represent(img_path=black_img, enforce_detection=False)
|
||||
|
||||
assert isinstance(objs, list)
|
||||
assert len(objs) > 0
|
||||
assert isinstance(objs[0], dict)
|
||||
assert "embedding" in objs[0].keys()
|
||||
assert "facial_area" in objs[0].keys()
|
||||
assert isinstance(objs[0]["facial_area"], dict)
|
||||
assert "x" in objs[0]["facial_area"].keys()
|
||||
assert "y" in objs[0]["facial_area"].keys()
|
||||
assert "w" in objs[0]["facial_area"].keys()
|
||||
assert "h" in objs[0]["facial_area"].keys()
|
||||
assert isinstance(objs[0]["embedding"], list)
|
||||
assert len(objs[0]["embedding"]) == 2622 # embedding of VGG-Face
|
||||
|
||||
logger.info("✅ disabled enforce detection with non facial input test for represent tests done")
|
||||
|
||||
|
||||
def test_disabled_enforce_detection_for_non_facial_input_on_verify():
|
||||
black_img = np.zeros([224, 224, 3])
|
||||
obj = DeepFace.verify(img1_path=black_img, img2_path=black_img, enforce_detection=False)
|
||||
assert isinstance(obj, dict)
|
||||
|
||||
logger.info("✅ disabled enforce detection with non facial input test for verify tests done")
|
24
tests/test_extract_faces.py
Normal file
24
tests/test_extract_faces.py
Normal file
@ -0,0 +1,24 @@
|
||||
from deepface import DeepFace
|
||||
from deepface.commons.logger import Logger
|
||||
|
||||
logger = Logger("tests/test_extract_faces.py")
|
||||
|
||||
|
||||
def test_different_detectors():
|
||||
detectors = ["opencv", "mtcnn"]
|
||||
|
||||
for detector in detectors:
|
||||
img_objs = DeepFace.extract_faces(img_path="dataset/img11.jpg", detector_backend=detector)
|
||||
for img_obj in img_objs:
|
||||
assert "face" in img_obj.keys()
|
||||
assert "facial_area" in img_obj.keys()
|
||||
assert isinstance(img_obj["facial_area"], dict)
|
||||
assert "x" in img_obj["facial_area"].keys()
|
||||
assert "y" in img_obj["facial_area"].keys()
|
||||
assert "w" in img_obj["facial_area"].keys()
|
||||
assert "h" in img_obj["facial_area"].keys()
|
||||
assert "confidence" in img_obj.keys()
|
||||
|
||||
img = img_obj["face"]
|
||||
assert img.shape[0] > 0 and img.shape[1] > 0
|
||||
logger.info(f"✅ extract_faces for {detector} backend test is done")
|
26
tests/test_find.py
Normal file
26
tests/test_find.py
Normal file
@ -0,0 +1,26 @@
|
||||
import cv2
|
||||
import pandas as pd
|
||||
from deepface import DeepFace
|
||||
from deepface.commons.logger import Logger
|
||||
|
||||
logger = Logger("tests/test_find.py")
|
||||
|
||||
|
||||
def test_find_with_exact_path():
|
||||
dfs = DeepFace.find(img_path="dataset/img1.jpg", db_path="dataset", silent=True)
|
||||
for df in dfs:
|
||||
assert isinstance(df, pd.DataFrame)
|
||||
logger.debug(df.head())
|
||||
assert df.shape[0] > 0
|
||||
logger.info("✅ test find for exact path done")
|
||||
|
||||
|
||||
def test_find_with_array_input():
|
||||
img1 = cv2.imread("dataset/img1.jpg")
|
||||
dfs = DeepFace.find(img1, db_path="dataset", silent=True)
|
||||
|
||||
for df in dfs:
|
||||
logger.debug(df.head())
|
||||
assert df.shape[0] > 0
|
||||
|
||||
logger.info("✅ test find for array input done")
|
30
tests/test_represent.py
Normal file
30
tests/test_represent.py
Normal file
@ -0,0 +1,30 @@
|
||||
from deepface import DeepFace
|
||||
from deepface.commons.logger import Logger
|
||||
|
||||
logger = Logger("tests/test_represent.py")
|
||||
|
||||
|
||||
def test_standard_represent():
|
||||
img_path = "dataset/img1.jpg"
|
||||
embedding_objs = DeepFace.represent(img_path)
|
||||
for embedding_obj in embedding_objs:
|
||||
embedding = embedding_obj["embedding"]
|
||||
logger.info(f"Function returned {len(embedding)} dimensional vector")
|
||||
assert len(embedding) == 2622
|
||||
logger.info("✅ test standard represent function done")
|
||||
|
||||
|
||||
def test_represent_for_skipped_detector_backend():
|
||||
face_img = "dataset/img5.jpg"
|
||||
img_objs = DeepFace.represent(img_path=face_img, detector_backend="skip")
|
||||
assert len(img_objs) >= 1
|
||||
img_obj = img_objs[0]
|
||||
assert "embedding" in img_obj.keys()
|
||||
assert "facial_area" in img_obj.keys()
|
||||
assert isinstance(img_obj["facial_area"], dict)
|
||||
assert "x" in img_obj["facial_area"].keys()
|
||||
assert "y" in img_obj["facial_area"].keys()
|
||||
assert "w" in img_obj["facial_area"].keys()
|
||||
assert "h" in img_obj["facial_area"].keys()
|
||||
assert "face_confidence" in img_obj.keys()
|
||||
logger.info("✅ test represent function for skipped detector backend done")
|
102
tests/test_verify.py
Normal file
102
tests/test_verify.py
Normal file
@ -0,0 +1,102 @@
|
||||
import cv2
|
||||
from deepface import DeepFace
|
||||
from deepface.commons.logger import Logger
|
||||
|
||||
logger = Logger("tests/test_facial_recognition_models.py")
|
||||
|
||||
|
||||
models = ["VGG-Face", "Facenet", "Facenet512", "ArcFace"]
|
||||
metrics = ["cosine", "euclidean", "euclidean_l2"]
|
||||
detectors = ["opencv", "mtcnn"]
|
||||
|
||||
|
||||
def test_different_facial_recognition_models():
|
||||
dataset = [
|
||||
["dataset/img1.jpg", "dataset/img2.jpg", True],
|
||||
["dataset/img5.jpg", "dataset/img6.jpg", True],
|
||||
["dataset/img6.jpg", "dataset/img7.jpg", True],
|
||||
["dataset/img8.jpg", "dataset/img9.jpg", True],
|
||||
["dataset/img1.jpg", "dataset/img11.jpg", True],
|
||||
["dataset/img2.jpg", "dataset/img11.jpg", True],
|
||||
["dataset/img1.jpg", "dataset/img3.jpg", False],
|
||||
["dataset/img2.jpg", "dataset/img3.jpg", False],
|
||||
["dataset/img6.jpg", "dataset/img8.jpg", False],
|
||||
["dataset/img6.jpg", "dataset/img9.jpg", False],
|
||||
]
|
||||
|
||||
expected_coverage = 97.53 # human level accuracy on LFW
|
||||
successful_tests = 0
|
||||
unsuccessful_tests = 0
|
||||
for model in models:
|
||||
for metric in metrics:
|
||||
for instance in dataset:
|
||||
img1 = instance[0]
|
||||
img2 = instance[1]
|
||||
result = instance[2]
|
||||
|
||||
resp_obj = DeepFace.verify(img1, img2, model_name=model, distance_metric=metric)
|
||||
|
||||
prediction = resp_obj["verified"]
|
||||
distance = round(resp_obj["distance"], 2)
|
||||
threshold = resp_obj["threshold"]
|
||||
|
||||
if prediction is result:
|
||||
test_result_label = "✅"
|
||||
successful_tests += 1
|
||||
else:
|
||||
test_result_label = "❌"
|
||||
unsuccessful_tests += 1
|
||||
|
||||
if prediction is True:
|
||||
classified_label = "same person"
|
||||
else:
|
||||
classified_label = "different persons"
|
||||
|
||||
img1_alias = img1.split("/", maxsplit=1)[-1]
|
||||
img2_alias = img2.split("/", maxsplit=1)[-1]
|
||||
|
||||
logger.debug(
|
||||
f"{test_result_label} Pair {img1_alias}-{img2_alias}"
|
||||
f" is {classified_label} based on {model}-{metric}"
|
||||
f" (Distance: {distance}, Threshold: {threshold})",
|
||||
)
|
||||
|
||||
coverage_score = (100 * successful_tests) / (successful_tests + unsuccessful_tests)
|
||||
assert (
|
||||
coverage_score > expected_coverage
|
||||
), f"⛔ facial recognition models test failed with {coverage_score} score"
|
||||
|
||||
logger.info(f"✅ facial recognition models test passed with {coverage_score}")
|
||||
|
||||
|
||||
def test_different_face_detectors():
|
||||
for detector in detectors:
|
||||
res = DeepFace.verify("dataset/img1.jpg", "dataset/img2.jpg", detector_backend=detector)
|
||||
assert isinstance(res, dict)
|
||||
assert "verified" in res.keys()
|
||||
assert res["verified"] in [True, False]
|
||||
assert "distance" in res.keys()
|
||||
assert "threshold" in res.keys()
|
||||
assert "model" in res.keys()
|
||||
assert "detector_backend" in res.keys()
|
||||
assert "similarity_metric" in res.keys()
|
||||
assert "facial_areas" in res.keys()
|
||||
assert "img1" in res["facial_areas"].keys()
|
||||
assert "img2" in res["facial_areas"].keys()
|
||||
assert "x" in res["facial_areas"]["img1"].keys()
|
||||
assert "y" in res["facial_areas"]["img1"].keys()
|
||||
assert "w" in res["facial_areas"]["img1"].keys()
|
||||
assert "h" in res["facial_areas"]["img1"].keys()
|
||||
assert "x" in res["facial_areas"]["img2"].keys()
|
||||
assert "y" in res["facial_areas"]["img2"].keys()
|
||||
assert "w" in res["facial_areas"]["img2"].keys()
|
||||
assert "h" in res["facial_areas"]["img2"].keys()
|
||||
logger.info(f"✅ test verify for {detector} backend done")
|
||||
|
||||
|
||||
def test_verify_for_preloaded_image():
|
||||
img1 = cv2.imread("dataset/img1.jpg")
|
||||
img2 = cv2.imread("dataset/img2.jpg")
|
||||
res = DeepFace.verify(img1, img2)
|
||||
assert res["verified"] is True
|
||||
logger.info("✅ test verify for pre-loaded image done")
|
@ -1,391 +0,0 @@
|
||||
import warnings
|
||||
import os
|
||||
import tensorflow as tf
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
import cv2
|
||||
from deepface import DeepFace
|
||||
from deepface.commons.logger import Logger
|
||||
|
||||
logger = Logger()
|
||||
|
||||
# pylint: disable=consider-iterating-dictionary,broad-except
|
||||
|
||||
logger.info("-----------------------------------------")
|
||||
|
||||
warnings.filterwarnings("ignore")
|
||||
os.environ["TF_CPP_MIN_LOG_LEVEL"] = "3"
|
||||
|
||||
tf_major_version = int(tf.__version__.split(".", maxsplit=1)[0])
|
||||
|
||||
if tf_major_version == 2:
|
||||
import logging
|
||||
|
||||
tf.get_logger().setLevel(logging.ERROR)
|
||||
|
||||
logger.info("Running unit tests for TF " + tf.__version__)
|
||||
|
||||
logger.info("-----------------------------------------")
|
||||
|
||||
expected_coverage = 97
|
||||
num_cases = 0
|
||||
succeed_cases = 0
|
||||
|
||||
|
||||
def evaluate(condition):
|
||||
|
||||
global num_cases, succeed_cases
|
||||
|
||||
if condition == True:
|
||||
succeed_cases += 1
|
||||
|
||||
num_cases += 1
|
||||
|
||||
|
||||
# ------------------------------------------------
|
||||
|
||||
detectors = ["opencv", "mtcnn"]
|
||||
models = ["VGG-Face", "Facenet", "Facenet512", "ArcFace"]
|
||||
metrics = ["cosine", "euclidean", "euclidean_l2"]
|
||||
|
||||
dataset = [
|
||||
["dataset/img1.jpg", "dataset/img2.jpg", True],
|
||||
["dataset/img5.jpg", "dataset/img6.jpg", True],
|
||||
["dataset/img6.jpg", "dataset/img7.jpg", True],
|
||||
["dataset/img8.jpg", "dataset/img9.jpg", True],
|
||||
["dataset/img1.jpg", "dataset/img11.jpg", True],
|
||||
["dataset/img2.jpg", "dataset/img11.jpg", True],
|
||||
["dataset/img1.jpg", "dataset/img3.jpg", False],
|
||||
["dataset/img2.jpg", "dataset/img3.jpg", False],
|
||||
["dataset/img6.jpg", "dataset/img8.jpg", False],
|
||||
["dataset/img6.jpg", "dataset/img9.jpg", False],
|
||||
]
|
||||
|
||||
logger.info("-----------------------------------------")
|
||||
|
||||
|
||||
def test_cases():
|
||||
|
||||
logger.info("Enforce detection test")
|
||||
black_img = np.zeros([224, 224, 3])
|
||||
|
||||
# enforce detection on for represent
|
||||
try:
|
||||
DeepFace.represent(img_path=black_img)
|
||||
exception_thrown = False
|
||||
except:
|
||||
exception_thrown = True
|
||||
|
||||
assert exception_thrown is True
|
||||
|
||||
# -------------------------------------------
|
||||
|
||||
# enforce detection off for represent
|
||||
try:
|
||||
objs = DeepFace.represent(img_path=black_img, enforce_detection=False)
|
||||
exception_thrown = False
|
||||
|
||||
# validate response of represent function
|
||||
assert isinstance(objs, list)
|
||||
assert len(objs) > 0
|
||||
assert isinstance(objs[0], dict)
|
||||
assert "embedding" in objs[0].keys()
|
||||
assert "facial_area" in objs[0].keys()
|
||||
assert isinstance(objs[0]["facial_area"], dict)
|
||||
assert "x" in objs[0]["facial_area"].keys()
|
||||
assert "y" in objs[0]["facial_area"].keys()
|
||||
assert "w" in objs[0]["facial_area"].keys()
|
||||
assert "h" in objs[0]["facial_area"].keys()
|
||||
assert isinstance(objs[0]["embedding"], list)
|
||||
assert len(objs[0]["embedding"]) == 2622 # embedding of VGG-Face
|
||||
except Exception as err:
|
||||
logger.error(f"Unexpected exception thrown: {str(err)}")
|
||||
exception_thrown = True
|
||||
|
||||
assert exception_thrown is False
|
||||
|
||||
# -------------------------------------------
|
||||
# enforce detection on for verify
|
||||
try:
|
||||
obj = DeepFace.verify(img1_path=black_img, img2_path=black_img)
|
||||
exception_thrown = False
|
||||
except:
|
||||
exception_thrown = True
|
||||
|
||||
assert exception_thrown is True
|
||||
# -------------------------------------------
|
||||
# enforce detection off for verify
|
||||
|
||||
try:
|
||||
obj = DeepFace.verify(img1_path=black_img, img2_path=black_img, enforce_detection=False)
|
||||
assert isinstance(obj, dict)
|
||||
exception_thrown = False
|
||||
except Exception as err:
|
||||
logger.error(f"Unexpected exception thrown: {str(err)}")
|
||||
exception_thrown = True
|
||||
|
||||
assert exception_thrown is False
|
||||
# -------------------------------------------
|
||||
|
||||
# Test represent on user-given image (skip detector)
|
||||
try:
|
||||
face_img = dataset[1][0] # It's a face
|
||||
img_objs = DeepFace.represent(img_path=face_img, detector_backend="skip")
|
||||
assert len(img_objs) == 1
|
||||
img_obj = img_objs[0]
|
||||
assert "embedding" in img_obj.keys()
|
||||
assert "facial_area" in img_obj.keys()
|
||||
assert isinstance(img_obj["facial_area"], dict)
|
||||
assert "x" in img_obj["facial_area"].keys()
|
||||
assert "y" in img_obj["facial_area"].keys()
|
||||
assert "w" in img_obj["facial_area"].keys()
|
||||
assert "h" in img_obj["facial_area"].keys()
|
||||
assert "face_confidence" in img_obj.keys()
|
||||
exception_thrown = False
|
||||
except Exception as e:
|
||||
exception_thrown = True
|
||||
|
||||
assert exception_thrown is False
|
||||
|
||||
# -------------------------------------------
|
||||
logger.info("-----------------------------------------")
|
||||
|
||||
logger.info("Extract faces test")
|
||||
|
||||
for detector in detectors:
|
||||
img_objs = DeepFace.extract_faces(img_path="dataset/img11.jpg", detector_backend=detector)
|
||||
for img_obj in img_objs:
|
||||
assert "face" in img_obj.keys()
|
||||
assert "facial_area" in img_obj.keys()
|
||||
assert isinstance(img_obj["facial_area"], dict)
|
||||
assert "x" in img_obj["facial_area"].keys()
|
||||
assert "y" in img_obj["facial_area"].keys()
|
||||
assert "w" in img_obj["facial_area"].keys()
|
||||
assert "h" in img_obj["facial_area"].keys()
|
||||
assert "confidence" in img_obj.keys()
|
||||
|
||||
img = img_obj["face"]
|
||||
evaluate(img.shape[0] > 0 and img.shape[1] > 0)
|
||||
logger.info(f"{detector} test is done")
|
||||
|
||||
logger.info("-----------------------------------------")
|
||||
|
||||
img_path = "dataset/img1.jpg"
|
||||
embedding_objs = DeepFace.represent(img_path)
|
||||
for embedding_obj in embedding_objs:
|
||||
embedding = embedding_obj["embedding"]
|
||||
logger.info(f"Function returned {len(embedding)} dimensional vector")
|
||||
evaluate(len(embedding) == 2622)
|
||||
|
||||
logger.info("-----------------------------------------")
|
||||
|
||||
logger.info("Different face detectors on verification test")
|
||||
|
||||
for detector in detectors:
|
||||
logger.info(detector + " detector")
|
||||
res = DeepFace.verify(dataset[0][0], dataset[0][1], detector_backend=detector)
|
||||
|
||||
assert isinstance(res, dict)
|
||||
assert "verified" in res.keys()
|
||||
assert res["verified"] in [True, False]
|
||||
assert "distance" in res.keys()
|
||||
assert "threshold" in res.keys()
|
||||
assert "model" in res.keys()
|
||||
assert "detector_backend" in res.keys()
|
||||
assert "similarity_metric" in res.keys()
|
||||
assert "facial_areas" in res.keys()
|
||||
assert "img1" in res["facial_areas"].keys()
|
||||
assert "img2" in res["facial_areas"].keys()
|
||||
assert "x" in res["facial_areas"]["img1"].keys()
|
||||
assert "y" in res["facial_areas"]["img1"].keys()
|
||||
assert "w" in res["facial_areas"]["img1"].keys()
|
||||
assert "h" in res["facial_areas"]["img1"].keys()
|
||||
assert "x" in res["facial_areas"]["img2"].keys()
|
||||
assert "y" in res["facial_areas"]["img2"].keys()
|
||||
assert "w" in res["facial_areas"]["img2"].keys()
|
||||
assert "h" in res["facial_areas"]["img2"].keys()
|
||||
|
||||
logger.info(res)
|
||||
evaluate(res["verified"] == dataset[0][2])
|
||||
|
||||
logger.info("-----------------------------------------")
|
||||
|
||||
logger.info("Find function test")
|
||||
|
||||
dfs = DeepFace.find(img_path="dataset/img1.jpg", db_path="dataset")
|
||||
for df in dfs:
|
||||
assert isinstance(df, pd.DataFrame)
|
||||
logger.info(df.head())
|
||||
evaluate(df.shape[0] > 0)
|
||||
|
||||
logger.info("-----------------------------------------")
|
||||
|
||||
logger.info("Facial analysis test. Passing nothing as an action")
|
||||
|
||||
img = "dataset/img4.jpg"
|
||||
demography_objs = DeepFace.analyze(img)
|
||||
for demography in demography_objs:
|
||||
logger.info(demography)
|
||||
evaluate(demography["age"] > 20 and demography["age"] < 40)
|
||||
evaluate(demography["dominant_gender"] == "Woman")
|
||||
|
||||
logger.info("-----------------------------------------")
|
||||
|
||||
logger.info("Facial analysis test. Passing all to the action")
|
||||
demography_objs = DeepFace.analyze(img, ["age", "gender", "race", "emotion"])
|
||||
|
||||
for demography in demography_objs:
|
||||
logger.debug(f"Demography: {demography}")
|
||||
# check response is a valid json
|
||||
age = demography["age"]
|
||||
gender = demography["dominant_gender"]
|
||||
race = demography["dominant_race"]
|
||||
emotion = demography["dominant_emotion"]
|
||||
logger.info(f"Age: {age}")
|
||||
logger.info(f"Gender: {gender}")
|
||||
logger.info(f"Race: {race}")
|
||||
logger.info(f"Emotion: {emotion}")
|
||||
|
||||
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_emotion") is not None)
|
||||
|
||||
logger.info("-----------------------------------------")
|
||||
|
||||
logger.info("Facial analysis test 2. Remove some actions and check they are not computed")
|
||||
demography_objs = DeepFace.analyze(img, ["age", "gender"])
|
||||
|
||||
for demography in demography_objs:
|
||||
age = demography["age"]
|
||||
gender = demography["dominant_gender"]
|
||||
|
||||
logger.info(f"Age: { age }")
|
||||
logger.info(f"Gender: {gender}")
|
||||
|
||||
evaluate(demography.get("age") 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)
|
||||
|
||||
logger.info("-----------------------------------------")
|
||||
|
||||
logger.info("Facial recognition tests")
|
||||
|
||||
for model in models:
|
||||
for metric in metrics:
|
||||
for instance in dataset:
|
||||
img1 = instance[0]
|
||||
img2 = instance[1]
|
||||
result = instance[2]
|
||||
|
||||
resp_obj = DeepFace.verify(img1, img2, model_name=model, distance_metric=metric)
|
||||
|
||||
prediction = resp_obj["verified"]
|
||||
distance = round(resp_obj["distance"], 2)
|
||||
threshold = resp_obj["threshold"]
|
||||
|
||||
passed = prediction == result
|
||||
|
||||
evaluate(passed)
|
||||
|
||||
if passed:
|
||||
test_result_label = "passed"
|
||||
else:
|
||||
test_result_label = "failed"
|
||||
|
||||
if prediction == True:
|
||||
classified_label = "verified"
|
||||
else:
|
||||
classified_label = "unverified"
|
||||
|
||||
img1_alias = img1.split("/", maxsplit=1)[-1]
|
||||
img2_alias = img2.split("/", maxsplit=1)[-1]
|
||||
|
||||
logger.info(
|
||||
f"{img1_alias} - {img2_alias}"
|
||||
f". {classified_label} as same person based on {model} and {metric}"
|
||||
f". Distance: {distance}, Threshold:{threshold} ({test_result_label})",
|
||||
)
|
||||
|
||||
logger.info("--------------------------")
|
||||
|
||||
# -----------------------------------------
|
||||
|
||||
logger.info("Passing numpy array to analyze function")
|
||||
|
||||
img = cv2.imread("dataset/img1.jpg")
|
||||
resp_objs = DeepFace.analyze(img)
|
||||
|
||||
for resp_obj in resp_objs:
|
||||
logger.info(resp_obj)
|
||||
evaluate(resp_obj["age"] > 20 and resp_obj["age"] < 40)
|
||||
evaluate(resp_obj["gender"] == "Woman")
|
||||
|
||||
logger.info("--------------------------")
|
||||
|
||||
logger.info("Passing numpy array to verify function")
|
||||
|
||||
img1 = cv2.imread("dataset/img1.jpg")
|
||||
img2 = cv2.imread("dataset/img2.jpg")
|
||||
|
||||
res = DeepFace.verify(img1, img2)
|
||||
logger.info(res)
|
||||
evaluate(res["verified"] == True)
|
||||
|
||||
logger.info("--------------------------")
|
||||
|
||||
logger.info("Passing numpy array to find function")
|
||||
|
||||
img1 = cv2.imread("dataset/img1.jpg")
|
||||
|
||||
dfs = DeepFace.find(img1, db_path="dataset")
|
||||
|
||||
for df in dfs:
|
||||
logger.info(df.head())
|
||||
evaluate(df.shape[0] > 0)
|
||||
|
||||
logger.info("--------------------------")
|
||||
|
||||
logger.info("non-binary gender tests")
|
||||
|
||||
# interface validation - no need to call evaluate here
|
||||
|
||||
for img1_path, _, _ in dataset:
|
||||
for detector in detectors:
|
||||
results = DeepFace.analyze(
|
||||
img1_path, actions=("gender",), detector_backend=detector, enforce_detection=False
|
||||
)
|
||||
|
||||
for result in results:
|
||||
logger.info(result)
|
||||
|
||||
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"]
|
||||
|
||||
|
||||
# ---------------------------------------------
|
||||
|
||||
test_cases()
|
||||
|
||||
logger.info("num of test cases run: " + str(num_cases))
|
||||
logger.info("succeeded test cases: " + str(succeed_cases))
|
||||
|
||||
test_score = (100 * succeed_cases) / num_cases
|
||||
|
||||
logger.info("test coverage: " + str(test_score))
|
||||
|
||||
if test_score > expected_coverage:
|
||||
logger.info("well done! min required test coverage is satisfied")
|
||||
else:
|
||||
logger.info("min required test coverage is NOT satisfied")
|
||||
|
||||
assert test_score > expected_coverage
|
Loading…
x
Reference in New Issue
Block a user