rawalkhirodkar's picture
Add initial commit
28c256d
# Copyright (c) Meta Platforms, Inc. and affiliates.
# All rights reserved.
#
# This source code is licensed under the license found in the
# LICENSE file in the root directory of this source tree.
import argparse
from mmengine.fileio import dump, load
from mmengine.logging import print_log
from mmengine.utils import ProgressBar
from pycocotools.coco import COCO
from pycocotools.cocoeval import COCOeval
from mmdet.models.utils import weighted_boxes_fusion
def parse_args():
parser = argparse.ArgumentParser(description='Fusion image \
prediction results using Weighted \
Boxes Fusion from multiple models.')
parser.add_argument(
'pred-results',
type=str,
nargs='+',
help='files of prediction results \
from multiple models, json format.')
parser.add_argument('--annotation', type=str, help='annotation file path')
parser.add_argument(
'--weights',
type=float,
nargs='*',
default=None,
help='weights for each model, '
'remember to correspond to the above prediction path.')
parser.add_argument(
'--fusion-iou-thr',
type=float,
default=0.55,
help='IoU value for boxes to be a match in wbf.')
parser.add_argument(
'--skip-box-thr',
type=float,
default=0.0,
help='exclude boxes with score lower than this variable in wbf.')
parser.add_argument(
'--conf-type',
type=str,
default='avg',
help='how to calculate confidence in weighted boxes in wbf.')
parser.add_argument(
'--eval-single',
action='store_true',
help='whether evaluate each single model result.')
parser.add_argument(
'--save-fusion-results',
action='store_true',
help='whether save fusion result')
parser.add_argument(
'--out-dir',
type=str,
default='outputs',
help='Output directory of images or prediction results.')
args = parser.parse_args()
return args
def main():
args = parse_args()
assert len(args.models_name) == len(args.pred_results), \
'the quantities of model names and prediction results are not equal'
cocoGT = COCO(args.annotation)
predicts_raw = []
models_name = ['model_' + str(i) for i in range(len(args.pred_results))]
for model_name, path in \
zip(models_name, args.pred_results):
pred = load(path)
predicts_raw.append(pred)
if args.eval_single:
print_log(f'Evaluate {model_name}...')
cocoDt = cocoGT.loadRes(pred)
coco_eval = COCOeval(cocoGT, cocoDt, iouType='bbox')
coco_eval.evaluate()
coco_eval.accumulate()
coco_eval.summarize()
predict = {
str(image_id): {
'bboxes_list': [[] for _ in range(len(predicts_raw))],
'scores_list': [[] for _ in range(len(predicts_raw))],
'labels_list': [[] for _ in range(len(predicts_raw))]
}
for image_id in cocoGT.getImgIds()
}
for i, pred_single in enumerate(predicts_raw):
for pred in pred_single:
p = predict[str(pred['image_id'])]
p['bboxes_list'][i].append(pred['bbox'])
p['scores_list'][i].append(pred['score'])
p['labels_list'][i].append(pred['category_id'])
result = []
prog_bar = ProgressBar(len(predict))
for image_id, res in predict.items():
bboxes, scores, labels = weighted_boxes_fusion(
res['bboxes_list'],
res['scores_list'],
res['labels_list'],
weights=args.weights,
iou_thr=args.fusion_iou_thr,
skip_box_thr=args.skip_box_thr,
conf_type=args.conf_type)
for bbox, score, label in zip(bboxes, scores, labels):
result.append({
'bbox': bbox.numpy().tolist(),
'category_id': int(label),
'image_id': int(image_id),
'score': float(score)
})
prog_bar.update()
if args.save_fusion_results:
out_file = args.out_dir + '/fusion_results.json'
dump(result, file=out_file)
print_log(
f'Fusion results have been saved to {out_file}.', logger='current')
print_log('Evaluate fusion results using wbf...')
cocoDt = cocoGT.loadRes(result)
coco_eval = COCOeval(cocoGT, cocoDt, iouType='bbox')
coco_eval.evaluate()
coco_eval.accumulate()
coco_eval.summarize()
if __name__ == '__main__':
main()