Skip to content

Commit 297d594

Browse files
committed
Update 部署 OpenVINO YOLOv5推理
1 parent 8d94d46 commit 297d594

File tree

3 files changed

+512
-0
lines changed

3 files changed

+512
-0
lines changed
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import os
2+
import sys
3+
from pathlib import Path
4+
5+
import torch
6+
import cv2
7+
8+
FILE = Path(__file__).resolve()
9+
ROOT = FILE.parents[0] # YOLOv5 root directory
10+
if str(ROOT) not in sys.path:
11+
sys.path.append(str(ROOT)) # add ROOT to PATH
12+
ROOT = Path(os.path.relpath(ROOT, Path.cwd())) # relative
13+
14+
# from models.common import DetectMultiBackend
15+
from standalone_model import DetectMultiBackend
16+
from standalone_utils import increment_path, colorstr, Profile, LOGGER, LoadImages, scale_boxes, non_max_suppression
17+
18+
19+
@torch.no_grad()
20+
def run(
21+
weights=ROOT / 'yolov5s/POT_INT8_openvino_model', # model path or triton URL
22+
source=ROOT / 'data/images', # file/dir/URL/glob/screen/0(webcam)
23+
data=ROOT / 'data/coco128.yaml', # dataset.yaml path
24+
imgsz=(640, 640), # inference size (height, width)
25+
conf_thres=0.25, # confidence threshold
26+
iou_thres=0.45, # NMS IOU threshold
27+
max_det=1000, # maximum detections per image
28+
device='cpu', # cuda device, i.e. 0 or 0,1,2,3 or cpu
29+
save_img=True, # save results
30+
classes=None, # filter by class: --class 0, or --class 0 2 3
31+
agnostic_nms=False, # class-agnostic NMS
32+
augment=False, # augmented inference
33+
visualize=False, # visualize features
34+
project=ROOT / 'runs/detect', # save results to project/name
35+
name='exp', # save results to project/name
36+
exist_ok=False, # existing project/name ok, do not increment
37+
line_thickness=3, # bounding box thickness (pixels)
38+
hide_labels=False, # hide labels
39+
hide_conf=False, # hide confidences
40+
half=False, # use FP16 half-precision inference
41+
vid_stride=1, # video frame-rate stride
42+
):
43+
source = str(source)
44+
45+
# Directories
46+
save_dir = increment_path(Path(project) / name, exist_ok=exist_ok) # increment run
47+
save_dir.mkdir(parents=True, exist_ok=True) # make dir
48+
49+
# Load model
50+
device = torch.device(device)
51+
model = DetectMultiBackend(weights, device=device, data=data, fp16=half)
52+
stride, names = model.stride, model.names
53+
54+
# Dataloader
55+
bs = 1 # batch_size
56+
# 前处理只有letterbox+HWC2CHW+BGR2RGB+ascontiguousarray
57+
dataset = LoadImages(source, img_size=imgsz, stride=stride, auto=False, vid_stride=vid_stride)
58+
vid_path, vid_writer = [None] * bs, [None] * bs
59+
60+
# Run inference
61+
seen, dt = 0, (Profile(), Profile(), Profile())
62+
for path, im, im0s, vid_cap, s in dataset:
63+
with dt[0]:
64+
im = torch.from_numpy(im).to(model.device)
65+
im = im.half() if model.fp16 else im.float() # uint8 to fp16/32
66+
im /= 255 # 0 - 255 to 0.0 - 1.0
67+
im = im[None] # expand for batch dim
68+
69+
# Inference
70+
with dt[1]:
71+
visualize = increment_path(save_dir / Path(path).stem, mkdir=True) if visualize else False
72+
pred = model(im, augment=augment, visualize=visualize)
73+
74+
# NMS
75+
with dt[2]:
76+
pred = non_max_suppression(pred, conf_thres, iou_thres, classes, agnostic_nms, max_det=max_det)
77+
return pred
78+
79+
80+
81+
if __name__ == "__main__":
82+
run()
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
from pathlib import Path
2+
import yaml
3+
import torch
4+
import torch.nn as nn
5+
import numpy as np
6+
from openvino.runtime import Core, Layout, get_batch
7+
from standalone_utils import LOGGER
8+
9+
10+
class DetectMultiBackend(nn.Module):
11+
# YOLOv5 MultiBackend class for python inference on various backends
12+
def __init__(self, weights='yolov5s.pt', device=torch.device('cpu'), dnn=False, data=None, fp16=False, fuse=True):
13+
super().__init__()
14+
w = str(weights[0] if isinstance(weights, list) else weights)
15+
LOGGER.info(f'Loading {w} for OpenVINO inference...')
16+
ie = Core()
17+
w = next(Path(w).glob('*.xml')) # get *.xml file from *_openvino_model dir
18+
network = ie.read_model(model=w, weights=Path(w).with_suffix('.bin'))
19+
network.get_parameters()[0].set_layout(Layout("NCHW"))
20+
batch_dim = get_batch(network)
21+
batch_size = batch_dim.get_length()
22+
executable_network = ie.compile_model(network, device_name="CPU") # device_name="MYRIAD" for Intel NCS2
23+
stride, names = self._load_metadata(Path(w).with_suffix('.yaml')) # load metadata
24+
self.__dict__.update(locals()) # assign all variables to self
25+
26+
def forward(self, im, augment=False, visualize=False):
27+
im = im.cpu().numpy() # FP32
28+
y = list(self.executable_network([im]).values())
29+
return self.from_numpy(y[0]) if len(y) == 1 else [self.from_numpy(x) for x in y]
30+
31+
def from_numpy(self, x):
32+
return torch.from_numpy(x).to(self.device) if isinstance(x, np.ndarray) else x
33+
34+
def _load_metadata(self, file=Path('path/to/meta.yaml')):
35+
with open(file, errors='ignore') as f:
36+
d = yaml.safe_load(f)
37+
return d['stride'], d['names'] # assign stride, names

0 commit comments

Comments
 (0)