mirror of
https://github.com/serengil/deepface.git
synced 2025-07-21 09:20:02 +00:00
Refactor: moved is_valid_landmark to closure, improved landmark_sanitization test
This commit is contained in:
parent
07dcb87a9b
commit
0a65934c56
@ -80,30 +80,6 @@ def extract_faces(
|
||||
just available in the result only if anti_spoofing is set to True in input arguments.
|
||||
"""
|
||||
|
||||
def is_valid_landmark(coord, width, height):
|
||||
"""
|
||||
Check if a landmark coordinate is within valid image bounds
|
||||
|
||||
Args:
|
||||
coord: (x, y) tuple or None; width; height: image dimensions
|
||||
Returns True if coord is a valid (x, y) inside the image, else False
|
||||
|
||||
Returns:
|
||||
bool: True if coordinate is valid and within bounds, False otherwise
|
||||
"""
|
||||
if coord is None:
|
||||
return False
|
||||
|
||||
# handle case where coord might not be a tuple/list
|
||||
try:
|
||||
x, y = coord
|
||||
except (TypeError, ValueError):
|
||||
return False
|
||||
|
||||
# check if coordinates are within image bounds
|
||||
return 0 <= x < width and 0 <= y < height
|
||||
|
||||
|
||||
resp_objs = []
|
||||
|
||||
# img might be path, base64 or numpy array. Convert it to numpy whatever it is.
|
||||
@ -114,6 +90,22 @@ def extract_faces(
|
||||
|
||||
height, width, _ = img.shape
|
||||
|
||||
def is_valid_landmark(coord: Optional[Union[tuple, list]]) -> bool:
|
||||
"""
|
||||
Check if a landmark coordinate is within valid image bounds.
|
||||
|
||||
Args:
|
||||
coord (tuple or list or None): (x, y) coordinate to check.
|
||||
Returns:
|
||||
bool: True if coordinate is valid and within bounds, False otherwise.
|
||||
"""
|
||||
if coord is None:
|
||||
return False
|
||||
if not (isinstance(coord, (tuple, list)) and len(coord) == 2):
|
||||
return False
|
||||
x, y = coord
|
||||
return 0 <= x < width and 0 <= y < height
|
||||
|
||||
base_region = FacialAreaRegion(x=0, y=0, w=width, h=height, confidence=0)
|
||||
|
||||
if detector_backend == "skip":
|
||||
@ -173,7 +165,6 @@ def extract_faces(
|
||||
w = min(width - x - 1, int(current_region.w))
|
||||
h = min(height - y - 1, int(current_region.h))
|
||||
|
||||
# landmark vaildation
|
||||
landmarks = {
|
||||
"left_eye":current_region.left_eye,
|
||||
"right_eye":current_region.right_eye,
|
||||
@ -184,7 +175,7 @@ def extract_faces(
|
||||
|
||||
# Sanitize landmarks - set invalid ones to None
|
||||
for key, value in landmarks.items():
|
||||
if not is_valid_landmark(value, width, height):
|
||||
if not is_valid_landmark(value):
|
||||
landmarks[key] = None
|
||||
|
||||
|
||||
|
@ -1,17 +1,19 @@
|
||||
import numpy as np
|
||||
import pytest
|
||||
from deepface.modules.detection import extract_faces, DetectedFace, FacialAreaRegion
|
||||
from deepface.commons.logger import Logger
|
||||
|
||||
def sanitize_landmarks(region, width, height):
|
||||
def is_valid_landmark(coord, width, height):
|
||||
logger = Logger()
|
||||
|
||||
def is_valid_landmark(coord, width, height):
|
||||
if coord is None:
|
||||
return False
|
||||
try:
|
||||
x, y = coord
|
||||
except (TypeError, ValueError):
|
||||
if not (isinstance(coord, (tuple, list)) and len(coord) == 2):
|
||||
return False
|
||||
x, y = coord
|
||||
return 0 <= x < width and 0 <= y < height
|
||||
|
||||
def sanitize_landmarks(region, width, height):
|
||||
landmarks = {
|
||||
"left_eye": region.left_eye,
|
||||
"right_eye": region.right_eye,
|
||||
@ -20,11 +22,13 @@ def sanitize_landmarks(region, width, height):
|
||||
"mouth_right": region.mouth_right,
|
||||
}
|
||||
for key, value in landmarks.items():
|
||||
if not is_valid_landmark(value, 100, 100):
|
||||
if not is_valid_landmark(value, width, height):
|
||||
landmarks[key] = None
|
||||
return landmarks
|
||||
|
||||
def test_sanitize_landmarks():
|
||||
img = np.zeros((100, 100, 3), dtype=np.uint8)
|
||||
height, width = img.shape[:2]
|
||||
region = FacialAreaRegion(
|
||||
x=10, y=10, w=50, h=50,
|
||||
left_eye=(-5, 20), # invalid
|
||||
@ -34,20 +38,17 @@ def test_sanitize_landmarks():
|
||||
mouth_right=(20, -10), # invalid
|
||||
confidence=0.9
|
||||
)
|
||||
landmarks = sanitize_landmarks(region, 100, 100)
|
||||
print("Sanitized landmarks:", landmarks)
|
||||
landmarks = sanitize_landmarks(region, width, height)
|
||||
logger.info(f"Sanitized landmarks: {landmarks}")
|
||||
assert landmarks["left_eye"] is None
|
||||
assert landmarks["right_eye"] is None
|
||||
assert landmarks["nose"] == (30, 30)
|
||||
assert landmarks["mouth_left"] is None
|
||||
assert landmarks["mouth_right"] is None
|
||||
print("Test passed: Invalid landmarks are sanitized to None.")
|
||||
logger.info("Test passed: Invalid landmarks are sanitized to None.")
|
||||
|
||||
def test_extract_faces_sanitizes_landmarks(monkeypatch):
|
||||
# Create a dummy image
|
||||
img = np.zeros((100, 100, 3), dtype=np.uint8)
|
||||
|
||||
# Create a DetectedFace with off-image landmarks
|
||||
facial_area = FacialAreaRegion(
|
||||
x=10, y=10, w=50, h=50,
|
||||
left_eye=(-5, 20), # invalid
|
||||
@ -58,21 +59,12 @@ def test_extract_faces_sanitizes_landmarks(monkeypatch):
|
||||
confidence=0.9
|
||||
)
|
||||
detected_face = DetectedFace(img=img, facial_area=facial_area, confidence=0.9)
|
||||
|
||||
# Patch detect_faces to return our test face
|
||||
monkeypatch.setattr("f_deepface.deepface.modules.detection.detect_faces", lambda *args, **kwargs: [detected_face])
|
||||
|
||||
# Use a different backend that will call detect_faces
|
||||
monkeypatch.setattr("deepface.modules.detection.detect_faces", lambda *args, **kwargs: [detected_face])
|
||||
result = extract_faces(img, detector_backend="opencv", enforce_detection=False)
|
||||
facial_area_out = result[0]["facial_area"]
|
||||
|
||||
print("Output facial_area:", facial_area_out) # Debug print
|
||||
|
||||
logger.info(f"Output facial_area: {facial_area_out}")
|
||||
assert facial_area_out["left_eye"] is None
|
||||
assert facial_area_out["right_eye"] is None
|
||||
assert facial_area_out.get("nose") == (30, 30)
|
||||
assert facial_area_out.get("mouth_left") is None
|
||||
assert facial_area_out.get("mouth_right") is None
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_sanitize_landmarks()
|
Loading…
x
Reference in New Issue
Block a user