| |
| import argparse |
| import json |
| import os |
| from collections import defaultdict |
|
|
| from iopath.common.file_io import g_pathmgr |
| from sam3.eval.saco_veval_evaluators import ( |
| VideoCGF1Evaluator, |
| VideoPhraseApEvaluator, |
| VideoPhraseHotaEvaluator, |
| VideoTetaEvaluator, |
| YTVISPredFileEvaluator, |
| ) |
|
|
|
|
| class VEvalEvaluator: |
| def __init__(self, gt_annot_file: str, eval_res_file: str): |
| self.gt_annot_file = gt_annot_file |
| self.eval_res_file = eval_res_file |
| self.evaluators = [ |
| |
| YTVISPredFileEvaluator(gt_annot_file), |
| |
| VideoPhraseApEvaluator(gt_annot_file), |
| |
| VideoTetaEvaluator(gt_annot_file, use_mask=True, is_exhaustive=True), |
| |
| VideoPhraseHotaEvaluator(gt_annot_file), |
| |
| VideoCGF1Evaluator(gt_annot_file), |
| ] |
|
|
| def run_eval(self, pred_file: str): |
| dataset_results = {} |
| video_np_results = defaultdict(dict) |
| for evaluator in self.evaluators: |
| d_res, v_np_res = evaluator.evaluate(pred_file) |
| dataset_results.update(d_res) |
| for (video_id, category_id), res in v_np_res.items(): |
| video_np_results[(video_id, category_id)].update(res) |
|
|
| if len(dataset_results) == 0: |
| dataset_results = {"": 0.0} |
|
|
| formatted_video_np_results = [ |
| {"video_id": video_id, "category_id": category_id, **res} |
| for (video_id, category_id), res in video_np_results.items() |
| ] |
| eval_metrics = { |
| "dataset_results": dataset_results, |
| "video_np_results": formatted_video_np_results, |
| } |
|
|
| with g_pathmgr.open(self.eval_res_file, "w") as f: |
| json.dump(eval_metrics, f) |
|
|
| return eval_metrics |
|
|
|
|
| def run_main_all(dataset_name, args): |
| gt_annot_file = os.path.join(args.gt_annot_dir, dataset_name + ".json") |
| pred_file = os.path.join(args.pred_dir, dataset_name + "_preds.json") |
| eval_res_file = os.path.join(args.eval_res_dir, dataset_name + "_eval_res.json") |
| print(f"=== Running evaluation for Pred {pred_file} vs GT {gt_annot_file} ===") |
| veval_evaluator = VEvalEvaluator( |
| gt_annot_file=gt_annot_file, eval_res_file=eval_res_file |
| ) |
| _ = veval_evaluator.run_eval(pred_file=pred_file) |
|
|
| print(f"=== Results saved to {eval_res_file} ===") |
|
|
|
|
| def main_all(args): |
| saco_veval_dataset_names = [ |
| "saco_veval_sav_test", |
| "saco_veval_sav_val", |
| "saco_veval_yt1b_test", |
| "saco_veval_yt1b_val", |
| "saco_veval_smartglasses_test", |
| "saco_veval_smartglasses_val", |
| ] |
|
|
| |
| |
| for dataset_name in saco_veval_dataset_names: |
| print(f"=== Running evaluation for dataset {dataset_name} ===") |
| run_main_all(dataset_name=dataset_name, args=args) |
|
|
|
|
| def main_one(args): |
| gt_annot_file = args.gt_annot_file |
| pred_file = args.pred_file |
| eval_res_file = args.eval_res_file |
|
|
| print(f"=== Running evaluation for Pred {pred_file} vs GT {gt_annot_file} ===") |
| veval_evaluator = VEvalEvaluator( |
| gt_annot_file=gt_annot_file, eval_res_file=eval_res_file |
| ) |
| _ = veval_evaluator.run_eval(pred_file=pred_file) |
|
|
| print(f"=== Results saved to {eval_res_file} ===") |
|
|
|
|
| def main(): |
| parser = argparse.ArgumentParser(description="Run video grounding evaluators") |
|
|
| |
| subparsers = parser.add_subparsers(dest="command", required=True) |
|
|
| |
| all_parser = subparsers.add_parser("all", help="Run evaluation for all datasets") |
| all_parser.add_argument( |
| "--gt_annot_dir", |
| type=str, |
| help="Directory that contains the ground truth annotation files", |
| ) |
| all_parser.add_argument( |
| "--pred_dir", |
| type=str, |
| help="Directory that contains the prediction files", |
| ) |
| all_parser.add_argument( |
| "--eval_res_dir", |
| type=str, |
| help="Directory that contains the eval results files", |
| ) |
| all_parser.set_defaults(func=main_all) |
|
|
| |
| one_parser = subparsers.add_parser("one", help="Run evaluation for one dataset") |
| one_parser.add_argument( |
| "--gt_annot_file", |
| type=str, |
| help="Path to the ground truth annotation file", |
| ) |
| one_parser.add_argument( |
| "--pred_file", |
| type=str, |
| help="Path to the prediction file", |
| ) |
| one_parser.add_argument( |
| "--eval_res_file", |
| type=str, |
| help="Path to the eval results file", |
| ) |
| one_parser.set_defaults(func=main_one) |
|
|
| |
| args = parser.parse_args() |
| args.func(args) |
|
|
|
|
| if __name__ == "__main__": |
| main() |
|
|