-
Notifications
You must be signed in to change notification settings - Fork 201
/
Copy pathdemo.py
135 lines (108 loc) · 5.2 KB
/
demo.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
import sys
import argparse
import copy
import datetime
import numpy as np
import cv2 as cv
# Check OpenCV version
opencv_python_version = lambda str_version: tuple(map(int, (str_version.split("."))))
assert opencv_python_version(cv.__version__) >= opencv_python_version("4.10.0"), \
"Please install latest opencv-python for benchmark: python3 -m pip install --upgrade opencv-python"
from facial_fer_model import FacialExpressionRecog
sys.path.append('../face_detection_yunet')
from yunet import YuNet
# Valid combinations of backends and targets
backend_target_pairs = [
[cv.dnn.DNN_BACKEND_OPENCV, cv.dnn.DNN_TARGET_CPU],
[cv.dnn.DNN_BACKEND_CUDA, cv.dnn.DNN_TARGET_CUDA],
[cv.dnn.DNN_BACKEND_CUDA, cv.dnn.DNN_TARGET_CUDA_FP16],
[cv.dnn.DNN_BACKEND_TIMVX, cv.dnn.DNN_TARGET_NPU],
[cv.dnn.DNN_BACKEND_CANN, cv.dnn.DNN_TARGET_NPU]
]
parser = argparse.ArgumentParser(description='Facial Expression Recognition')
parser.add_argument('--input', '-i', type=str,
help='Path to the input image. Omit for using default camera.')
parser.add_argument('--model', '-m', type=str, default='./facial_expression_recognition_mobilefacenet_2022july.onnx',
help='Path to the facial expression recognition model.')
parser.add_argument('--backend_target', '-bt', type=int, default=0,
help='''Choose one of the backend-target pair to run this demo:
{:d}: (default) OpenCV implementation + CPU,
{:d}: CUDA + GPU (CUDA),
{:d}: CUDA + GPU (CUDA FP16),
{:d}: TIM-VX + NPU,
{:d}: CANN + NPU
'''.format(*[x for x in range(len(backend_target_pairs))]))
parser.add_argument('--save', '-s', action='store_true',
help='Specify to save results. This flag is invalid when using camera.')
parser.add_argument('--vis', '-v', action='store_true',
help='Specify to open a window for result visualization. This flag is invalid when using camera.')
args = parser.parse_args()
def visualize(image, det_res, fer_res, box_color=(0, 255, 0), text_color=(0, 0, 255)):
print('%s %3d faces detected.' % (datetime.datetime.now(), len(det_res)))
output = image.copy()
landmark_color = [
(255, 0, 0), # right eye
(0, 0, 255), # left eye
(0, 255, 0), # nose tip
(255, 0, 255), # right mouth corner
(0, 255, 255) # left mouth corner
]
for ind, (det, fer_type) in enumerate(zip(det_res, fer_res)):
bbox = det[0:4].astype(np.int32)
fer_type = FacialExpressionRecog.getDesc(fer_type)
print("Face %2d: %d %d %d %d %s." % (ind, bbox[0], bbox[1], bbox[0]+bbox[2], bbox[1]+bbox[3], fer_type))
cv.rectangle(output, (bbox[0], bbox[1]), (bbox[0]+bbox[2], bbox[1]+bbox[3]), box_color, 2)
cv.putText(output, fer_type, (bbox[0], bbox[1]+12), cv.FONT_HERSHEY_DUPLEX, 0.5, text_color)
landmarks = det[4:14].astype(np.int32).reshape((5, 2))
for idx, landmark in enumerate(landmarks):
cv.circle(output, landmark, 2, landmark_color[idx], 2)
return output
def process(detect_model, fer_model, frame):
h, w, _ = frame.shape
detect_model.setInputSize([w, h])
dets = detect_model.infer(frame)
if dets is None:
return False, None, None
fer_res = np.zeros(0, dtype=np.int8)
for face_points in dets:
fer_res = np.concatenate((fer_res, fer_model.infer(frame, face_points[:-1])), axis=0)
return True, dets, fer_res
if __name__ == '__main__':
backend_id = backend_target_pairs[args.backend_target][0]
target_id = backend_target_pairs[args.backend_target][1]
detect_model = YuNet(modelPath='../face_detection_yunet/face_detection_yunet_2023mar.onnx')
fer_model = FacialExpressionRecog(modelPath=args.model,
backendId=backend_id,
targetId=target_id)
# If input is an image
if args.input is not None:
image = cv.imread(args.input)
# Get detection and fer results
status, dets, fer_res = process(detect_model, fer_model, image)
if status:
# Draw results on the input image
image = visualize(image, dets, fer_res)
# Save results
if args.save:
cv.imwrite('result.jpg', image)
print('Results saved to result.jpg\n')
# Visualize results in a new window
if args.vis:
cv.namedWindow(args.input, cv.WINDOW_AUTOSIZE)
cv.imshow(args.input, image)
cv.waitKey(0)
else: # Omit input to call default camera
deviceId = 0
cap = cv.VideoCapture(deviceId)
while cv.waitKey(1) < 0:
hasFrame, frame = cap.read()
if not hasFrame:
print('No frames grabbed!')
break
# Get detection and fer results
status, dets, fer_res = process(detect_model, fer_model, frame)
if status:
# Draw results on the input image
frame = visualize(frame, dets, fer_res)
# Visualize results in a new window
cv.imshow('FER Demo', frame)