diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..9030923 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.ipynb linguist-vendored \ No newline at end of file diff --git a/deepface/DeepFace.py b/deepface/DeepFace.py index a61702a..b9fe211 100644 --- a/deepface/DeepFace.py +++ b/deepface/DeepFace.py @@ -21,6 +21,7 @@ from deepface.modules import ( detection, realtime, ) +from deepface import __version__ logger = Logger(module="DeepFace") diff --git a/deepface/__init__.py b/deepface/__init__.py index e69de29..0db49b7 100644 --- a/deepface/__init__.py +++ b/deepface/__init__.py @@ -0,0 +1 @@ +__version__ = "0.0.85" diff --git a/deepface/detectors/Dlib.py b/deepface/detectors/Dlib.py index 9709401..c202e01 100644 --- a/deepface/detectors/Dlib.py +++ b/deepface/detectors/Dlib.py @@ -113,12 +113,14 @@ class DlibClient(Detector): top = d.top() bottom = d.bottom() - # detected_face = img[top:bottom, left:right] - detected_face = img[ - max(0, top) : min(bottom, img.shape[0]), max(0, left) : min(right, img.shape[1]) - ] + y = int(max(0, top)) + h = int(min(bottom, img.shape[0]) - y) + x = int(max(0, left)) + w = int(min(right, img.shape[1]) - x) - img_region = FacialAreaRegion(x=left, y=right, w=right - left, h=bottom - top) + detected_face = img[int(y) : int(y + h), int(x) : int(x + w)] + + img_region = FacialAreaRegion(x=x, y=y, w=w, h=h) confidence = scores[idx] if align: diff --git a/deepface/modules/verification.py b/deepface/modules/verification.py index 133dc45..b48d273 100644 --- a/deepface/modules/verification.py +++ b/deepface/modules/verification.py @@ -175,6 +175,14 @@ def verify( def find_cosine_distance( source_representation: Union[np.ndarray, list], test_representation: Union[np.ndarray, list] ) -> np.float64: + """ + Find cosine distance between two given vectors + Args: + source_representation (np.ndarray or list): 1st vector + test_representation (np.ndarray or list): 2nd vector + Returns + distance (np.float64): calculated cosine distance + """ if isinstance(source_representation, list): source_representation = np.array(source_representation) @@ -190,6 +198,14 @@ def find_cosine_distance( def find_euclidean_distance( source_representation: Union[np.ndarray, list], test_representation: Union[np.ndarray, list] ) -> np.float64: + """ + Find euclidean distance between two given vectors + Args: + source_representation (np.ndarray or list): 1st vector + test_representation (np.ndarray or list): 2nd vector + Returns + distance (np.float64): calculated euclidean distance + """ if isinstance(source_representation, list): source_representation = np.array(source_representation) @@ -203,12 +219,29 @@ def find_euclidean_distance( def l2_normalize(x: Union[np.ndarray, list]) -> np.ndarray: + """ + Normalize input vector with l2 + Args: + x (np.ndarray or list): given vector + Returns: + y (np.ndarray): l2 normalized vector + """ if isinstance(x, list): x = np.array(x) return x / np.sqrt(np.sum(np.multiply(x, x))) def find_threshold(model_name: str, distance_metric: str) -> float: + """ + Retrieve pre-tuned threshold values for a model and distance metric pair + Args: + model_name (str): facial recognition model name + distance_metric (str): distance metric name. Options are cosine, euclidean + and euclidean_l2. + Returns: + threshold (float): threshold value for that model name and distance metric + pair. Distances less than this threshold will be classified same person. + """ base_threshold = {"cosine": 0.40, "euclidean": 0.55, "euclidean_l2": 0.75} diff --git a/package_info.json b/package_info.json new file mode 100644 index 0000000..6f4bc61 --- /dev/null +++ b/package_info.json @@ -0,0 +1,3 @@ +{ + "version": "0.0.85" +} \ No newline at end of file diff --git a/setup.py b/setup.py index 8c70375..f56a292 100644 --- a/setup.py +++ b/setup.py @@ -1,3 +1,4 @@ +import json import setuptools with open("README.md", "r", encoding="utf-8") as fh: @@ -6,16 +7,19 @@ with open("README.md", "r", encoding="utf-8") as fh: with open("requirements.txt", "r", encoding="utf-8") as f: requirements = f.read().split("\n") +with open("package_info.json", "r", encoding="utf-8") as f: + package_info = json.load(f) + setuptools.setup( name="deepface", - version="0.0.85", + version=package_info["version"], author="Sefik Ilkin Serengil", author_email="serengil@gmail.com", description=( "A Lightweight Face Recognition and Facial Attribute Analysis Framework" " (Age, Gender, Emotion, Race) for Python" ), - data_files=[("", ["README.md", "requirements.txt"])], + data_files=[("", ["README.md", "requirements.txt", "package_info.json"])], long_description=long_description, long_description_content_type="text/markdown", url="https://github.com/serengil/deepface", diff --git a/tests/test_version.py b/tests/test_version.py new file mode 100644 index 0000000..8f221e3 --- /dev/null +++ b/tests/test_version.py @@ -0,0 +1,13 @@ +import json +from deepface import DeepFace +from deepface.commons.logger import Logger + +logger = Logger("tests/test_version.py") + + +def test_version(): + with open("../package_info.json", "r", encoding="utf-8") as f: + package_info = json.load(f) + + assert DeepFace.__version__ == package_info["version"] + logger.info("✅ versions are matching in both package_info.json and deepface/__init__.py")