input shape is now retrieved from models

This commit is contained in:
Sefik Ilkin Serengil 2024-01-31 19:37:43 +00:00
parent 95c55c0401
commit 4800aa3e8c
15 changed files with 64 additions and 55 deletions

View File

@ -53,6 +53,8 @@ class ArcFaceClient(FacialRecognition):
def __init__(self):
self.model = load_model()
self.model_name = "ArcFace"
self.input_shape = (112, 112)
self.output_shape = 512
def find_embeddings(self, img: np.ndarray) -> List[float]:
"""

View File

@ -49,6 +49,8 @@ class DeepIdClient(FacialRecognition):
def __init__(self):
self.model = load_model()
self.model_name = "DeepId"
self.input_shape = (47, 55)
self.output_shape = 160
def find_embeddings(self, img: np.ndarray) -> List[float]:
"""

View File

@ -20,6 +20,8 @@ class DlibClient(FacialRecognition):
def __init__(self):
self.model = DlibResNet()
self.model_name = "Dlib"
self.input_shape = (150, 150)
self.output_shape = 128
def find_embeddings(self, img: np.ndarray) -> List[float]:
"""

View File

@ -53,6 +53,8 @@ class FaceNet128dClient(FacialRecognition):
def __init__(self):
self.model = load_facenet128d_model()
self.model_name = "FaceNet-128d"
self.input_shape = (160, 160)
self.output_shape = 128
def find_embeddings(self, img: np.ndarray) -> List[float]:
"""
@ -75,6 +77,8 @@ class FaceNet512dClient(FacialRecognition):
def __init__(self):
self.model = load_facenet512d_model()
self.model_name = "FaceNet-512d"
self.input_shape = (160, 160)
self.output_shape = 512
def find_embeddings(self, img: np.ndarray) -> List[float]:
"""

View File

@ -46,6 +46,8 @@ class DeepFaceClient(FacialRecognition):
def __init__(self):
self.model = load_model()
self.model_name = "DeepFace"
self.input_shape = (152, 152)
self.output_shape = 4096
def find_embeddings(self, img: np.ndarray) -> List[float]:
"""

View File

@ -36,6 +36,8 @@ class OpenFaceClient(FacialRecognition):
def __init__(self):
self.model = load_model()
self.model_name = "OpenFace"
self.input_shape = (96, 96)
self.output_shape = 128
def find_embeddings(self, img: np.ndarray) -> List[float]:
"""

View File

@ -22,6 +22,8 @@ class SFaceClient(FacialRecognition):
def __init__(self):
self.model = load_model()
self.model_name = "SFace"
self.input_shape = (112, 112)
self.output_shape = 128
def find_embeddings(self, img: np.ndarray) -> List[float]:
"""

View File

@ -43,6 +43,8 @@ class VggFaceClient(FacialRecognition):
def __init__(self):
self.model = load_model()
self.model_name = "VGG-Face"
self.input_shape = (224, 224)
self.output_shape = 4096
def find_embeddings(self, img: np.ndarray) -> List[float]:
"""

View File

@ -40,33 +40,3 @@ def get_deepface_home() -> str:
str: the home directory.
"""
return str(os.getenv("DEEPFACE_HOME", default=str(Path.home())))
def find_target_size(model_name: str) -> tuple:
"""Find the target size of the model.
Args:
model_name (str): the model name.
Returns:
tuple: the target size.
"""
target_sizes = {
"VGG-Face": (224, 224),
"Facenet": (160, 160),
"Facenet512": (160, 160),
"OpenFace": (96, 96),
"DeepFace": (152, 152),
"DeepID": (47, 55),
"Dlib": (150, 150),
"ArcFace": (112, 112),
"SFace": (112, 112),
}
target_size = target_sizes.get(model_name)
if target_size == None:
raise ValueError(f"unimplemented model name - {model_name}")
return target_size

View File

@ -1,5 +1,5 @@
from abc import ABC, abstractmethod
from typing import Any, Union, List
from typing import Any, Union, List, Tuple
import numpy as np
from deepface.commons import functions
@ -15,6 +15,9 @@ else:
class FacialRecognition(ABC):
model: Union[Model, Any]
model_name: str
input_shape: Tuple[int, int]
output_shape: int
@abstractmethod
def find_embeddings(self, img: np.ndarray) -> List[float]:

View File

