-
Notifications
You must be signed in to change notification settings - Fork 3
/
landmark_detection.py
77 lines (59 loc) · 2.54 KB
/
landmark_detection.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
66
67
68
69
70
71
72
73
74
75
76
77
#! /usr/bin/env python
"""
Using the provided functions in dlib to detect the points of facial landmarks in an image
"""
import numpy as np
import cv2
import dlib
# Pre-trained shape predictor from iBUG 300-W dataset
SHAPE_PREDICTOR = 'data/shape_predictor_68_face_landmarks.dat'
debug_landmark_detection=False
frontal_face_detector = dlib.get_frontal_face_detector()
landmarks_predictor = dlib.shape_predictor(SHAPE_PREDICTOR)
# convenience function from imutils
def dlib_to_cv_bounding_box(box):
# convert dlib bounding box for OpenCV display
x = box.left()
y = box.top()
w = box.right() - x
h = box.bottom() - y
return x, y, w, h
# another conversion from imutils
def landmarks_to_numpy(landmarks):
# initialize the matrix of (x, y)-coordinates with a row for each landmark
coords = np.zeros((landmarks.num_parts, 2), dtype=int)
# convert each landmark to (x, y)
for i in range(0, landmarks.num_parts):
coords[i] = (landmarks.part(i).x, landmarks.part(i).y)
# return the array of (x, y)-coordinates
return coords
def show_face_annotated(faces,landmarks, img):
for face in faces:
# draw box for face
x, y, w, h = dlib_to_cv_bounding_box(face)
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
# draw circles for landmarks
for landmark_set in landmarks:
for x, y in landmark_set:
cv2.circle(img, (x, y), 1, (0, 0, 255), -1)
# show the output image with the face detections + facial landmarks
cv2.imshow("Output", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
def detect_landmarks(img):
# this list will contain the facial landmark points for each face detected
points = []
# second argument of 1 indicates the image will be upscaled once, upscaling creates a bigger image so it is easier
# to detect the faces, can increase this number if there are troubles detecting faces
# returns a bounding box around each face
detected_faces = frontal_face_detector(img, 1)
# now that we have the boxes containing the faces find the landmarks inside them
for face in detected_faces:
# use dlib to find the expected facial landmarks in the boxes around the detected faces
landmarks = landmarks_predictor(img, face)
# add the facial landmarks in a form we can use later without dlib
points.append(landmarks_to_numpy(landmarks))
# show the bounding box
if debug_landmark_detection:
show_face_annotated(detected_faces, points, img)
return points