module.py 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. # Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved.
  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 os
  15. import time
  16. from functools import reduce
  17. import cv2
  18. import numpy as np
  19. from paddlehub.module.module import moduleinfo
  20. import solov2.processor as P
  21. import solov2.data_feed as D
  22. class Detector(object):
  23. """
  24. Args:
  25. model_dir (str): root path of __model__, __params__ and infer_cfg.yml
  26. use_gpu (bool): whether use gpu
  27. run_mode (str): mode of running(fluid/trt_fp32/trt_fp16)
  28. threshold (float): threshold to reserve the result for output.
  29. """
  30. def __init__(self,
  31. min_subgraph_size=60,
  32. use_gpu=False,
  33. run_mode='fluid',
  34. threshold=0.5):
  35. model_dir = os.path.join(self.directory, 'solov2_r101_vd_fpn_3x')
  36. self.predictor = D.load_predictor(
  37. model_dir,
  38. run_mode=run_mode,
  39. min_subgraph_size=min_subgraph_size,
  40. use_gpu=use_gpu)
  41. self.compose = [
  42. P.Resize(max_size=1333), P.Normalize(
  43. mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
  44. P.Permute(), P.PadStride(stride=32)
  45. ]
  46. def transform(self, im):
  47. im, im_info = P.preprocess(im, self.compose)
  48. inputs = D.create_inputs(im, im_info)
  49. return inputs, im_info
  50. def postprocess(self, np_boxes, np_masks, im_info, threshold=0.5):
  51. # postprocess output of predictor
  52. results = {}
  53. expect_boxes = (np_boxes[:, 1] > threshold) & (np_boxes[:, 0] > -1)
  54. np_boxes = np_boxes[expect_boxes, :]
  55. for box in np_boxes:
  56. print('class_id:{:d}, confidence:{:.4f},'
  57. 'left_top:[{:.2f},{:.2f}],'
  58. ' right_bottom:[{:.2f},{:.2f}]'.format(
  59. int(box[0]), box[1], box[2], box[3], box[4], box[5]))
  60. results['boxes'] = np_boxes
  61. if np_masks is not None:
  62. np_masks = np_masks[expect_boxes, :, :, :]
  63. results['masks'] = np_masks
  64. return results
  65. def predict(self, image, threshold=0.5, warmup=0, repeats=1):
  66. '''
  67. Args:
  68. image (str/np.ndarray): path of image/ np.ndarray read by cv2
  69. threshold (float): threshold of predicted box' score
  70. Returns:
  71. results (dict): include 'boxes': np.ndarray: shape:[N,6], N: number of box,
  72. matix element:[class, score, x_min, y_min, x_max, y_max]
  73. MaskRCNN's results include 'masks': np.ndarray:
  74. shape:[N, class_num, mask_resolution, mask_resolution]
  75. '''
  76. inputs, im_info = self.transform(image)
  77. np_boxes, np_masks = None, None
  78. input_names = self.predictor.get_input_names()
  79. for i in range(len(input_names)):
  80. input_tensor = self.predictor.get_input_tensor(input_names[i])
  81. input_tensor.copy_from_cpu(inputs[input_names[i]])
  82. for i in range(warmup):
  83. self.predictor.zero_copy_run()
  84. output_names = self.predictor.get_output_names()
  85. boxes_tensor = self.predictor.get_output_tensor(output_names[0])
  86. np_boxes = boxes_tensor.copy_to_cpu()
  87. for i in range(repeats):
  88. self.predictor.zero_copy_run()
  89. output_names = self.predictor.get_output_names()
  90. boxes_tensor = self.predictor.get_output_tensor(output_names[0])
  91. np_boxes = boxes_tensor.copy_to_cpu()
  92. # do not perform postprocess in benchmark mode
  93. results = []
  94. if reduce(lambda x, y: x * y, np_boxes.shape) < 6:
  95. print('[WARNNING] No object detected.')
  96. results = {'boxes': np.array([])}
  97. else:
  98. results = self.postprocess(
  99. np_boxes, np_masks, im_info, threshold=threshold)
  100. return results
  101. @moduleinfo(
  102. name="solov2",
  103. type="CV/image_editing",
  104. author="paddlepaddle",
  105. author_email="",
  106. summary="solov2 is a detection model, this module is trained with COCO dataset.",
  107. version="1.0.0")
  108. class DetectorSOLOv2(Detector):
  109. def __init__(self, use_gpu=False, run_mode='fluid', threshold=0.5):
  110. super(DetectorSOLOv2, self).__init__(
  111. use_gpu=use_gpu, run_mode=run_mode, threshold=threshold)
  112. def predict(self,
  113. image,
  114. threshold=0.5,
  115. warmup=0,
  116. repeats=1,
  117. visualization=False,
  118. save_dir='solov2_result'):
  119. inputs, im_info = self.transform(image)
  120. np_label, np_score, np_segms = None, None, None
  121. input_names = self.predictor.get_input_names()
  122. for i in range(len(input_names)):
  123. input_tensor = self.predictor.get_input_tensor(input_names[i])
  124. input_tensor.copy_from_cpu(inputs[input_names[i]])
  125. for i in range(warmup):
  126. self.predictor.zero_copy_run()
  127. output_names = self.predictor.get_output_names()
  128. np_label = self.predictor.get_output_tensor(output_names[
  129. 0]).copy_to_cpu()
  130. np_score = self.predictor.get_output_tensor(output_names[
  131. 1]).copy_to_cpu()
  132. np_segms = self.predictor.get_output_tensor(output_names[
  133. 2]).copy_to_cpu()
  134. for i in range(repeats):
  135. self.predictor.zero_copy_run()
  136. output_names = self.predictor.get_output_names()
  137. np_label = self.predictor.get_output_tensor(output_names[
  138. 0]).copy_to_cpu()
  139. np_score = self.predictor.get_output_tensor(output_names[
  140. 1]).copy_to_cpu()
  141. np_segms = self.predictor.get_output_tensor(output_names[
  142. 2]).copy_to_cpu()
  143. output = dict(segm=np_segms, label=np_label, score=np_score)
  144. if visualization:
  145. if not os.path.exists(save_dir):
  146. os.makedirs(save_dir)
  147. image = D.visualize_box_mask(im=image, results=output)
  148. name = str(time.time()) + '.png'
  149. save_path = os.path.join(save_dir, name)
  150. image.save(save_path)
  151. img = cv2.cvtColor(np.array(image), cv2.COLOR_RGB2BGR)
  152. output['image'] = img
  153. return output