File size: 1,924 Bytes
7ea1851 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | #!/usr/bin/env python3
"""Run the conservative lower-third person bootstrap pass."""
from __future__ import annotations
import argparse
import json
import os
import sys
REPO_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
BACKEND_ROOT = os.path.join(REPO_ROOT, "backend")
sys.path.insert(0, BACKEND_ROOT)
from face_search import get_face_search_instance
from lower_third_person_bootstrap import DEFAULT_MIN_SCORE, bootstrap_lower_third_people
from media_metadata import get_all_media
from runtime_paths import get_image_db_path
def parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--apply", action="store_true", help="Create/link people instead of dry-running")
parser.add_argument("--language", default="E", help="JW language code")
parser.add_argument("--limit", type=int, default=100, help="Maximum candidates to inspect")
parser.add_argument("--min-score", type=float, default=DEFAULT_MIN_SCORE, help="Lower-third label score floor")
parser.add_argument("--ocr", action="store_true", help="Use RapidOCR when the title does not name a person")
parser.add_argument(
"--resolve-conflicts",
action="store_true",
help="Allow high-confidence lower-third evidence to replace an existing face assignment",
)
return parser.parse_args()
def main() -> int:
args = parse_args()
summary = bootstrap_lower_third_people(
image_db_path=get_image_db_path(),
face_search=get_face_search_instance(),
media_items=get_all_media(args.language),
min_score=args.min_score,
limit=args.limit,
dry_run=not args.apply,
use_ocr=args.ocr,
resolve_conflicts=args.resolve_conflicts,
)
print(json.dumps(summary.to_dict(), indent=2, ensure_ascii=False))
return 0
if __name__ == "__main__":
raise SystemExit(main())
|