From 27ce418832ebaa0c81c2da6e139582c0f5695733 Mon Sep 17 00:00:00 2001 From: Sefik Ilkin Serengil Date: Sat, 2 Mar 2024 21:04:43 +0000 Subject: [PATCH] correction in facial areas and expanding logic --- retinaface/RetinaFace.py | 47 +++++++++++++++------------------------- tests/test_actions.py | 18 +++++++++++++-- 2 files changed, 34 insertions(+), 31 deletions(-) diff --git a/retinaface/RetinaFace.py b/retinaface/RetinaFace.py index 1a3ecf5..cb72180 100644 --- a/retinaface/RetinaFace.py +++ b/retinaface/RetinaFace.py @@ -245,16 +245,20 @@ def extract_faces( x = facial_area[0] y = facial_area[1] - w = facial_area[2] - h = facial_area[3] + w = facial_area[2] - x + h = facial_area[3] - y - # expand the facial area to be extracted and stay within img.shape limits - x1 = max(0, x - int((w * expand_face_area) / 100)) # expand left - y1 = max(0, y - int((h * expand_face_area) / 100)) # expand top - x2 = min(img.shape[1], w + int((w * expand_face_area) / 100)) # expand right - y2 = min(img.shape[0], h + int((h * expand_face_area) / 100)) # expand bottom + if expand_face_area > 0: + expanded_w = w + int(w * expand_face_area / 100) + expanded_h = h + int(h * expand_face_area / 100) - facial_img = img[y1:y2, x1:x2] + # overwrite facial area + x = max(0, x - int((expanded_w - w) / 2)) + y = max(0, y - int((expanded_h - h) / 2)) + w = min(img.shape[1] - x, expanded_w) + h = min(img.shape[0] - y, expanded_h) + + facial_img = img[y : y + h, x : x + w] if align is True: landmarks = identity["landmarks"] @@ -265,32 +269,17 @@ def extract_faces( # mouth_left = landmarks["mouth_left"] # notice that left eye of one is seen on the right from your perspective - facial_img, rotate_angle, rotate_direction = postprocess.alignment_procedure( + aligned_img, rotate_angle, rotate_direction = postprocess.alignment_procedure( img=img, left_eye=right_eye, right_eye=left_eye, nose=nose ) # find new facial area coordinates after alignment - projected_facial_area = postprocess.rotate_facial_area( - facial_area, rotate_angle, rotate_direction, img.shape - ) - # Expand the facial area to be extracted and stay within img.shape limits - x1 = max( - 0, - projected_facial_area[0] - int((projected_facial_area[2] * expand_face_area) / 100), - ) - y1 = max( - 0, - projected_facial_area[1] - int((projected_facial_area[3] * expand_face_area) / 100), - ) - x2 = min( - img.shape[1], - projected_facial_area[2] + int((projected_facial_area[2] * expand_face_area) / 100), - ) - y2 = min( - img.shape[0], - projected_facial_area[3] + int((projected_facial_area[3] * expand_face_area) / 100), + rotated_x1, rotated_y1, rotated_x2, rotated_y2 = postprocess.rotate_facial_area( + (x, y, x + w, y + h), rotate_angle, rotate_direction, img.shape ) - facial_img = facial_img[y1:y2, x1:x2] + facial_img = aligned_img[ + int(rotated_y1) : int(rotated_y2), int(rotated_x1) : int(rotated_x2) + ] resp.append(facial_img[:, :, ::-1]) diff --git a/tests/test_actions.py b/tests/test_actions.py index ae8ac43..3cfd950 100644 --- a/tests/test_actions.py +++ b/tests/test_actions.py @@ -52,7 +52,7 @@ def test_analyze_crowded_photo(): plt.imshow(img[:, :, ::-1]) plt.axis("off") plt.show() - cv2.imwrite("outputs/" + img_path.split("/")[1], img) + # cv2.imwrite("outputs/" + img_path.split("/")[1], img) logger.info("✅ Crowded photo analysis test done") @@ -75,7 +75,7 @@ def test_alignment_for_clock_way(): def do_alignment_checks(img: np.ndarray, expected_faces: int) -> None: - faces = RetinaFace.extract_faces(img_path=img, align=True, expand_face_area=10) + faces = RetinaFace.extract_faces(img_path=img, align=True, expand_face_area=25) # it has one clear face assert len(faces) == expected_faces @@ -93,3 +93,17 @@ def do_alignment_checks(img: np.ndarray, expected_faces: int) -> None: # check eyes are on same horizantal assert abs(right_eye[1] - left_eye[1]) < 10 + + +def test_different_expanding_ratios(): + expand_ratios = [0, 25, 50] + + for expand_ratio in expand_ratios: + faces = RetinaFace.extract_faces( + img_path="tests/dataset/img11.jpg", align=True, expand_face_area=expand_ratio + ) + for face in faces: + if do_plotting is True: + plt.imshow(face) + plt.axis("off") + plt.show()