1
- #pytorch
2
- import torch
3
- from torchvision import transforms
1
+ import time
4
2
5
- #other lib
6
- import sys
7
- import numpy as np
8
3
import cv2
9
- import time
10
4
11
- sys .path .insert (0 , "face_detection/yolov5_face" )
12
-
13
- from face_detection .yolov5_face .models .experimental import attempt_load
14
- from face_detection .yolov5_face .utils .datasets import letterbox
15
- from face_detection .yolov5_face .utils .general import check_img_size , non_max_suppression_face , scale_coords
16
-
17
- # Check device
18
- device = torch .device ("cuda" if torch .cuda .is_available () else "cpu" )
19
-
20
- # Get model detect
21
- ## Case 1:
22
- # model = attempt_load("face_detection/yolov5_face/yolov5s-face.pt", map_location=device)
23
-
24
- ## Case 2:
25
- model = attempt_load ("face_detection/yolov5_face/yolov5n-0.5.pt" , map_location = device )
26
-
27
- # Resize image
28
- def resize_image (img0 , img_size ):
29
- h0 , w0 = img0 .shape [:2 ] # orig hw
30
- r = img_size / max (h0 , w0 ) # resize image to img_size
31
-
32
- if r != 1 : # always resize down, only resize up if training with augmentation
33
- interp = cv2 .INTER_AREA if r < 1 else cv2 .INTER_LINEAR
34
- img0 = cv2 .resize (img0 , (int (w0 * r ), int (h0 * r )), interpolation = interp )
35
-
36
- imgsz = check_img_size (img_size , s = model .stride .max ()) # check img_size
37
- img = letterbox (img0 , new_shape = imgsz )[0 ]
38
-
39
- # Convert
40
- img = img [:, :, ::- 1 ].transpose (2 , 0 , 1 ).copy () # BGR to RGB, to 3x416x416
41
-
42
- img = torch .from_numpy (img ).to (device )
43
- img = img .float () # uint8 to fp16/32
44
- img /= 255.0 # 0 - 255 to 0.0 - 1.0
45
-
46
- return img
47
-
48
- def scale_coords_landmarks (img1_shape , coords , img0_shape , ratio_pad = None ):
49
- # Rescale coords (xyxy) from img1_shape to img0_shape
50
- if ratio_pad is None : # calculate from img0_shape
51
- gain = min (img1_shape [0 ] / img0_shape [0 ], img1_shape [1 ] / img0_shape [1 ]) # gain = old / new
52
- pad = (img1_shape [1 ] - img0_shape [1 ] * gain ) / 2 , (img1_shape [0 ] - img0_shape [0 ] * gain ) / 2 # wh padding
53
- else :
54
- gain = ratio_pad [0 ][0 ]
55
- pad = ratio_pad [1 ]
56
-
57
- coords [:, [0 , 2 , 4 , 6 , 8 ]] -= pad [0 ] # x padding
58
- coords [:, [1 , 3 , 5 , 7 , 9 ]] -= pad [1 ] # y padding
59
- coords [:, :10 ] /= gain
60
- #clip_coords(coords, img0_shape)
61
- coords [:, 0 ].clamp_ (0 , img0_shape [1 ]) # x1
62
- coords [:, 1 ].clamp_ (0 , img0_shape [0 ]) # y1
63
- coords [:, 2 ].clamp_ (0 , img0_shape [1 ]) # x2
64
- coords [:, 3 ].clamp_ (0 , img0_shape [0 ]) # y2
65
- coords [:, 4 ].clamp_ (0 , img0_shape [1 ]) # x3
66
- coords [:, 5 ].clamp_ (0 , img0_shape [0 ]) # y3
67
- coords [:, 6 ].clamp_ (0 , img0_shape [1 ]) # x4
68
- coords [:, 7 ].clamp_ (0 , img0_shape [0 ]) # y4
69
- coords [:, 8 ].clamp_ (0 , img0_shape [1 ]) # x5
70
- coords [:, 9 ].clamp_ (0 , img0_shape [0 ]) # y5
71
- return coords
72
-
73
- def get_face (input_image ):
74
- # Parameters
75
- size_convert = 128
76
- conf_thres = 0.4
77
- iou_thres = 0.5
78
-
79
- # Resize image
80
- img = resize_image (input_image .copy (), size_convert )
81
-
82
- # Via yolov5-face
83
- with torch .no_grad ():
84
- pred = model (img [None , :])[0 ]
85
-
86
- # Apply NMS
87
- det = non_max_suppression_face (pred , conf_thres , iou_thres )[0 ]
88
- bboxs = np .int32 (scale_coords (img .shape [1 :], det [:, :4 ], input_image .shape ).round ().cpu ().numpy ())
89
-
90
- landmarks = np .int32 (scale_coords_landmarks (img .shape [1 :], det [:, 5 :15 ], input_image .shape ).round ().cpu ().numpy ())
91
-
92
- return bboxs , landmarks
5
+ from face_detection .yolov5_face .detect import Detector
6
+
93
7
94
8
def main ():
95
- # Open camera
9
+ detector = Detector ()
10
+
11
+ # Open camera
96
12
cap = cv2 .VideoCapture (0 )
97
13
start = time .time_ns ()
98
14
frame_count = 0
99
15
fps = - 1
100
-
16
+
101
17
# Save video
102
18
frame_width = int (cap .get (3 ))
103
19
frame_height = int (cap .get (4 ))
104
-
20
+
105
21
size = (frame_width , frame_height )
106
- video = cv2 .VideoWriter ('results/face-detection.mp4' ,cv2 .VideoWriter_fourcc (* 'mp4v' ), 30 , size )
107
-
22
+ video = cv2 .VideoWriter (
23
+ "results/face-detection.mp4" , cv2 .VideoWriter_fourcc (* "mp4v" ), 30 , size
24
+ )
25
+
108
26
# Read until video is completed
109
- while ( True ) :
27
+ while True :
110
28
# Capture frame-by-frame
111
29
_ , frame = cap .read ()
112
-
30
+
113
31
# Get faces
114
- bboxs , landmarks = get_face ( frame )
115
- h ,w , c = frame .shape
116
-
32
+ bboxs , landmarks = detector . inference_detect ( input_image = frame )
33
+ h , w , c = frame .shape
34
+
117
35
tl = 1 or round (0.002 * (h + w ) / 2 ) + 1 # line/font thickness
118
- clors = [(255 ,0 ,0 ),(0 ,255 ,0 ),(0 ,0 ,255 ),(255 ,255 ,0 ),(0 ,255 ,255 )]
119
-
36
+ clors = [(255 , 0 , 0 ), (0 , 255 , 0 ), (0 , 0 , 255 ), (255 , 255 , 0 ), (0 , 255 , 255 )]
120
37
121
38
# Get boxs
122
39
for i in range (len (bboxs )):
123
40
# Get location face
124
41
x1 , y1 , x2 , y2 = bboxs [i ]
125
42
cv2 .rectangle (frame , (x1 , y1 ), (x2 , y2 ), (0 , 146 , 230 ), 2 )
126
-
43
+
127
44
# Landmarks
128
45
for x in range (5 ):
129
46
point_x = int (landmarks [i ][2 * x ])
130
47
point_y = int (landmarks [i ][2 * x + 1 ])
131
- cv2 .circle (frame , (point_x , point_y ), tl + 1 , clors [x ], - 1 )
132
-
133
- # Count fps
48
+ cv2 .circle (frame , (point_x , point_y ), tl + 1 , clors [x ], - 1 )
49
+
50
+ # Count fps
134
51
frame_count += 1
135
-
52
+
136
53
if frame_count >= 30 :
137
54
end = time .time_ns ()
138
55
fps = 1e9 * frame_count / (end - start )
@@ -141,22 +58,25 @@ def main():
141
58
142
59
if fps > 0 :
143
60
fps_label = "FPS: %.2f" % fps
144
- cv2 .putText (frame , fps_label , (10 , 25 ), cv2 .FONT_HERSHEY_SIMPLEX , 1 , (0 , 0 , 255 ), 2 )
145
-
146
- #Save video
61
+ cv2 .putText (
62
+ frame , fps_label , (10 , 25 ), cv2 .FONT_HERSHEY_SIMPLEX , 1 , (0 , 0 , 255 ), 2
63
+ )
64
+
65
+ # Save video
147
66
video .write (frame )
148
-
149
- #Show result
67
+
68
+ # Show result
150
69
cv2 .imshow ("Face Detection" , frame )
151
-
70
+
152
71
# Press Q on keyboard to exit
153
- if cv2 .waitKey (25 ) & 0xFF == ord ('q' ):
154
- break
155
-
72
+ if cv2 .waitKey (25 ) & 0xFF == ord ("q" ):
73
+ break
74
+
156
75
video .release ()
157
76
cap .release ()
158
77
cv2 .destroyAllWindows ()
159
78
cv2 .waitKey (0 )
160
79
161
- if __name__ == "__main__" :
162
- main ()
80
+
81
+ if __name__ == "__main__" :
82
+ main ()
0 commit comments