Skip to content

Commit 100db93

Browse files
authored
[benchmark] Allow running all benchmarks (#491)
Add --all flag to run all detector/dataset combinations. Add and require --detailed flag to output information for each video. Add extra separators in detailed mode to help more easily see the overall result versus each individual video.
1 parent f196a31 commit 100db93

File tree

2 files changed

+81
-30
lines changed

2 files changed

+81
-30
lines changed

benchmark/README.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,17 @@ rm AutoShot.tar.gz
2626
## Evaluation
2727
To evaluate PySceneDetect on a dataset, run the following command from the root of the repo:
2828
```
29-
python -m benchmark -d <dataset_name> --detector <detector_name>
29+
python -m benchmark --dataset <dataset_name> --detector <detector_name>
3030
```
3131
For example, to evaluate ContentDetector on the BBC dataset:
3232
```
33-
python -m benchmark -d BBC --detector detect-content
33+
python -m benchmark --dataset BBC --detector detect-content
3434
```
35+
To run all detectors on all datasets:
36+
```
37+
python -m benchmark --all
38+
```
39+
The `--all` flag can also be combined with `--dataset` or `--detector`.
3540

3641
### Result
3742
The performance is computed as recall, precision, f1, and elapsed time.

benchmark/__main__.py

Lines changed: 74 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import argparse
22
import time
33
import os
4+
import typing as ty
45

56
from tqdm import tqdm
67

@@ -16,37 +17,33 @@
1617
detect,
1718
)
1819

19-
20-
def _make_detector(detector_name: str):
21-
if detector_name == "detect-adaptive":
22-
return AdaptiveDetector()
23-
if detector_name == "detect-content":
24-
return ContentDetector()
25-
if detector_name == "detect-hash":
26-
return HashDetector()
27-
if detector_name == "detect-hist":
28-
return HistogramDetector()
29-
if detector_name == "detect-threshold":
30-
return ThresholdDetector()
31-
raise RuntimeError(f"Unknown detector: {detector_name}")
20+
_DETECTORS = {
21+
"detect-adaptive": AdaptiveDetector,
22+
"detect-content": ContentDetector,
23+
"detect-hash": HashDetector,
24+
"detect-hist": HistogramDetector,
25+
"detect-threshold": ThresholdDetector,
26+
}
3227

3328

3429
_DATASETS = {
3530
"BBC": BBCDataset("benchmark/BBC"),
3631
"AutoShot": AutoShotDataset("benchmark/AutoShot"),
3732
}
3833

34+
_DEFAULT_DETECTOR = "detect-content"
35+
_DEFAULT_DATASET = "BBC"
36+
3937
_RESULT_PRINT_FORMAT = (
4038
"Recall: {recall:.2f}, Precision: {precision:.2f}, F1: {f1:.2f} Elapsed time: {elapsed:.2f}\n"
4139
)
4240

4341

44-
def _detect_scenes(detector_type: str, dataset):
42+
def _detect_scenes(detector: str, dataset: str, detailed: bool):
4543
pred_scenes = {}
46-
for video_file, scene_file in tqdm(dataset):
44+
for video_file, scene_file in tqdm(_DATASETS[dataset]):
4745
start = time.time()
48-
detector = _make_detector(detector_type)
49-
pred_scene_list = detect(video_file, detector)
46+
pred_scene_list = detect(video_file, _DETECTORS[detector]())
5047
elapsed = time.time() - start
5148
filename = os.path.basename(video_file)
5249
scenes = {
@@ -57,22 +54,28 @@ def _detect_scenes(detector_type: str, dataset):
5754
}
5855
}
5956
result = Evaluator().evaluate_performance(scenes)
60-
print(f"\n{filename} results:")
61-
print(_RESULT_PRINT_FORMAT.format(**result) + "\n")
57+
if detailed:
58+
print(f"\n{filename} results:")
59+
print(_RESULT_PRINT_FORMAT.format(**result) + "\n")
6260
pred_scenes.update(scenes)
6361

6462
return pred_scenes
6563

6664

67-
def main(args):
68-
print(f"Evaluating {args.detector} on dataset {args.dataset}...\n")
69-
pred_scenes = _detect_scenes(detector_type=args.detector, dataset=_DATASETS[args.dataset])
65+
def run_benchmark(detector: str, dataset: str, detailed: bool):
66+
print(f"Evaluating {detector} on dataset {dataset}...\n")
67+
pred_scenes = _detect_scenes(detector=detector, dataset=dataset, detailed=detailed)
7068
result = Evaluator().evaluate_performance(pred_scenes)
71-
print(f"\nOverall Results for {args.detector} on dataset {args.dataset}:")
69+
# Print extra separators in detailed output to identify overall results vs individual videos.
70+
if detailed:
71+
print("------------------------------------------------------------")
72+
print(f"\nOverall Results for {detector} on dataset {dataset}:")
7273
print(_RESULT_PRINT_FORMAT.format(**result))
74+
if detailed:
75+
print("------------------------------------------------------------")
7376

7477

75-
if __name__ == "__main__":
78+
def create_parser():
7679
parser = argparse.ArgumentParser(description="Benchmarking PySceneDetect performance.")
7780
parser.add_argument(
7881
"--dataset",
@@ -81,7 +84,6 @@ def main(args):
8184
"BBC",
8285
"AutoShot",
8386
],
84-
default="BBC",
8587
help="Dataset name. Supported datasets are BBC and AutoShot.",
8688
)
8789
parser.add_argument(
@@ -94,8 +96,52 @@ def main(args):
9496
"detect-hist",
9597
"detect-threshold",
9698
],
97-
default="detect-content",
98-
help="Detector name. Implemented detectors are listed: https://www.scenedetect.com/docs/latest/cli.html",
99+
help="Detector name. Implemented detectors are listed: "
100+
"https://www.scenedetect.com/docs/latest/cli.html",
101+
)
102+
parser.add_argument(
103+
"--detailed",
104+
action="store_const",
105+
const=True,
106+
help="Print results for each video, in addition to overall summary.",
107+
)
108+
parser.add_argument(
109+
"--all",
110+
action="store_const",
111+
const=True,
112+
help="Benchmark all detectors on all datasets. If --detector or --dataset are specified, "
113+
"will only run with those.",
99114
)
115+
return parser
116+
117+
118+
def run_all_benchmarks(detector: ty.Optional[str], dataset: ty.Optional[str], detailed: bool):
119+
detectors = {detector: _DETECTORS[detector]} if detector else _DETECTORS
120+
datasets = {dataset: _DATASETS[dataset]} if dataset else _DATASETS
121+
print(
122+
"Running benchmarks for:\n"
123+
f" - Detectors: {', '.join(detectors.keys())}\n"
124+
f" - Datasets: {', '.join(datasets.keys())}\n"
125+
)
126+
for detector in detectors:
127+
for dataset in datasets:
128+
run_benchmark(detector=detector, dataset=dataset, detailed=detailed)
129+
130+
131+
def main():
132+
parser = create_parser()
100133
args = parser.parse_args()
101-
main(args)
134+
if args.all:
135+
run_all_benchmarks(
136+
detector=args.detector, dataset=args.dataset, detailed=bool(args.detailed)
137+
)
138+
else:
139+
run_benchmark(
140+
detector=args.detector if args.detector else _DEFAULT_DETECTOR,
141+
dataset=args.dataset if args.dataset else _DEFAULT_DATASET,
142+
detailed=bool(args.detailed),
143+
)
144+
145+
146+
if __name__ == "__main__":
147+
main()

0 commit comments

Comments
 (0)