Skip to content

Commit 2d5b56e

Browse files
committed
some cosmetic changes
1 parent adfa54b commit 2d5b56e

File tree

3 files changed

+98
-93
lines changed

3 files changed

+98
-93
lines changed

retinaface/RetinaFace.py

+48-85
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import os
22
import warnings
33
import logging
4-
from typing import Union, Any, Optional, Dict, Tuple
4+
from typing import Union, Any, Optional, Dict
55

66
import numpy as np
77
import tensorflow as tf
@@ -243,89 +243,52 @@ def extract_faces(
243243
"Align first functionality can be applied only if there is single face in the input"
244244
)
245245

246-
if isinstance(obj, dict):
247-
for _, identity in obj.items():
248-
facial_area = identity["facial_area"]
249-
250-
x = facial_area[0]
251-
y = facial_area[1]
252-
w = facial_area[2]
253-
h = facial_area[3]
254-
255-
# expand the facial area to be extracted and stay within img.shape limits
256-
x1 = max(0, x - int((w * expand_face_area) / 100)) # expand left
257-
y1 = max(0, y - int((h * expand_face_area) / 100)) # expand top
258-
x2 = min(img.shape[1], w + int((w * expand_face_area) / 100)) # expand right
259-
y2 = min(img.shape[0], h + int((h * expand_face_area) / 100)) # expand bottom
260-
261-
if align_first is False or (align_first is True and len(obj) > 1):
262-
facial_img = img[y1:y2, x1:x2]
263-
else:
264-
facial_img = img.copy()
265-
266-
if align is True:
267-
landmarks = identity["landmarks"]
268-
left_eye = landmarks["left_eye"]
269-
right_eye = landmarks["right_eye"]
270-
nose = landmarks["nose"]
271-
# mouth_right = landmarks["mouth_right"]
272-
# mouth_left = landmarks["mouth_left"]
273-
facial_img, rotate_angle, rotate_direction = postprocess.alignment_procedure(
274-
facial_img, right_eye, left_eye, nose
275-
)
276-
277-
if align_first is True and len(obj) == 1:
278-
facial_area = rotate_facial_area(
279-
facial_area, rotate_angle, rotate_direction, img.shape
280-
)
281-
# Expand the facial area to be extracted and stay within img.shape limits
282-
x1 = max(0, facial_area[0] - int((facial_area[2] * expand_face_area) / 100))
283-
y1 = max(0, facial_area[1] - int((facial_area[3] * expand_face_area) / 100))
284-
x2 = min(
285-
img.shape[1], facial_area[2] + int((facial_area[2] * expand_face_area) / 100)
286-
)
287-
y2 = min(
288-
img.shape[0], facial_area[3] + int((facial_area[3] * expand_face_area) / 100)
289-
)
290-
facial_img = facial_img[y1:y2, x1:x2]
291-
292-
resp.append(facial_img[:, :, ::-1])
293-
294-
return resp
295-
296-
def rotate_facial_area(facial_area: Tuple[int, int, int, int], angle: float, direction:
297-
int, size: Tuple[int, int]) -> Tuple[int, int, int, int]:
298-
"""
299-
Rotate the facial area around its center.
300-
301-
Args:
302-
facial_area (tuple of int): Representing the (x1, y1, x2, y2) of the facial area.
303-
angle (float): Angle of rotation in degrees.
304-
direction (int): Direction of rotation (-1 for clockwise, 1 for counterclockwise).
305-
size (tuple of int): Tuple representing the size of the image (width, height).
306-
307-
Returns:
308-
tuple of int: Representing the new coordinates (x1, y1, x2, y2) of the rotated facial area.
309-
"""
310-
# Angle in radians
311-
angle = angle * np.pi / 180
312-
313-
# Translate the facial area to the center of the image
314-
x = (facial_area[0] + facial_area[2]) / 2 - size[1] / 2
315-
y = (facial_area[1] + facial_area[3]) / 2 - size[0] / 2
316-
317-
# Rotate the facial area
318-
x_new = x * np.cos(angle) + y * direction * np.sin(angle)
319-
y_new = -x * direction * np.sin(angle) + y * np.cos(angle)
320-
321-
# Translate the facial area back to the original position
322-
x_new = x_new + size[1] / 2
323-
y_new = y_new + size[0] / 2
246+
if not isinstance(obj, dict):
247+
return resp
324248

