Skip to content

Commit 03306c5

Browse files
authored
add a demo of video inference (#200)
1 parent 4720be1 commit 03306c5

File tree

4 files changed

+149
-3
lines changed

4 files changed

+149
-3
lines changed

README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,13 @@ With a pretrained weight, you can run inference on an single image like this:
5858
$ python tools/demo.py --config configs/bisenetv2_city.py --weight-path /path/to/your/weights.pth --img-path ./example.png
5959
```
6060

61-
This would run inference on the image and save the result image to `./res.jpg`.
61+
This would run inference on the image and save the result image to `./res.jpg`.
62+
63+
Or you can run inference on a video like this:
64+
```
65+
$ python tools/demo_video.py --config configs/bisenetv2_coco.py --weight-path res/model_final.pth --input ./video.mp4 --output res.mp4
66+
```
67+
This would generate segmentation file as `res.mp4`. If you want to read from camera, you can set `--input camera_id` rather than `input ./video.mp4`.
6268

6369

6470
## prepare dataset

openvino/README.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ If you want to use gpu, you also need to install some dependencies inside the co
5757

5858
I got the above commands from the official docs but I did not test it since my cpu does not have integrated gpu.
5959

60+
You can check if your platform has intel gpu with this command:
61+
```
62+
$ sudo lspci | grep -i vga
63+
```
6064

6165
4.configure environment
6266
just run this script, and the environment would be ready:
@@ -87,6 +91,6 @@ After this, you will see a segmentation result image named `res.jpg` generated.
8791

8892
### Tipes
8993

90-
1.GPU support: openvino supports intel cpu and intel "gpu inside cpu". Until now(2021.11), other popular isolated gpus are not supported, such as nvidia/amd gpus. Also, other integrated gpus are not supported, such as aspeed graphics family.
94+
1. GPU support: openvino supports intel cpu and intel "gpu inside cpu". Until now(2021.11), other popular isolated gpus are not supported, such as nvidia/amd gpus. Also, other integrated gpus are not supported, such as aspeed graphics family.
9195

92-
2.About low-precision: precision is optimized automatically, and the model will be run in one or several precision mode. We can also manually enforce to use bf16, as long as our cpu have `avx512_bf16` supports. If cpu does not support bf16, it will use simulation which would slow down the inference. If neither native bf16 nor simulation is supported, an error would occur.
96+
2. About low-precision: precision is optimized automatically, and the model will be run in one or several precision mode. We can also manually enforce to use bf16, as long as our cpu have `avx512_bf16` supports. If cpu does not support bf16, it will use simulation which would slow down the inference. If neither native bf16 nor simulation is supported, an error would occur.

tools/demo_video.py

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
2+
import sys
3+
sys.path.insert(0, '.')
4+
import argparse
5+
import torch
6+
import torch.nn as nn
7+
import torch.nn.functional as F
8+
from PIL import Image
9+
import numpy as np
10+
import cv2
11+
from torch.multiprocessing import Process, Queue
12+
13+
import lib.transform_cv2 as T
14+
from lib.models import model_factory
15+
from configs import set_cfg_from_file
16+
17+
18+
torch.set_grad_enabled(False)
19+
20+
21+
# args
22+
parse = argparse.ArgumentParser()
23+
parse.add_argument('--config', dest='config', type=str, default='configs/bisenetv2.py',)
24+
parse.add_argument('--weight-path', type=str, default='./res/model_final.pth',)
25+
parse.add_argument('--input', dest='input', type=str, default='./example.mp4',)
26+
parse.add_argument('--output', dest='output', type=str, default='./res.mp4',)
27+
args = parse.parse_args()
28+
cfg = set_cfg_from_file(args.config)
29+
30+
31+
32+
# define model
33+
def get_model():
34+
net = model_factory[cfg.model_type](cfg.n_cats, aux_mode='eval')
35+
net.load_state_dict(torch.load(args.weight_path, map_location='cpu'), strict=False)
36+
net.eval()
37+
net.cuda()
38+
return net
39+
40+
41+
# fetch frames
42+
def get_func(inpth, in_q):
43+
cap = cv2.VideoCapture(args.input)
44+
width = cap.get(cv2.CAP_PROP_FRAME_WIDTH) # type is float
45+
height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT) # type is float
46+
fps = cap.get(cv2.CAP_PROP_FPS)
47+
48+
to_tensor = T.ToTensor(
49+
mean=(0.3257, 0.3690, 0.3223), # city, rgb
50+
std=(0.2112, 0.2148, 0.2115),
51+
)
52+
53+
while cap.isOpened():
54+
ret, frame = cap.read()
55+
if not ret: break
56+
frame = to_tensor(dict(im=frame, lb=None))['im'].unsqueeze(0)
57+
frame = frame.flip(dims=(1,)) # rgb
58+
in_q.put(frame)
59+
60+
in_q.put('quit')
61+
while not in_q.empty(): continue
62+
cap.release()
63+
print('input queue done')
64+
65+
66+
# save to video
67+
def save_func(inpth, outpth, out_q):
68+
np.random.seed(123)
69+
palette = np.random.randint(0, 256, (256, 3), dtype=np.uint8)
70+
71+
cap = cv2.VideoCapture(args.input)
72+
width = cap.get(cv2.CAP_PROP_FRAME_WIDTH) # type is float
73+
height = cap.get(cv2.CAP_PROP_FRAME_HEIGHT) # type is float
74+
fps = cap.get(cv2.CAP_PROP_FPS)
75+
cap.release()
76+
77+
video_writer = cv2.VideoWriter(outpth,
78+
cv2.VideoWriter_fourcc(*"mp4v"),
79+
fps, (int(width), int(height)))
80+
81+
while True:
82+
out = out_q.get()
83+
if out == 'quit': break
84+
out = out.numpy()
85+
preds = palette[out]
86+
for pred in preds:
87+
video_writer.write(pred)
88+
video_writer.release()
89+
print('output queue done')
90+
91+
92+
# inference a list of frames
93+
def infer_batch(frames):
94+
frames = torch.cat(frames, dim=0).cuda()
95+
H, W = frames.size()[2:]
96+
frames = F.interpolate(frames, size=(768, 768), mode='bilinear',
97+
align_corners=False) # must be divisible by 32
98+
out = net(frames)[0]
99+
out = F.interpolate(out, size=(H, W), mode='bilinear',
100+
align_corners=False).argmax(dim=1).detach().cpu()
101+
out_q.put(out)
102+
103+
104+
105+
if __name__ == '__main__':
106+
torch.multiprocessing.set_start_method('spawn')
107+
108+
in_q = Queue(1024)
109+
out_q = Queue(1024)
110+
111+
in_worker = Process(target=get_func,
112+
args=(args.input, in_q))
113+
out_worker = Process(target=save_func,
114+
args=(args.input, args.output, out_q))
115+
116+
in_worker.start()
117+
out_worker.start()
118+
119+
net = get_model()
120+
121+
frames = []
122+
while True:
123+
frame = in_q.get()
124+
if frame == 'quit': break
125+
126+
frames.append(frame)
127+
if len(frames) == 8:
128+
infer_batch(frames)
129+
frames = []
130+
if len(frames) > 0:
131+
infer_batch(frames)
132+
133+
out_q.put('quit')
134+
135+
out_worker.join()
136+
in_worker.join()

video.mp4

1.21 MB
Binary file not shown.

0 commit comments

Comments
 (0)