6.3. Python编程详解
SOPHONSDK通过SAIL库向用户提供Python编程接口。
这个章节将会选取 YOLOV5 检测算法作为示例, 来介绍python接口编程,样例代码路径位于sophon-demo/sample/YOLOV5
其他sail关于接口的更详细的信息,请阅读《 SOPHON-SAIL用户手册 》。
本章主要介绍以下三点内容:
加载模型
预处理
推理
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. 预处理
1def preprocess(self, ori_img):
2 """
3 pre-processing
4 Args:
5 img: numpy.ndarray -- (h,w,3)
6
7 Returns: (3,h,w) numpy.ndarray after pre-processing
8
9 """
10 letterbox_img, ratio, (tx1, ty1) = self.letterbox(
11 ori_img,
12 new_shape=(self.net_h, self.net_w),
13 color=(114, 114, 114),
14 auto=False,
15 scaleFill=False,
16 scaleup=True,
17 stride=32
18 )
19
20 img = letterbox_img.transpose((2, 0, 1))[::-1] # HWC to CHW, BGR to RGB
21 img = img.astype(np.float32)
22 # input_data = np.expand_dims(input_data, 0)
23 img = np.ascontiguousarray(img / 255.0)
24 return img, ratio, (tx1, ty1)
25
26def letterbox(self, im, new_shape=(640, 640), color=(114, 114, 114), auto=False, scaleFill=False, scaleup=True, stride=32):
27 # Resize and pad image while meeting stride-multiple constraints
28 shape = im.shape[:2] # current shape [height, width]
29 if isinstance(new_shape, int):
30 new_shape = (new_shape, new_shape)
31
32 # Scale ratio (new / old)
33 r = min(new_shape[0] / shape[0], new_shape[1] / shape[1])
34 if not scaleup: # only scale down, do not scale up (for better val mAP)
35 r = min(r, 1.0)
36
37 # Compute padding
38 ratio = r, r # width, height ratios
39 new_unpad = int(round(shape[1] * r)), int(round(shape[0] * r))
40 dw, dh = new_shape[1] - new_unpad[0], new_shape[0] - new_unpad[1] # wh padding
41 if auto: # minimum rectangle
42 dw, dh = np.mod(dw, stride), np.mod(dh, stride) # wh padding
43 elif scaleFill: # stretch
44 dw, dh = 0.0, 0.0
45 new_unpad = (new_shape[1], new_shape[0])
46 ratio = new_shape[1] / shape[1], new_shape[0] / shape[0] # width, height ratios
47
48 dw /= 2 # divide padding into 2 sides
49 dh /= 2
50
51 if shape[::-1] != new_unpad: # resize
52 im = cv2.resize(im, new_unpad, interpolation=cv2.INTER_LINEAR)
53 top, bottom = int(round(dh - 0.1)), int(round(dh + 0.1))
54 left, right = int(round(dw - 0.1)), int(round(dw + 0.1))
55 im = cv2.copyMakeBorder(im, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color) # add border
56 return im, ratio, (dw, dh)
57
58 ...
6.3.3. 推理
1def predict(self, input_img, img_num):
2 input_data = {self.input_name: input_img}
3 outputs = self.net.process(self.graph_name, input_data)
4
5 if self.use_cpu_opt:
6 out = {}
7 for name in outputs.keys():
8 # outputs_dict[name] = self.output_tensors[name].asnumpy()[:img_num] * self.output_scales[name]
9 out[name] = sail.Tensor(self.handle, outputs[name])
10 else:
11 # resort
12 out_keys = list(outputs.keys())
13 ord = []
14 for n in self.output_names:
15 for i, k in enumerate(out_keys):
16 if n == k:
17 ord.append(i)
18 break
19 out = [outputs[out_keys[i]][:img_num] for i in ord]
20 return out