325-
# Calculate the new facial area
326-
x1 = x_new - (facial_area[2] - facial_area[0]) / 2
327-
y1 = y_new - (facial_area[3] - facial_area[1]) / 2
328-
x2 = x_new + (facial_area[2] - facial_area[0]) / 2
329-
y2 = y_new + (facial_area[3] - facial_area[1]) / 2
249+
for _, identity in obj.items():
250+
facial_area = identity["facial_area"]
251+
rotate_angle = 0
252+
rotate_direction = 1
253+
254+
x = facial_area[0]
255+
y = facial_area[1]
256+
w = facial_area[2]
257+
h = facial_area[3]
258+
259+
# expand the facial area to be extracted and stay within img.shape limits
260+
x1 = max(0, x - int((w * expand_face_area) / 100)) # expand left
261+
y1 = max(0, y - int((h * expand_face_area) / 100)) # expand top
262+
x2 = min(img.shape[1], w + int((w * expand_face_area) / 100)) # expand right
263+
y2 = min(img.shape[0], h + int((h * expand_face_area) / 100)) # expand bottom
264+
265+
if align_first is False or (align_first is True and len(obj) > 1):
266+
facial_img = img[y1:y2, x1:x2]
267+
else:
268+
facial_img = img.copy()
269+
270+
if align is True:
271+
landmarks = identity["landmarks"]
272+
left_eye = landmarks["left_eye"]
273+
right_eye = landmarks["right_eye"]
274+
nose = landmarks["nose"]
275+
# mouth_right = landmarks["mouth_right"]
276+
# mouth_left = landmarks["mouth_left"]
277+
facial_img, rotate_angle, rotate_direction = postprocess.alignment_procedure(
278+
facial_img, right_eye, left_eye, nose
279+
)
280+
281+
if align_first is True and len(obj) == 1:
282+
facial_area = postprocess.rotate_facial_area(
283+
facial_area, rotate_angle, rotate_direction, img.shape
284+
)
285+
# Expand the facial area to be extracted and stay within img.shape limits
286+
x1 = max(0, facial_area[0] - int((facial_area[2] * expand_face_area) / 100))
287+
y1 = max(0, facial_area[1] - int((facial_area[3] * expand_face_area) / 100))
288+
x2 = min(img.shape[1], facial_area[2] + int((facial_area[2] * expand_face_area) / 100))
289+
y2 = min(img.shape[0], facial_area[3] + int((facial_area[3] * expand_face_area) / 100))
290+
facial_img = facial_img[y1:y2, x1:x2]
291+
292+
resp.append(facial_img[:, :, ::-1])
330293

331-
return (int(x1), int(y1), int(x2), int(y2))
294+
return resp

retinaface/commons/postprocess.py

+48-6
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
import math
2-
from typing import Union
2+
from typing import Union, Tuple
33
import numpy as np
44
from PIL import Image
55

66

77
# pylint: disable=unused-argument
88

99

