-
Notifications
You must be signed in to change notification settings - Fork 1
/
locator.py
65 lines (53 loc) · 1.83 KB
/
locator.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
"""
Locate face points
"""
import cv2
import numpy as np
import stasm
def boundary_points(points):
""" Produce additional boundary points
:param points: *m* x 2 np array of x,y points
:returns: 2 additional points at the top corners
"""
x, y, w, h = cv2.boundingRect(points)
buffer_percent = 0.001
spacerw = int(w * buffer_percent)
spacerh = int(h * buffer_percent)
return [[x+spacerw, y+spacerh],
[x+w-spacerw, y+spacerh]]
def face_points(img, add_boundary_points=True):
""" Locates 77 face points using stasm (http://www.milbo.users.sonic.net/stasm)
:param img: an image array
:param add_boundary_points: bool to add 2 additional points
:returns: Array of x,y face points. Empty array if no face found
"""
try:
points = stasm.search_single(cv2.cvtColor(img, cv2.COLOR_BGR2GRAY))
except Exception as e:
print('Failed finding face points: ', e)
return []
points = points.astype(np.int32)
if len(points) == 0:
return points
if add_boundary_points:
return np.vstack([points, boundary_points(points)])
return points
def average_points(point_set):
""" Averages a set of face points from images
:param point_set: *n* x *m* x 2 array of face points. \\
*n* = number of images. *m* = number of face points per image
"""
return np.mean(point_set, 0).astype(np.int32)
def weighted_average_points(start_points, end_points, percent=0.5):
""" Weighted average of two sets of supplied points
:param start_points: *m* x 2 array of start face points.
:param end_points: *m* x 2 array of end face points.
:param percent: [0, 1] percentage weight on start_points
:returns: *m* x 2 array of weighted average points
"""
if percent <= 0:
return end_points
elif percent >= 1:
return start_points
else:
return np.asarray(start_points*percent + end_points*(1-percent), np.int32)