mirror of
https://github.com/serengil/deepface.git
synced 2025-06-06 19:45:21 +00:00
Update minimum distance between embeddings calculation: fixes
This commit is contained in:
parent
ca1db5fac7
commit
a2e590cfb0
@ -105,19 +105,54 @@ def verify(
|
|||||||
)
|
)
|
||||||
dims = model.output_shape
|
dims = model.output_shape
|
||||||
|
|
||||||
def extract_faces_from_img(img_path, index=1):
|
no_facial_area = {
|
||||||
# extract faces from img
|
"x": None,
|
||||||
|
"y": None,
|
||||||
|
"w": None,
|
||||||
|
"h": None,
|
||||||
|
"left_eye": None,
|
||||||
|
"right_eye": None,
|
||||||
|
}
|
||||||
|
|
||||||
|
def extract_embeddings_and_facial_areas(
|
||||||
|
img_path: Union[str, np.ndarray, List[float]],
|
||||||
|
index: int
|
||||||
|
) -> Tuple[List[List[float]], List[dict]]:
|
||||||
|
"""
|
||||||
|
Extracts facial embeddings and corresponding facial areas from an
|
||||||
|
image or returns pre-calculated embeddings.
|
||||||
|
|
||||||
|
Depending on the type of img_path, the function either extracts
|
||||||
|
facial embeddings from the provided image
|
||||||
|
(via a path or NumPy array) or verifies that the input is a list of
|
||||||
|
pre-calculated embeddings and validates them.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
img_path (Union[str, np.ndarray, List[float]]):
|
||||||
|
- A string representing the file path to an image,
|
||||||
|
- A NumPy array containing the image data,
|
||||||
|
- Or a list of pre-calculated embedding values (of type `float`).
|
||||||
|
index (int): An index value used in error messages and logging
|
||||||
|
to identify the number of the image.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Tuple[List[List[float]], List[dict]]:
|
||||||
|
- A list containing lists of facial embeddings for each detected face.
|
||||||
|
- A list of dictionaries where each dictionary contains facial area information.
|
||||||
|
"""
|
||||||
if isinstance(img_path, list):
|
if isinstance(img_path, list):
|
||||||
# given image is already pre-calculated embedding
|
# given image is already pre-calculated embedding
|
||||||
if not all(isinstance(dim, float) for dim in img_path):
|
if not all(isinstance(dim, float) for dim in img_path):
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
f"When passing img{index}_path as a list, ensure that all its items are of type float."
|
f"When passing img{index}_path as a list,"
|
||||||
|
" ensure that all its items are of type float."
|
||||||
)
|
)
|
||||||
|
|
||||||
if silent is False:
|
if silent is False:
|
||||||
logger.warn(
|
logger.warn(
|
||||||
"You passed 1st image as pre-calculated embeddings."
|
"You passed 1st image as pre-calculated embeddings."
|
||||||
f"Please ensure that embeddings have been calculated for the {model_name} model."
|
"Please ensure that embeddings have been calculated"
|
||||||
|
f" for the {model_name} model."
|
||||||
)
|
)
|
||||||
|
|
||||||
if len(img_path) != dims:
|
if len(img_path) != dims:
|
||||||
@ -127,7 +162,7 @@ def verify(
|
|||||||
)
|
)
|
||||||
|
|
||||||
img_embeddings = [img_path]
|
img_embeddings = [img_path]
|
||||||
img_facial_areas = [None]
|
img_facial_areas = [no_facial_area]
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
img_embeddings, img_facial_areas = __extract_faces_and_embeddings(
|
img_embeddings, img_facial_areas = __extract_faces_and_embeddings(
|
||||||
@ -144,17 +179,8 @@ def verify(
|
|||||||
raise ValueError(f"Exception while processing img{index}_path") from err
|
raise ValueError(f"Exception while processing img{index}_path") from err
|
||||||
return img_embeddings, img_facial_areas
|
return img_embeddings, img_facial_areas
|
||||||
|
|
||||||
img1_embeddings, img1_facial_areas = extract_faces_from_img(img1_path, 1)
|
img1_embeddings, img1_facial_areas = extract_embeddings_and_facial_areas(img1_path, 1)
|
||||||
img2_embeddings, img2_facial_areas = extract_faces_from_img(img2_path, 2)
|
img2_embeddings, img2_facial_areas = extract_embeddings_and_facial_areas(img2_path, 2)
|
||||||
|
|
||||||
no_facial_area = {
|
|
||||||
"x": None,
|
|
||||||
"y": None,
|
|
||||||
"w": None,
|
|
||||||
"h": None,
|
|
||||||
"left_eye": None,
|
|
||||||
"right_eye": None,
|
|
||||||
}
|
|
||||||
|
|
||||||
min_distance, min_idx, min_idy = float("inf"), None, None
|
min_distance, min_idx, min_idy = float("inf"), None, None
|
||||||
for idx, img1_embedding in enumerate(img1_embeddings):
|
for idx, img1_embedding in enumerate(img1_embeddings):
|
||||||
@ -166,8 +192,10 @@ def verify(
|
|||||||
# find the face pair with minimum distance
|
# find the face pair with minimum distance
|
||||||
threshold = threshold or find_threshold(model_name, distance_metric)
|
threshold = threshold or find_threshold(model_name, distance_metric)
|
||||||
distance = float(min_distance)
|
distance = float(min_distance)
|
||||||
facial_areas = (no_facial_area, no_facial_area) if None in (min_idx, min_idy) else \
|
facial_areas = (
|
||||||
(img1_facial_areas[min_idx], img2_facial_areas[min_idy])
|
no_facial_area if min_idx is None else img1_facial_areas[min_idx],
|
||||||
|
no_facial_area if min_idy is None else img2_facial_areas[min_idy],
|
||||||
|
)
|
||||||
|
|
||||||
toc = time.time()
|
toc = time.time()
|
||||||
|
|
||||||
|
@ -121,6 +121,25 @@ def test_verify_for_precalculated_embeddings():
|
|||||||
assert result["verified"] is True
|
assert result["verified"] is True
|
||||||
assert result["distance"] < result["threshold"]
|
assert result["distance"] < result["threshold"]
|
||||||
assert result["model"] == model_name
|
assert result["model"] == model_name
|
||||||
|
assert result["facial_areas"]["img1"] is not None
|
||||||
|
assert result["facial_areas"]["img2"] is not None
|
||||||
|
|
||||||
|
assert isinstance(result["facial_areas"]["img1"], dict)
|
||||||
|
assert isinstance(result["facial_areas"]["img2"], dict)
|
||||||
|
|
||||||
|
assert "x" in result["facial_areas"]["img1"].keys()
|
||||||
|
assert "y" in result["facial_areas"]["img1"].keys()
|
||||||
|
assert "w" in result["facial_areas"]["img1"].keys()
|
||||||
|
assert "h" in result["facial_areas"]["img1"].keys()
|
||||||
|
assert "left_eye" in result["facial_areas"]["img1"].keys()
|
||||||
|
assert "right_eye" in result["facial_areas"]["img1"].keys()
|
||||||
|
|
||||||
|
assert "x" in result["facial_areas"]["img2"].keys()
|
||||||
|
assert "y" in result["facial_areas"]["img2"].keys()
|
||||||
|
assert "w" in result["facial_areas"]["img2"].keys()
|
||||||
|
assert "h" in result["facial_areas"]["img2"].keys()
|
||||||
|
assert "left_eye" in result["facial_areas"]["img2"].keys()
|
||||||
|
assert "right_eye" in result["facial_areas"]["img2"].keys()
|
||||||
|
|
||||||
logger.info("✅ test verify for pre-calculated embeddings done")
|
logger.info("✅ test verify for pre-calculated embeddings done")
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user