#!/usr/bin/env python """Generate a labeled sample gallery of every augmentation effect in isolation. For each of the 25 configurable augmentation families, forces that one effect on (probability=1.0) and disables every other effect, so the visual result is attributable to that effect alone. Placement is frozen (no rotation/scale/ misplacement jitter, fixed template) so samples across effects are directly comparable. Writes 5 sample images per effect to degradation//, each a multi-panel figure (full page, signature crop, ink mask, coverage metrics, difficulty breakdown) via the existing visualizer. Usage: python scripts/generate_degradation_gallery.py """ from __future__ import annotations import sys from pathlib import Path sys.path.insert(0, str(Path(__file__).resolve().parents[1])) from src.config.loader import load_config from src.generator import GeneratorContext from src.visualization.visualizer import save_visualization SIGNATURE_EFFECTS = [ "rotation", "stroke_dilation", "ink_fading", "ink_bleed", "motion_blur", "gaussian_blur", ] DOCUMENT_EFFECTS = [ "perspective", "contrast", "gamma", "coffee_stain", "stain", "shadow", "crumple", "discoloration", "page_tilt", "dust", "scanner_streaks", "scanner_noise", "salt_pepper", "jpeg_compression", ] ALL_EFFECTS = SIGNATURE_EFFECTS + DOCUMENT_EFFECTS OUT_ROOT = Path(__file__).resolve().parents[1] / "degradation" SAMPLES_PER_EFFECT = 5 TEMPLATE_ID = "bank_doc_05" # decent-sized signature box (255x35px) FORCED_STRENGTH = 0.75 def build_overrides(target_effect: str) -> list[str]: overrides = [ f"document.template={TEMPLATE_ID}", "placement.rotation_deg.min=0", "placement.rotation_deg.max=0", "placement.scale_factor.min=0.85", "placement.scale_factor.max=0.85", "placement.x_offset=0", "placement.y_offset=0", "placement.misplacement_probability=0.0", "generation.run_validation=false", ] for name in ALL_EFFECTS: is_target = name == target_effect overrides.append(f"augmentation.{name}.enabled={'true' if is_target else 'false'}") overrides.append(f"augmentation.{name}.probability={'1.0' if is_target else '0.0'}") overrides.append(f"augmentation.{target_effect}.strength={FORCED_STRENGTH}") return overrides def main() -> None: OUT_ROOT.mkdir(parents=True, exist_ok=True) for effect in ALL_EFFECTS: out_dir = OUT_ROOT / effect out_dir.mkdir(parents=True, exist_ok=True) config = load_config(overrides=build_overrides(effect)) ctx = GeneratorContext(config) for i in range(1, SAMPLES_PER_EFFECT + 1): metadata, final_image, _ = ctx.run_sample(i) save_visualization(out_dir / f"sample_{i}.png", final_image, metadata) print(f"[{effect}] wrote {SAMPLES_PER_EFFECT} samples -> {out_dir}") if __name__ == "__main__": main()