You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

util.py 8.3 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. # Copyright 2020 Huawei Technologies Co., Ltd
  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. # ============================================================================
  15. """coco eval for fasterrcnn"""
  16. import json
  17. import numpy as np
  18. from pycocotools.coco import COCO
  19. from pycocotools.cocoeval import COCOeval
  20. import mmcv
  21. _init_value = np.array(0.0)
  22. summary_init = {
  23. 'Precision/mAP': _init_value,
  24. 'Precision/mAP@.50IOU': _init_value,
  25. 'Precision/mAP@.75IOU': _init_value,
  26. 'Precision/mAP (small)': _init_value,
  27. 'Precision/mAP (medium)': _init_value,
  28. 'Precision/mAP (large)': _init_value,
  29. 'Recall/AR@1': _init_value,
  30. 'Recall/AR@10': _init_value,
  31. 'Recall/AR@100': _init_value,
  32. 'Recall/AR@100 (small)': _init_value,
  33. 'Recall/AR@100 (medium)': _init_value,
  34. 'Recall/AR@100 (large)': _init_value,
  35. }
  36. def coco_eval(result_files, result_types, coco, max_dets=(100, 300, 1000), single_result=False):
  37. """coco eval for fasterrcnn"""
  38. anns = json.load(open(result_files['bbox']))
  39. if not anns:
  40. return summary_init
  41. if mmcv.is_str(coco):
  42. coco = COCO(coco)
  43. assert isinstance(coco, COCO)
  44. for res_type in result_types:
  45. result_file = result_files[res_type]
  46. assert result_file.endswith('.json')
  47. coco_dets = coco.loadRes(result_file)
  48. gt_img_ids = coco.getImgIds()
  49. det_img_ids = coco_dets.getImgIds()
  50. iou_type = 'bbox' if res_type == 'proposal' else res_type
  51. cocoEval = COCOeval(coco, coco_dets, iou_type)
  52. if res_type == 'proposal':
  53. cocoEval.params.useCats = 0
  54. cocoEval.params.maxDets = list(max_dets)
  55. tgt_ids = gt_img_ids if not single_result else det_img_ids
  56. if single_result:
  57. res_dict = dict()
  58. for id_i in tgt_ids:
  59. cocoEval = COCOeval(coco, coco_dets, iou_type)
  60. if res_type == 'proposal':
  61. cocoEval.params.useCats = 0
  62. cocoEval.params.maxDets = list(max_dets)
  63. cocoEval.params.imgIds = [id_i]
  64. cocoEval.evaluate()
  65. cocoEval.accumulate()
  66. cocoEval.summarize()
  67. res_dict.update({coco.imgs[id_i]['file_name']: cocoEval.stats[1]})
  68. cocoEval = COCOeval(coco, coco_dets, iou_type)
  69. if res_type == 'proposal':
  70. cocoEval.params.useCats = 0
  71. cocoEval.params.maxDets = list(max_dets)
  72. cocoEval.params.imgIds = tgt_ids
  73. cocoEval.evaluate()
  74. cocoEval.accumulate()
  75. cocoEval.summarize()
  76. summary_metrics = {
  77. 'Precision/mAP': cocoEval.stats[0],
  78. 'Precision/mAP@.50IOU': cocoEval.stats[1],
  79. 'Precision/mAP@.75IOU': cocoEval.stats[2],
  80. 'Precision/mAP (small)': cocoEval.stats[3],
  81. 'Precision/mAP (medium)': cocoEval.stats[4],
  82. 'Precision/mAP (large)': cocoEval.stats[5],
  83. 'Recall/AR@1': cocoEval.stats[6],
  84. 'Recall/AR@10': cocoEval.stats[7],
  85. 'Recall/AR@100': cocoEval.stats[8],
  86. 'Recall/AR@100 (small)': cocoEval.stats[9],
  87. 'Recall/AR@100 (medium)': cocoEval.stats[10],
  88. 'Recall/AR@100 (large)': cocoEval.stats[11],
  89. }
  90. return summary_metrics
  91. def xyxy2xywh(bbox):
  92. _bbox = bbox.tolist()
  93. return [
  94. _bbox[0],
  95. _bbox[1],
  96. _bbox[2] - _bbox[0] + 1,
  97. _bbox[3] - _bbox[1] + 1,
  98. ]
  99. def bbox2result_1image(bboxes, labels, num_classes):
  100. """Convert detection results to a list of numpy arrays.
  101. Args:
  102. bboxes (Tensor): shape (n, 5)
  103. labels (Tensor): shape (n, )
  104. num_classes (int): class number, including background class
  105. Returns:
  106. list(ndarray): bbox results of each class
  107. """
  108. if bboxes.shape[0] == 0:
  109. result = [np.zeros((0, 5), dtype=np.float32) for i in range(num_classes - 1)]
  110. else:
  111. result = [bboxes[labels == i, :] for i in range(num_classes - 1)]
  112. return result
  113. def proposal2json(dataset, results):
  114. """convert proposal to json mode"""
  115. img_ids = dataset.getImgIds()
  116. json_results = []
  117. dataset_len = dataset.get_dataset_size()*2
  118. for idx in range(dataset_len):
  119. img_id = img_ids[idx]
  120. bboxes = results[idx]
  121. for i in range(bboxes.shape[0]):
  122. data = dict()
  123. data['image_id'] = img_id
  124. data['bbox'] = xyxy2xywh(bboxes[i])
  125. data['score'] = float(bboxes[i][4])
  126. data['category_id'] = 1
  127. json_results.append(data)
  128. return json_results
  129. def det2json(dataset, results):
  130. """convert det to json mode"""
  131. cat_ids = dataset.getCatIds()
  132. img_ids = dataset.getImgIds()
  133. json_results = []
  134. dataset_len = len(img_ids)
  135. for idx in range(dataset_len):
  136. img_id = img_ids[idx]
  137. if idx == len(results): break
  138. result = results[idx]
  139. for label, result_label in enumerate(result):
  140. bboxes = result_label
  141. for i in range(bboxes.shape[0]):
  142. data = dict()
  143. data['image_id'] = img_id
  144. data['bbox'] = xyxy2xywh(bboxes[i])
  145. data['score'] = float(bboxes[i][4])
  146. data['category_id'] = cat_ids[label]
  147. json_results.append(data)
  148. return json_results
  149. def segm2json(dataset, results):
  150. """convert segm to json mode"""
  151. bbox_json_results = []
  152. segm_json_results = []
  153. for idx in range(len(dataset)):
  154. img_id = dataset.img_ids[idx]
  155. det, seg = results[idx]
  156. for label, det_label in enumerate(det):
  157. # bbox results
  158. bboxes = det_label
  159. for i in range(bboxes.shape[0]):
  160. data = dict()
  161. data['image_id'] = img_id
  162. data['bbox'] = xyxy2xywh(bboxes[i])
  163. data['score'] = float(bboxes[i][4])
  164. data['category_id'] = dataset.cat_ids[label]
  165. bbox_json_results.append(data)
  166. if len(seg) == 2:
  167. segms = seg[0][label]
  168. mask_score = seg[1][label]
  169. else:
  170. segms = seg[label]
  171. mask_score = [bbox[4] for bbox in bboxes]
  172. for i in range(bboxes.shape[0]):
  173. data = dict()
  174. data['image_id'] = img_id
  175. data['score'] = float(mask_score[i])
  176. data['category_id'] = dataset.cat_ids[label]
  177. segms[i]['counts'] = segms[i]['counts'].decode()
  178. data['segmentation'] = segms[i]
  179. segm_json_results.append(data)
  180. return bbox_json_results, segm_json_results
  181. def results2json(dataset, results, out_file):
  182. """convert result convert to json mode"""
  183. result_files = dict()
  184. if isinstance(results[0], list):
  185. json_results = det2json(dataset, results)
  186. result_files['bbox'] = '{}.{}.json'.format(out_file, 'bbox')
  187. result_files['proposal'] = '{}.{}.json'.format(out_file, 'bbox')
  188. mmcv.dump(json_results, result_files['bbox'])
  189. elif isinstance(results[0], tuple):
  190. json_results = segm2json(dataset, results)
  191. result_files['bbox'] = '{}.{}.json'.format(out_file, 'bbox')
  192. result_files['proposal'] = '{}.{}.json'.format(out_file, 'bbox')
  193. result_files['segm'] = '{}.{}.json'.format(out_file, 'segm')
  194. mmcv.dump(json_results[0], result_files['bbox'])
  195. mmcv.dump(json_results[1], result_files['segm'])
  196. elif isinstance(results[0], np.ndarray):
  197. json_results = proposal2json(dataset, results)
  198. result_files['proposal'] = '{}.{}.json'.format(out_file, 'proposal')
  199. mmcv.dump(json_results, result_files['proposal'])
  200. else:
  201. raise TypeError('invalid type of results')
  202. return result_files