@ -4,7 +4,7 @@ import numpy as np
import pandas as pd
import cv2
from deepface import DeepFace
from deepface.commons import functions
from deepface.models.FacialRecognition import FacialRecognition
from deepface.commons.logger import Logger
logger = Logger(module="commons.realtime")
@ -32,12 +32,13 @@ def analysis(
enable_emotion = True
enable_age_gender = True
# ------------------------
# find custom values for this input set
target_size = functions.find_target_size(model_name=model_name)
# ------------------------
# build models once to store them in the memory
# otherwise, they will be built after cam started and this will cause delays
DeepFace.build_model(model_name=model_name)
model: FacialRecognition = DeepFace.build_model(model_name=model_name)
# find custom values for this input set
target_size = model.input_shape
logger.info(f"facial recognition model {model_name} is just built")
if enable_face_analysis:

View File

@ -10,9 +10,10 @@ import pandas as pd
from tqdm import tqdm
# project dependencies
from deepface.commons import functions, distance as dst
from deepface.commons import distance as dst
from deepface.commons.logger import Logger
from deepface.modules import representation, detection
from deepface.modules import representation, detection, modeling
from deepface.models.FacialRecognition import FacialRecognition
logger = Logger(module="deepface/modules/recognition.py")
@ -89,7 +90,8 @@ def find(
if os.path.isdir(db_path) is not True:
raise ValueError("Passed db_path does not exist!")
target_size = functions.find_target_size(model_name=model_name)
model: FacialRecognition = modeling.build_model(model_name)
target_size = model.input_shape
# ---------------------------------------

View File

@ -7,7 +7,6 @@ import cv2
# project dependencies
from deepface.modules import modeling, detection, preprocessing
from deepface.commons import functions
from deepface.models.FacialRecognition import FacialRecognition
@ -61,7 +60,7 @@ def represent(
# ---------------------------------
# we have run pre-process in verification. so, this can be skipped if it is coming from verify.
target_size = functions.find_target_size(model_name=model_name)
target_size = model.input_shape
if detector_backend != "skip":
img_objs = detection.extract_faces(
img_path=img_path,

View File

@ -6,8 +6,9 @@ from typing import Any, Dict, Union
import numpy as np
# project dependencies
from deepface.commons import functions, distance as dst
from deepface.modules import representation, detection
from deepface.commons import distance as dst
from deepface.modules import representation, detection, modeling
from deepface.models.FacialRecognition import FacialRecognition
def verify(
@ -79,7 +80,8 @@ def verify(
tic = time.time()
# --------------------------------
target_size = functions.find_target_size(model_name=model_name)
model: FacialRecognition = modeling.build_model(model_name)
target_size = model.input_shape
# img pairs might have many faces
img1_objs = detection.extract_faces(

View File

@ -1,7 +1,8 @@
import matplotlib.pyplot as plt
import numpy as np
from deepface import DeepFace
from deepface.commons import functions
from deepface.commons import distance
from deepface.models.FacialRecognition import FacialRecognition
from deepface.commons.logger import Logger
logger = Logger()
@ -11,9 +12,9 @@ logger = Logger()
model_name = "VGG-Face"
model = DeepFace.build_model(model_name=model_name)
model: FacialRecognition = DeepFace.build_model(model_name=model_name)
target_size = functions.find_target_size(model_name)
target_size = model.input_shape
logger.info(f"target_size: {target_size}")
@ -22,21 +23,34 @@ logger.info(f"target_size: {target_size}")
img1 = DeepFace.extract_faces(img_path="dataset/img1.jpg", target_size=target_size)[0]["face"]
img1 = np.expand_dims(img1, axis=0) # to (1, 224, 224, 3)
img1_representation = model.predict(img1)[0, :]
img1_representation = model.find_embeddings(img1)
img2 = DeepFace.extract_faces(img_path="dataset/img3.jpg", target_size=target_size)[0]["face"]
img2 = np.expand_dims(img2, axis=0)
img2_representation = model.predict(img2)[0, :]
img2_representation = model.find_embeddings(img2)
img1_representation = np.array(img1_representation)
img2_representation = np.array(img2_representation)
# ----------------------------------------------
# distance between two images
# distance between two images - euclidean distance formula
distance_vector = np.square(img1_representation - img2_representation)
logger.debug(distance_vector)
current_distance = np.sqrt(distance_vector.sum())
logger.info(f"Euclidean distance: {current_distance}")
distance = np.sqrt(distance_vector.sum())
logger.info(f"Euclidean distance: {distance}")
threshold = distance.findThreshold(model_name=model_name, distance_metric="euclidean")
logger.info(f"Threshold for {model_name}-euclidean pair is {threshold}")
if current_distance < threshold:
logger.info(
f"This pair is same person because its distance {current_distance}"
f" is less than threshold {threshold}"
)
else:
logger.info(
f"This pair is different persons because its distance {current_distance}"
f" is greater than threshold {threshold}"
)
# ----------------------------------------------
# expand vectors to be shown better in graph
@ -75,7 +89,7 @@ im = plt.imshow(img2_graph, interpolation="nearest", cmap=plt.cm.ocean)
plt.colorbar()
ax5 = fig.add_subplot(3, 2, 5)
plt.text(0.35, 0, f"Distance: {distance}")
plt.text(0.35, 0, f"Distance: {current_distance}")
plt.axis("off")
ax6 = fig.add_subplot(3, 2, 6)