mirror of
https://github.com/serengil/deepface.git
synced 2025-06-06 11:35:21 +00:00
input shape is now retrieved from models
This commit is contained in:
parent
95c55c0401
commit
4800aa3e8c
@ -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]:
|
||||
"""
|
||||
|
@ -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]:
|
||||
"""
|
||||
|
@ -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]:
|
||||
"""
|
||||
|
@ -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]:
|
||||
"""
|
||||
|
@ -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]:
|
||||
"""
|
||||
|
@ -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]:
|
||||
"""
|
||||
|
@ -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]:
|
||||
"""
|
||||
|
@ -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]:
|
||||
"""
|
||||
|
@ -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
|
||||
|
@ -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]:
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
||||
# ---------------------------------------
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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(
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user