11import argparse
22import time
33import os
4+ import typing as ty
45
56from tqdm import tqdm
67
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"\n Overall 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"\n Overall 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