coco_metrics.py 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. # Copyright (c) 2024 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. from __future__ import absolute_import, division, print_function
  15. import copy
  16. import sys
  17. from collections import OrderedDict
  18. from .coco_utils import cocoapi_eval, get_infer_results
  19. class COCOMetric(object):
  20. def __init__(self, coco_gt, **kwargs):
  21. self.clsid2catid = {
  22. i: cat["id"] for i, cat in enumerate(coco_gt.loadCats(coco_gt.getCatIds()))
  23. }
  24. self.coco_gt = coco_gt
  25. self.classwise = kwargs.get("classwise", False)
  26. self.bias = 0
  27. self.reset()
  28. def reset(self):
  29. # only bbox and mask evaluation support currently
  30. self.details = {
  31. "gt": copy.deepcopy(self.coco_gt.dataset),
  32. "bbox": [],
  33. "mask": [],
  34. }
  35. self.eval_stats = {}
  36. def update(self, im_id, outputs):
  37. outs = {}
  38. # outputs Tensor -> numpy.ndarray
  39. for k, v in outputs.items():
  40. outs[k] = v
  41. outs["im_id"] = im_id
  42. infer_results = get_infer_results(outs, self.clsid2catid, bias=self.bias)
  43. self.details["bbox"] += infer_results["bbox"] if "bbox" in infer_results else []
  44. self.details["mask"] += infer_results["mask"] if "mask" in infer_results else []
  45. def accumulate(self):
  46. if len(self.details["bbox"]) > 0:
  47. bbox_stats = cocoapi_eval(
  48. copy.deepcopy(self.details["bbox"]),
  49. "bbox",
  50. coco_gt=self.coco_gt,
  51. classwise=self.classwise,
  52. )
  53. self.eval_stats["bbox"] = bbox_stats
  54. sys.stdout.flush()
  55. if len(self.details["mask"]) > 0:
  56. seg_stats = cocoapi_eval(
  57. copy.deepcopy(self.details["mask"]),
  58. "segm",
  59. coco_gt=self.coco_gt,
  60. classwise=self.classwise,
  61. )
  62. self.eval_stats["mask"] = seg_stats
  63. sys.stdout.flush()
  64. def log(self):
  65. pass
  66. def get(self):
  67. if "bbox" not in self.eval_stats:
  68. return {"bbox_mmap": 0.0}
  69. if "mask" in self.eval_stats:
  70. return OrderedDict(
  71. zip(
  72. ["bbox_mmap", "segm_mmap"],
  73. [self.eval_stats["bbox"][0], self.eval_stats["mask"][0]],
  74. )
  75. )
  76. else:
  77. return {"bbox_mmap": self.eval_stats["bbox"][0]}