This repository has been archived by the owner on Mar 2, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
main.py
144 lines (125 loc) · 5.21 KB
/
main.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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
import argparse
import cv2
import dlib
from head_pose_geometry import HeadPoseGeometry
from head_pose_model import HeadPoseModel
from head_pose_multi import MultiHeadPoseEstimator
from head_pose_tracker import HeadPoseTracker
from image_utils import draw_and_show_landmarks_and_head_pose
from landmark_recognition import landmarks_for_face
landmark_model_path = "models/shape_predictor_68_face_landmarks.dat"
parser = argparse.ArgumentParser(description='Head pose estimation (yaw, pitch, roll)')
parser.add_argument('-i',
action='store',
dest='input_type',
help='type of input: image, video, camera',
choices=['image', 'video', 'camera'],
default='camera')
parser.add_argument('-p',
action='store',
dest='path',
help='path to input file',
required=False,
type=str)
parser.add_argument('-m',
action='store',
dest='method',
help='method used to estimate head pose: 0 - 3D model, 1 - tracking, 2 - geometry',
choices=[0, 1, 2],
type=int,
default=0)
parser.add_argument('-eval',
action='store_true',
dest='evaluate',
help='Print result of roll, yaw pitch to stdout for evaluation purpose',
default=False)
args = parser.parse_args()
if args.input_type != 'camera' and args.path is None:
print('You need to provide file input. Missing -p.')
exit(0)
def get_estimator(method, detector, predictor):
"""
Factory method for head pose estimators
:param method: method to estimate with {0, 1, 2} - {3D model, tracking, geometry}
:param detector: face detector
:param predictor: landmark detector
"""
if method == 0:
head_pose_estimator = HeadPoseModel()
elif method == 1:
head_pose_estimator = HeadPoseTracker()
elif method == 2:
head_pose_estimator = HeadPoseGeometry()
elif method == 3:
head_pose_estimator = MultiHeadPoseEstimator()
else:
raise Exception("Invalid method:{}".format(method))
return head_pose_estimator
def video_estimation(method, file_path=0):
"""
Head pose estimation for video input {video file, camera}
:param method: method to estimate with {0, 1, 2} - {3D model, tracking, geometry}
:param file_path: path to source video file, int for chosen camera input
:return:
"""
cap = cv2.VideoCapture(file_path)
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor(landmark_model_path)
head_pose_estimator = get_estimator(method, detector, predictor)
while cap.isOpened():
ret, frame = cap.read()
if ret:
landmarks = landmarks_for_face(detector, predictor, frame)
if len(landmarks) == 0 or landmarks is None:
draw_and_show_landmarks_and_head_pose([], frame, info_text="Using {}. Face not found.".format(
head_pose_estimator.get_name()))
else:
yaw, pitch, roll = head_pose_estimator.pose_for_landmarks(frame, landmarks)
if args.evaluate:
print(roll, "\t", yaw, "\t", pitch)
else:
draw_and_show_landmarks_and_head_pose(head_pose_estimator.landmarks, frame, yaw, pitch, roll,
"Using {}.".format(head_pose_estimator.get_name()))
input = cv2.waitKey(20) & 0xFF
if input == ord('q'):
break
elif input == ord('n'):
method = (method + 1) % 4
head_pose_estimator = get_estimator(method, detector, predictor)
else:
break
cap.release()
def pose_estimation(method, file_path):
"""
Head pose estimation for single image
:param method: method to estimate with {0, 1, 2} - {3D model, tracking, geometry}
:param file_path: path to source image
"""
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor(landmark_model_path)
img = cv2.imread(file_path)
if method == 0:
head_pose_estimator = HeadPoseModel()
elif method == 1:
print('Method 1 is unusable for images.')
return
elif method == 2:
head_pose_estimator = HeadPoseGeometry()
else:
raise Exception("Invalid method:{}".format(method))
landmarks = landmarks_for_face(detector, predictor, img)
success = len(landmarks) and landmarks is not None
yaw, pitch, roll = head_pose_estimator.pose_for_landmarks(img, landmarks)
if success and args.evaluate:
print(roll, "\t", yaw, "\t", pitch)
elif success:
draw_and_show_landmarks_and_head_pose(head_pose_estimator.landmarks, img, yaw, pitch, roll)
else:
draw_and_show_landmarks_and_head_pose([], img, info_text='Face not found.')
cv2.waitKey()
if args.input_type == 'camera':
video_estimation(args.method)
elif args.input_type == 'video':
video_estimation(args.method, args.path)
elif args.input_type == 'image':
pose_estimation(args.method, args.path)