coco_evaluator.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. import json
  2. import tempfile
  3. import torch
  4. from pycocotools.cocoeval import COCOeval
  5. from dataset.coco import COCODataset
  6. from utils.box_ops import rescale_bboxes
  7. class COCOAPIEvaluator():
  8. def __init__(self, cfg, data_dir, device, transform=None):
  9. # ----------------- Basic parameters -----------------
  10. self.image_set = 'val2017'
  11. self.transform = transform
  12. self.device = device
  13. # ----------------- Metrics -----------------
  14. self.map = 0.
  15. self.ap50_95 = 0.
  16. self.ap50 = 0.
  17. # ----------------- Dataset -----------------
  18. self.dataset = COCODataset(cfg=cfg, data_dir=data_dir, image_set=self.image_set, transform=None, is_train=False)
  19. @torch.no_grad()
  20. def evaluate(self, model):
  21. model.eval()
  22. ids = []
  23. data_dict = []
  24. num_images = len(self.dataset)
  25. print('total number of images: %d' % (num_images))
  26. # --------------- COCO evaluation ---------------
  27. for index in range(num_images):
  28. if index % 500 == 0:
  29. print('[Eval: %d / %d]'%(index, num_images))
  30. # ----------- Load an image -----------
  31. img, img_id = self.dataset.pull_image(index)
  32. orig_h, orig_w, _ = img.shape
  33. orig_size = [orig_w, orig_h]
  34. # ----------- Data preprocess -----------
  35. x, _, ratio = self.transform(img)
  36. x = x.unsqueeze(0).to(self.device)
  37. img_id = int(img_id)
  38. ids.append(img_id)
  39. # ----------- Model inference -----------
  40. outputs = model(x)
  41. scores = outputs['scores']
  42. labels = outputs['labels']
  43. bboxes = outputs['bboxes']
  44. # ----------- Rescale bboxes -----------
  45. bboxes = rescale_bboxes(bboxes, orig_size, ratio)
  46. # ----------- Process results -----------
  47. for i, box in enumerate(bboxes):
  48. x1 = float(box[0])
  49. y1 = float(box[1])
  50. x2 = float(box[2])
  51. y2 = float(box[3])
  52. label = self.dataset.class_ids[int(labels[i])]
  53. # COCO box format: x1, y1, bw, bh
  54. bbox = [x1, y1, x2 - x1, y2 - y1]
  55. score = float(scores[i])
  56. # COCO json format
  57. A = {"image_id": img_id,
  58. "category_id": label,
  59. "bbox": bbox,
  60. "score": score}
  61. data_dict.append(A)
  62. annType = ['segm', 'bbox', 'keypoints']
  63. # ------------- COCO Box detection evaluation -------------
  64. if len(data_dict) > 0:
  65. print('evaluating ......')
  66. cocoGt = self.dataset.coco
  67. _, tmp = tempfile.mkstemp()
  68. json.dump(data_dict, open(tmp, 'w'))
  69. cocoDt = cocoGt.loadRes(tmp)
  70. cocoEval = COCOeval(self.dataset.coco, cocoDt, annType[1])
  71. cocoEval.params.imgIds = ids
  72. cocoEval.evaluate()
  73. cocoEval.accumulate()
  74. cocoEval.summarize()
  75. ap50_95, ap50 = cocoEval.stats[0], cocoEval.stats[1]
  76. print('ap50_95 : ', ap50_95)
  77. print('ap50 : ', ap50)
  78. self.map = ap50_95
  79. self.ap50_95 = ap50_95
  80. self.ap50 = ap50
  81. return ap50, ap50_95
  82. else:
  83. return 0, 0