diff --git a/README.md b/README.md index 37e0cfc..cab3986 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,7 @@ context leaks onto the wrong card: | `--edge-margin` | 0 | require faces this far inside frame edges; `0` accepts edge-touching faces (original hard-rejected them) | | `--scene-threshold` | 30.0 | PySceneDetect ContentDetector threshold (same as original) | | `--imgsz` | 1280 | inference size; model was trained at 1280, `640` is faster at some recall cost | +| `--all-files` | off | also scan OP/ED files. Off by default: music videos are full of stylized graphics (feather storms, transformation emblems) that false-positive as face-shaped; episodes carry the real character close-ups | | `--preview-dir` | off | also write annotated copies (green boxes) of every saved frame for eyeball QC | ## Notes diff --git a/anime_facesaver.py b/anime_facesaver.py index 9d483e5..23c4c74 100644 --- a/anime_facesaver.py +++ b/anime_facesaver.py @@ -132,6 +132,15 @@ def parse_arguments(): help="Inference image size. The model was trained at 1280; lower " "it (640) for speed at some recall cost.", ) + parser.add_argument( + "--all-files", + action="store_true", + help="Also scan OP/ED files (name matches 'opening'/'ending'). " + "Skipped by default: music-video files are dominated by " + "stylized graphics (feather storms, transformation " + "emblems) that false-positive face detectors; character " + "close-ups for training datasets come from episodes.", + ) parser.add_argument( "--preview-dir", default=None, @@ -367,11 +376,18 @@ def main(): video_extensions = ('.mp4', '.avi', '.mov', '.mkv') grand_total = 0 for filename in sorted(os.listdir(args.input_dir)): - if filename.lower().endswith(video_extensions): - video_path = os.path.join(args.input_dir, filename) - print(f"Processing video: {video_path}") - grand_total += process_video( - video_path, args.output_dir, args, model, device, draw) + if not filename.lower().endswith(video_extensions): + continue + if (not args.all_files + and any(k in filename.lower() + for k in ("opening", "ending", " op", " ed"))): + print(f"Skipping OP/ED file (use --all-files to include): " + f"{filename}") + continue + video_path = os.path.join(args.input_dir, filename) + print(f"Processing video: {video_path}") + grand_total += process_video( + video_path, args.output_dir, args, model, device, draw) print(f"Done. {grand_total} stills saved to {args.output_dir}")