-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathface_detection.py
More file actions
124 lines (94 loc) · 3.8 KB
/
Copy pathface_detection.py
File metadata and controls
124 lines (94 loc) · 3.8 KB
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
import argparse
import cv2
import torch
from tqdm import tqdm
from vedacore.misc import Config, color_val, load_weights
from vedacore.parallel import collate, scatter
from vedadet.datasets.pipelines import Compose
from vedadet.engines import build_engine
from src.sort import Sort
from src.utils import iou, get_color, draw_box
from src.io import get_video_capture, get_video_writer
def parse_args():
parser = argparse.ArgumentParser(description='People counter based on face detection')
parser.add_argument('video', type=str, help='Path to the video')
parser.add_argument('config', type=str, help='Path to config file')
parser.add_argument('weights', type=str, help='Path to the weights of face detector')
parser.add_argument('--output', type=str, default='outputs/face_detection.mp4', help='Path to the output')
parser.add_argument('--start_sec', type=int, default=0, help='Process file from this second')
parser.add_argument('--duration', type=int, default=20, help='How much seconds to process')
return parser.parse_args()
def main():
args = parse_args()
door_boxes = [(1250, 70, 1440, 310)]
cfg = Config.fromfile(args.config)
engine, data_pipeline, device = prepare(cfg, weights_path=args.weights)
vidcap, video_meta = get_video_capture(args.video)
fps = video_meta['fps']
vidcap.set(cv2.CAP_PROP_POS_FRAMES, int(fps * args.start_sec))
out = get_video_writer(args.output, video_meta)
tracker = Sort(max_age=3, min_hits=1, iou_threshold=0.05)
entered_doors = set()
n_frames = int(args.duration * fps)
for _ in tqdm(range(n_frames)):
it_worked, img = vidcap.read()
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
if not it_worked:
break
# Detection
result = infer_image(img, engine, data_pipeline, device)
boxes = result[0][:, :-1]
# Tracking
tracks = tracker.update(boxes).astype(int)
boxes = tracks[:, :4].astype(int)
track_ids = tracks[:, 4]
# Check if person enters doors
for box, track_id in zip(boxes, track_ids):
enters = False
for door_box in door_boxes:
enters = (iou(door_box, box) > 0)
if enters:
break
if enters:
entered_doors.add(track_id)
# Draw doors
for box in door_boxes:
draw_box(img, box, color=(255, 0, 0), thickness=5)
# Draw faces
for box, track_id in zip(boxes, track_ids):
draw_box(img, tuple(box), color=get_color(track_id))
# Write number of entrances
cv2.putText(img, str(len(entered_doors)), (10, 150), cv2.FONT_HERSHEY_SIMPLEX, 5, (255, 255, 0), 10)
frame = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
out.write(frame)
out.release()
def prepare(cfg, weights_path):
device = torch.cuda.current_device() if torch.cuda.is_available() else 'cpu'
engine = build_engine(cfg.infer_engine)
engine.model.to(device)
load_weights(engine.model, weights_path)
data_pipeline = Compose(cfg.data_pipeline)
return engine, data_pipeline, device
def infer_image(img, engine, data_pipeline, device):
data = dict(
filename='',
ori_filename='',
img=img,
img_shape=img.shape,
ori_shape=img.shape,
img_fields=['img'],
img_prefix=None,
)
data = data_pipeline(data)
data = collate([data], samples_per_gpu=1)
if device != 'cpu':
# scatter to specified GPU
data = scatter(data, [device])[0]
else:
# just get the actual data from DataContainer
data['img_metas'] = data['img_metas'][0].data
data['img'] = data['img'][0].data
result = engine.infer(data['img'], data['img_metas'])[0]
return result
if __name__ == '__main__':
main()