#!/usr/bin/env python """Generate plain full-page images (no dashboard overlay) for normal vs. extreme multi-degradation cases, for slides. Reuses the same two configurations as scripts/generate_multiple_degradation_gallery.py ("normal": configs/generate.yaml's realistic per-effect probabilities, unmodified) and scripts/generate_multiple_degradation_extreme_gallery.py ("extreme": every effect pushed to high probability/strength plus worst-case placement/rendering), but writes the bare rendered page instead of the multi-panel debug figure, since slides just need the document image plus a short caption. Usage: python scripts/generate_case_assets.py """ from __future__ import annotations import json import sys from pathlib import Path sys.path.insert(0, str(Path(__file__).resolve().parents[1])) from PIL import Image from src.config.loader import load_config from src.generator import GeneratorContext from scripts.generate_multiple_degradation_extreme_gallery import build_overrides as extreme_overrides ROOT = Path(__file__).resolve().parents[1] TEMPLATE_ID = "bank_doc_05" N_SAMPLES = 2 def _run_case(out_dir: Path, config_path, overrides: list[str]) -> None: out_dir.mkdir(parents=True, exist_ok=True) config = load_config(config_path=config_path, overrides=overrides) ctx = GeneratorContext(config) manifest = {} for i in range(1, N_SAMPLES + 1): meta, final_image, _ = ctx.run_sample(i) Image.fromarray(final_image).save(out_dir / f"case_{i}.png") effects = meta["augmentation"]["effects"] applied = [n for n, r in effects.items() if r["applied"]] manifest[f"case_{i}"] = { "applied_effects": applied, "n_applied": len(applied), "n_total": len(effects), "difficulty_score": meta["difficulty"]["score"], "difficulty_tier": meta["difficulty"]["tier"], "placement": { "rotation_deg": meta["placement"]["rotation_deg"], "scale_factor": meta["placement"]["scale_factor"], "misplaced": meta["placement"]["misplaced"], }, } print(f"[{out_dir.parent.name}/case_{i}] {len(applied)}/{len(effects)} effects, " f"difficulty={meta['difficulty']['score']:.3f} ({meta['difficulty']['tier']})") (out_dir / "case_manifest.json").write_text(json.dumps(manifest, indent=2), encoding="utf-8") def main() -> None: # Normal: configs/generate.yaml's realistic "varied batch" probabilities, unmodified. _run_case( ROOT / "multiple_degradation" / "case_assets", ROOT / "configs" / "generate.yaml", [f"document.template={TEMPLATE_ID}", "generation.run_validation=false"], ) # Extreme: every effect pushed high, worst-case placement/rendering. _run_case( ROOT / "multiple_degradation_extreme" / "case_assets", None, extreme_overrides(), ) print("\nDone.") if __name__ == "__main__": main()