"""Central configuration for all models and pipeline settings.""" from dataclasses import dataclass, field from enum import Enum from pathlib import Path class Quality(str, Enum): FAST = "fast" BALANCED = "balanced" HIGH = "high" ULTRA = "ultra" class LineArtStyle(str, Enum): INFORMATIVE = "informative" ANYLINE = "anyline" MANGA = "manga" FUSED = "fused" # Merge multiple models AUTO = "auto" # Pick based on content class ContentType(str, Enum): PHOTO = "photo" ILLUSTRATION = "illustration" ANIME = "anime" PORTRAIT = "portrait" LANDSCAPE = "landscape" AUTO = "auto" class Difficulty(str, Enum): EASY = "easy" # 6-8 colors, large regions MEDIUM = "medium" # 10-14 colors HARD = "hard" # 16-22 colors, small regions EXPERT = "expert" # 24-30 colors, tiny regions AUTO = "auto" @dataclass class ModelPaths: informative_drawings: str = "models/informative_drawings.onnx" anyline: str = "models/anyline.onnx" manga_line: str = "models/manga_line.onnx" sam2_encoder: str = "models/sam2_encoder.onnx" sam2_decoder: str = "models/sam2_decoder.onnx" depth_anything: str = "models/depth_anything_v2.onnx" real_esrgan: str = "models/real_esrgan_x4.onnx" rmbg: str = "models/rmbg2.onnx" face_parsing: str = "models/face_parsing.onnx" def available(self, name: str) -> bool: path = getattr(self, name, None) return path is not None and Path(path).exists() @dataclass class PipelineConfig: # Content content_type: ContentType = ContentType.AUTO difficulty: Difficulty = Difficulty.AUTO quality: Quality = Quality.BALANCED # Colors k_colors: int | None = None # None = auto use_lab: bool = True spatial_weight: float = 0.0 # Line art line_style: LineArtStyle = LineArtStyle.FUSED line_threshold: int = 128 # Regions min_region_area: int = 200 use_sam: bool = True # Use SAM2 for segmentation # Enhancement upscale_if_small: bool = True remove_background: bool = False detect_faces: bool = True # Depth use_depth: bool = True depth_layers: int = 3 # Number of difficulty layers # Closing density: str = "auto" close_kernel: int = 3 close_iterations: int = 2 bridge_gaps: bool = True # System max_dimension: int = 1024 save_debug: bool = False debug_dir: str = "outputs/debug" def apply_difficulty(self): """Set parameters based on difficulty level.""" presets = { Difficulty.EASY: {"k": 8, "min_area": 500, "spatial": 0.4}, Difficulty.MEDIUM: {"k": 14, "min_area": 300, "spatial": 0.2}, Difficulty.HARD: {"k": 22, "min_area": 150, "spatial": 0.1}, Difficulty.EXPERT: {"k": 30, "min_area": 20, "spatial": 0.05}, } if self.difficulty in presets: p = presets[self.difficulty] if self.k_colors is None: self.k_colors = p["k"] self.min_region_area = p["min_area"] self.spatial_weight = p["spatial"] def apply_quality(self): """Set processing params based on quality level.""" if self.quality == Quality.FAST: self.use_sam = False self.use_depth = False self.bridge_gaps = False self.line_style = LineArtStyle.INFORMATIVE self.upscale_if_small = False elif self.quality == Quality.ULTRA: self.use_sam = True self.use_depth = True self.bridge_gaps = True self.line_style = LineArtStyle.FUSED self.density = "dense" self.close_iterations = 2