10-
def findEuclideanDistance(
10+
def find_euclidean_distance(
1111
source_representation: Union[np.ndarray, list], test_representation: Union[np.ndarray, list]
1212
) -> float:
1313
"""
@@ -30,7 +30,9 @@ def findEuclideanDistance(
3030
return euclidean_distance
3131

3232

33-
def alignment_procedure(img: np.ndarray, left_eye: tuple, right_eye: tuple, nose: tuple):
33+
def alignment_procedure(
34+
img: np.ndarray, left_eye: tuple, right_eye: tuple, nose: tuple
35+
) -> Tuple[np.ndarray, float, int]:
3436
"""
3537
Alignma given face with respect to the left and right eye coordinates.
3638
Left eye is the eye appearing on the left (right eye of the person). Left top point is (0, 0)
@@ -58,9 +60,9 @@ def alignment_procedure(img: np.ndarray, left_eye: tuple, right_eye: tuple, nose
5860
# -----------------------
5961
# find length of triangle edges
6062

61-
a = findEuclideanDistance(np.array(left_eye), np.array(point_3rd))
62-
b = findEuclideanDistance(np.array(right_eye), np.array(point_3rd))
63-
c = findEuclideanDistance(np.array(right_eye), np.array(left_eye))
63+
a = find_euclidean_distance(np.array(left_eye), np.array(point_3rd))
64+
b = find_euclidean_distance(np.array(right_eye), np.array(point_3rd))
65+
c = find_euclidean_distance(np.array(right_eye), np.array(left_eye))
6466

6567
# -----------------------
6668
# apply cosine rule
@@ -91,6 +93,46 @@ def alignment_procedure(img: np.ndarray, left_eye: tuple, right_eye: tuple, nose
9193
return img, angle, direction
9294

9395

96+
def rotate_facial_area(
97+
facial_area: Tuple[int, int, int, int], angle: float, direction: int, size: Tuple[int, int]
98+
) -> Tuple[int, int, int, int]:
99+
"""
100+
Rotate the facial area around its center.
101+
102+
Args:
103+
facial_area (tuple of int): Representing the (x1, y1, x2, y2) of the facial area.
104+
angle (float): Angle of rotation in degrees.
105+
direction (int): Direction of rotation (-1 for clockwise, 1 for counterclockwise).
106+
size (tuple of int): Tuple representing the size of the image (width, height).
107+
108+
Returns:
109+
rotated_facial_area (tuple of int): Representing the new coordinates
110+
(x1, y1, x2, y2) of the rotated facial area.
111+
"""
112+
# Angle in radians
113+
angle = angle * np.pi / 180
114+
115+
# Translate the facial area to the center of the image
116+
x = (facial_area[0] + facial_area[2]) / 2 - size[1] / 2
117+
y = (facial_area[1] + facial_area[3]) / 2 - size[0] / 2
118+
119+
# Rotate the facial area
120+
x_new = x * np.cos(angle) + y * direction * np.sin(angle)
121+
y_new = -x * direction * np.sin(angle) + y * np.cos(angle)
122+
123+
# Translate the facial area back to the original position
124+
x_new = x_new + size[1] / 2
125+
y_new = y_new + size[0] / 2
126+
127+
# Calculate the new facial area
128+
x1 = x_new - (facial_area[2] - facial_area[0]) / 2
129+
y1 = y_new - (facial_area[3] - facial_area[1]) / 2
130+
x2 = x_new + (facial_area[2] - facial_area[0]) / 2
131+
y2 = y_new + (facial_area[3] - facial_area[1]) / 2
132+
133+
return (int(x1), int(y1), int(x2), int(y2))
134+
135+
94136
def bbox_pred(boxes, box_deltas):
95137
"""
96138
This function is copied from the following code snippet:

tests/test_expand_face_area.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ def test_expand_face_area():
2525
landmarks1 = obj1["face_1"]["landmarks"]
2626
landmarks2 = obj2["face_1"]["landmarks"]
2727

28-
distance1 = postprocess.findEuclideanDistance(landmarks1["right_eye"], landmarks1["left_eye"])
29-
distance2 = postprocess.findEuclideanDistance(landmarks2["right_eye"], landmarks2["left_eye"])
28+
distance1 = postprocess.find_euclidean_distance(landmarks1["right_eye"], landmarks1["left_eye"])
29+
distance2 = postprocess.find_euclidean_distance(landmarks2["right_eye"], landmarks2["left_eye"])
3030

3131
# 2nd one's expand ratio is higher. so, it should be smaller.
3232
assert distance2 < distance1

0 commit comments

Comments
 (0)