deploy.py 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. # copyright (c) 2020 PaddlePaddle Authors. All Rights Reserve.
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. import sys
  15. import os
  16. import os.path as osp
  17. import time
  18. import cv2
  19. import numpy as np
  20. import yaml
  21. from six import text_type as _text_type
  22. from openvino.inference_engine import IECore
  23. from utils import logging
  24. class Predictor:
  25. def __init__(self,
  26. model_xml,
  27. model_yaml,
  28. device="CPU"):
  29. self.device = device
  30. if not osp.exists(model_xml):
  31. logging.error("model xml file is not exists in {}".format(model_xml))
  32. self.model_xml = model_xml
  33. self.model_bin = osp.splitext(model_xml)[0] + ".bin"
  34. if not osp.exists(model_yaml):
  35. logging,error("model yaml file is not exists in {}".format(model_yaml))
  36. with open(model_yaml) as f:
  37. self.info = yaml.load(f.read(), Loader=yaml.Loader)
  38. self.model_type = self.info['_Attributes']['model_type']
  39. self.model_name = self.info['Model']
  40. self.num_classes = self.info['_Attributes']['num_classes']
  41. self.labels = self.info['_Attributes']['labels']
  42. if self.info['Model'] == 'MaskRCNN':
  43. if self.info['_init_params']['with_fpn']:
  44. self.mask_head_resolution = 28
  45. else:
  46. self.mask_head_resolution = 14
  47. transforms_mode = self.info.get('TransformsMode', 'RGB')
  48. if transforms_mode == 'RGB':
  49. to_rgb = True
  50. else:
  51. to_rgb = False
  52. self.transforms = self.build_transforms(self.info['Transforms'], to_rgb)
  53. self.predictor, self.net = self.create_predictor()
  54. self.total_time = 0
  55. self.count_num = 0
  56. def create_predictor(self):
  57. #initialization for specified device
  58. logging.info("Creating Inference Engine")
  59. ie = IECore()
  60. logging.info("Loading network files:\n\t{}\n\t{}".format(self.model_xml, self.model_bin))
  61. net = ie.read_network(model=self.model_xml, weights=self.model_bin)
  62. net.batch_size = 1
  63. network_config = {}
  64. if self.device == "MYRIAD":
  65. network_config = {'VPU_HW_STAGES_OPTIMIZATION':'NO'}
  66. exec_net = ie.load_network(network=net, device_name=self.device, network_config)
  67. return exec_net, net
  68. def build_transforms(self, transforms_info, to_rgb=True):
  69. if self.model_type == "classifier":
  70. import transforms.cls_transforms as transforms
  71. elif self.model_type == "detector":
  72. import transforms.det_transforms as transforms
  73. elif self.model_type == "segmenter":
  74. import transforms.seg_transforms as transforms
  75. op_list = list()
  76. for op_info in transforms_info:
  77. op_name = list(op_info.keys())[0]
  78. op_attr = op_info[op_name]
  79. if not hasattr(transforms, op_name):
  80. raise Exception(
  81. "There's no operator named '{}' in transforms of {}".
  82. format(op_name, self.model_type))
  83. op_list.append(getattr(transforms, op_name)(**op_attr))
  84. eval_transforms = transforms.Compose(op_list)
  85. if hasattr(eval_transforms, 'to_rgb'):
  86. eval_transforms.to_rgb = to_rgb
  87. self.arrange_transforms(eval_transforms)
  88. return eval_transforms
  89. def arrange_transforms(self, eval_transforms):
  90. if self.model_type == 'classifier':
  91. import transforms.cls_transforms as transforms
  92. arrange_transform = transforms.ArrangeClassifier
  93. elif self.model_type == 'segmenter':
  94. import transforms.seg_transforms as transforms
  95. arrange_transform = transforms.ArrangeSegmenter
  96. elif self.model_type == 'detector':
  97. import transforms.det_transforms as transforms
  98. arrange_name = 'Arrange{}'.format(self.model_name)
  99. arrange_transform = getattr(transforms, arrange_name)
  100. else:
  101. raise Exception("Unrecognized model type: {}".format(
  102. self.model_type))
  103. if type(eval_transforms.transforms[-1]).__name__.startswith('Arrange'):
  104. eval_transforms.transforms[-1] = arrange_transform(mode='test')
  105. else:
  106. eval_transforms.transforms.append(arrange_transform(mode='test'))
  107. def raw_predict(self, preprocessed_input):
  108. self.count_num += 1
  109. feed_dict = {}
  110. if self.model_name == "YOLOv3":
  111. inputs = self.net.inputs
  112. for name in inputs:
  113. if(len(inputs[name].shape) == 2):
  114. feed_dict[name] = preprocessed_input['im_size']
  115. elif(len(inputs[name].shape) == 4):
  116. feed_dict[name] = preprocessed_input['image']
  117. else:
  118. pass
  119. else:
  120. input_blob = next(iter(self.net.inputs))
  121. feed_dict[input_blob] = preprocessed_input['image']
  122. #Start sync inference
  123. logging.info("Starting inference in synchronous mode")
  124. res = self.predictor.infer(inputs=feed_dict)
  125. #Processing output blob
  126. logging.info("Processing output blob")
  127. return res
  128. def preprocess(self, image):
  129. res = dict()
  130. if self.model_type == "classifier":
  131. im, = self.transforms(image)
  132. im = np.expand_dims(im, axis=0).copy()
  133. res['image'] = im
  134. elif self.model_type == "detector":
  135. if self.model_name == "YOLOv3":
  136. im, im_shape = self.transforms(image)
  137. im = np.expand_dims(im, axis=0).copy()
  138. im_shape = np.expand_dims(im_shape, axis=0).copy()
  139. res['image'] = im
  140. res['im_size'] = im_shape
  141. if self.model_name.count('RCNN') > 0:
  142. im, im_resize_info, im_shape = self.transforms(image)
  143. im = np.expand_dims(im, axis=0).copy()
  144. im_resize_info = np.expand_dims(im_resize_info, axis=0).copy()
  145. im_shape = np.expand_dims(im_shape, axis=0).copy()
  146. res['image'] = im
  147. res['im_info'] = im_resize_info
  148. res['im_shape'] = im_shape
  149. elif self.model_type == "segmenter":
  150. im, im_info = self.transforms(image)
  151. im = np.expand_dims(im, axis=0).copy()
  152. #np.savetxt('./input_data.txt',im.flatten())
  153. res['image'] = im
  154. res['im_info'] = im_info
  155. return res
  156. def classifier_postprocess(self, preds, topk=1):
  157. """ 对分类模型的预测结果做后处理
  158. """
  159. true_topk = min(self.num_classes, topk)
  160. output_name = next(iter(self.net.outputs))
  161. pred_label = np.argsort(-preds[output_name][0])[:true_topk]
  162. result = [{
  163. 'category_id': l,
  164. 'category': self.labels[l],
  165. 'score': preds[output_name][0][l],
  166. } for l in pred_label]
  167. print(result)
  168. return result
  169. def segmenter_postprocess(self, preds, preprocessed_inputs):
  170. """ 对语义分割结果做后处理
  171. """
  172. it = iter(self.net.outputs)
  173. next(it)
  174. score_name = next(it)
  175. #np.savetxt('./score_map.txt',preds[score_name].flatten())
  176. score_map = np.squeeze(preds[score_name])
  177. score_map = np.transpose(score_map, (1, 2, 0))
  178. label_name = next(it)
  179. #np.savetxt('./label_map.txt',preds[label_name].flatten())
  180. label_map = np.squeeze(preds[label_name]).astype('uint8')
  181. im_info = preprocessed_inputs['im_info']
  182. for info in im_info[::-1]:
  183. if info[0] == 'resize':
  184. w, h = info[1][1], info[1][0]
  185. label_map = cv2.resize(label_map, (w, h), cv2.INTER_NEAREST)
  186. score_map = cv2.resize(score_map, (w, h), cv2.INTER_LINEAR)
  187. elif info[0] == 'padding':
  188. w, h = info[1][1], info[1][0]
  189. label_map = label_map[0:h, 0:w]
  190. score_map = score_map[0:h, 0:w, :]
  191. else:
  192. raise Exception("Unexpected info '{}' in im_info".format(info[
  193. 0]))
  194. return {'label_map': label_map, 'score_map': score_map}
  195. def detector_postprocess(self, preds, preprocessed_inputs):
  196. """对图像检测结果做后处理
  197. """
  198. output_name = next(iter(self.net.outputs))
  199. outputs = preds[output_name][0]
  200. result = []
  201. for out in outputs:
  202. if(out[0] > 0):
  203. result.append(out.tolist())
  204. else:
  205. pass
  206. print(result)
  207. return result
  208. def predict(self, image, topk=1, threshold=0.5):
  209. preprocessed_input = self.preprocess(image)
  210. model_pred = self.raw_predict(preprocessed_input)
  211. if self.model_type == "classifier":
  212. results = self.classifier_postprocess(model_pred, topk)
  213. elif self.model_type == "detector":
  214. results = self.detector_postprocess(model_pred, preprocessed_input)
  215. elif self.model_type == "segmenter":
  216. results = self.segmenter_postprocess(model_pred,
  217. preprocessed_input)