6.3. Python编程详解
BM1688/CV186AH SOPHONSDK通过SAIL库向用户提供Python编程接口。
这个章节将会选取 YOLOV5 检测算法作为示例, 来介绍python接口编程,样例代码路径位于sophon-demo/sample/YOLOV5
关于sail接口的详细信息,请阅读doc目录下的《sophon-sail_zh》。
本章主要介绍以下三点内容:
加载模型
预处理
推理
6.3.1. 加载模型
1import sophon.sail as sail
2
3...
4
5engine = sail.Engine(model_path, device_id, io_mode)
6
7...
6.3.2. 预处理
1class PreProcess:
2 def __init__(self, width, height, batch_size, img_dtype, input_scale=None):
3
4 self.std = np.array([255., 255., 255.], dtype=np.float32)
5 self.batch_size = batch_size
6 self.input_scale = float(1.0) if input_scale is None else input_scale
7 self.img_dtype = img_dtype
8
9 self.width = width
10 self.height = height
11 self.use_resize_padding = True
12 self.use_vpp = False
13 ...
14
15 def resize(self, img, handle, bmcv):
16
17 if self.use_resize_padding:
18 img_w = img.width()
19 img_h = img.height()
20 r_w = self.width / img_w
21 r_h = self.height / img_h
22
23 if r_h > r_w:
24 tw = self.width
25 th = int(r_w * img_h)
26 tx1 = tx2 = 0
27 ty1 = int((self.height - th) / 2)
28 ty2 = self.height - th - ty1
29
30 else:
31 tw = int(r_h * img_w)
32 th = self.height
33 tx1 = int((self.width - tw) / 2)
34 tx2 = self.width - tw - tx1
35 ty1 = ty2 = 0
36
37 ratio = (min(r_w, r_h), min(r_w, r_h))
38 txy = (tx1, ty1)
39 attr = sail.PaddingAtrr()
40 attr.set_stx(tx1)
41 attr.set_sty(ty1)
42 attr.set_w(tw)
43 attr.set_h(th)
44 attr.set_r(114)
45 attr.set_g(114)
46 attr.set_b(114)
47
48 tmp_planar_img = sail.BMImage(handle, img.height(), img.width(),
49 sail.Format.FORMAT_RGB_PLANAR, sail.DATA_TYPE_EXT_1N_BYTE)
50 bmcv.convert_format(img, tmp_planar_img)
51 preprocess_fn = bmcv.vpp_crop_and_resize_padding if self.use_vpp else bmcv.crop_and_resize_padding
52 resized_img_rgb = preprocess_fn(tmp_planar_img,
53 0, 0, img.width(), img.height(),
54 self.width, self.height, attr)
55 else:
56 r_w = self.width / img.width()
57 r_h = self.height / img.height()
58 ratio = (r_w, r_h)
59 txy = (0, 0)
60 tmp_planar_img = sail.BMImage(handle, img.height(), img.width(),
61 sail.Format.FORMAT_RGB_PLANAR, sail.DATA_TYPE_EXT_1N_BYTE)
62 bmcv.convert_format(img, tmp_planar_img)
63 preprocess_fn = bmcv.vpp_resize if self.use_vpp else bmcv.resize
64 resized_img_rgb = preprocess_fn(tmp_planar_img, self.width, self.height)
65 return resized_img_rgb, ratio, txy
66
67 ...
68
69 def norm_batch(self, resized_images, handle, bmcv):
70
71 bm_array = eval('sail.BMImageArray{}D'.format(self.batch_size))
72
73 preprocessed_imgs = bm_array(handle,
74 self.height,
75 self.width,
76 sail.FORMAT_RGB_PLANAR,
77 self.img_dtype)
78
79 a = 1 / self.std
80 b = (0, 0, 0)
81 alpha_beta = tuple([(ia * self.input_scale, ib * self.input_scale) for ia, ib in zip(a, b)])
82
83 # do convert_to
84 bmcv.convert_to(resized_images, preprocessed_imgs, alpha_beta)
85 return preprocessed_imgs
6.3.3. 推理
1class SophonInference:
2 def __init__(self, **kwargs):
3
4 ...
5
6 self.io_mode = sail.IOMode.SYSIO
7 self.engine = sail.Engine(self.model_path, self.device_id, self.io_mode)
8 self.handle = self.engine.get_handle()
9 self.graph_name = self.engine.get_graph_names()[0]
10 self.bmcv = sail.Bmcv(self.handle)
11
12 ...
13
14 input_names = self.engine.get_input_names(self.graph_name)
15 for input_name in input_names:
16
17 input_shape = self.engine.get_input_shape(self.graph_name, input_name)
18 input_dtype = self.engine.get_input_dtype(self.graph_name, input_name)
19 input_scale = self.engine.get_input_scale(self.graph_name, input_name)
20 ...
21 if self.input_mode:
22 input = sail.Tensor(self.handle, input_shape, input_dtype, True, True)
23 ...
24 input_tensors[input_name] = input
25 ...
26
27 output_names = self.engine.get_output_names(self.graph_name)
28
29 for output_name in output_names:
30
31 output_shape = self.engine.get_output_shape(self.graph_name, output_name)
32 output_dtype = self.engine.get_output_dtype(self.graph_name, output_name)
33 output_scale = self.engine.get_output_scale(self.graph_name, output_name)
34 ...
35 if self.input_mode:
36 output = sail.Tensor(self.handle, output_shape, output_dtype, True, True)
37 ...
38 output_tensors[output_name] = output
39 ...
40 def infer_bmimage(self, input_data):
41 self.get_input_feed(self.input_names, input_data)
42
43 #inference
44 self.engine.process(self.graph_name, self.input_tensors, self.output_tensors)
45 outputs_dict = OrderedDict()
46 for name in self.output_names:
47 outputs_dict[name] = self.output_tensors[name].asnumpy().copy() * self.output_scales[name]
48 return outputs_dict