From ec86fa43b49327b5d04855b81901e2474f355b9e Mon Sep 17 00:00:00 2001 From: "ilian.iliev" Date: Sun, 23 Nov 2025 21:44:34 +0200 Subject: [PATCH] Fixed typo --- .gitignore | 1 + CLAUDE.md | 66 +++++++++++++++++++ scripts/eyemask/modules/depthmap.py | 2 - scripts/eyemask/script.py | 6 +- scripts/eyemask/script_embedded.py | 6 +- scripts/eyemask/ui.py | 4 +- .../eyemask/{widlcards.py => wildcards.py} | 0 7 files changed, 75 insertions(+), 10 deletions(-) create mode 100644 CLAUDE.md rename scripts/eyemask/{widlcards.py => wildcards.py} (100%) diff --git a/.gitignore b/.gitignore index 23ccfb9..6323ffb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ .idea +.claude __pycache__/ /outputs/ diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..878e5d7 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,66 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +**stable-diffusion-webui-eyemask** is a Python extension for AUTOMATIC1111's Stable Diffusion Web UI. It creates masks for eyes, faces, and bodies using dlib facial landmarks or MiDaS depth estimation, then redraws those masked areas using configurable prompts and parameters. + +## Architecture + +### Entry Points (scripts/) + +Three parallel entry points provide different execution modes: + +- **`em_script.py`** - Standard mode: `EyeMaskScript` extends `scripts.Script`, executes via `run()` method +- **`em_script_embedded.py`** - Embedded mode: `EyeMaskEmbeddedScript` hooks into the generation pipeline via `process()`/`postprocess()` instead of running separately. Toggled via `em_show_embedded_version` setting +- **`em_api.py`** - REST API at `/sdapi/v1/eyemask/v1/*` for programmatic access + +### Core Logic (scripts/eyemask/) + +- **`script.py`** - `EyeMasksCore.execute()` orchestrates the main flow: generate/receive image → generate mask → inpaint with mask prompt → save with metadata +- **`script_embedded.py`** - `EyeMasksEmbeddedCore` extends `EyeMasksCore`, applies mask redraw as a post-processing refinement step +- **`mask_generator.py`** - Mask detection algorithms: + - `get_eyes_mask_dlib()` - Uses dlib landmarks 36-48 for eye regions + - `get_face_mask_dlib()` - Uses dlib landmarks 0-27 for face outline + - `get_face_mask_depth()` / `get_body_mask_depth()` - MiDaS depth estimation +- **`ui.py`** - `EyeMaskUI` renders Gradio interface, supports both standard and embedded modes +- **`wildcards.py`** - `WildcardsGenerator` handles `__wildcard_name__` pattern substitution from files in `/wildcards/` +- **`state.py`** - `SharedSettingsContext` manages model switching with automatic restoration + +### Modules (scripts/eyemask/modules/) + +- **`depthmap.py`** - `SimpleDepthMapGenerator` wraps MiDaS models (DPT Large, MiDaS v21/v21_small) with lazy loading and GPU/CPU selection + +### API (scripts/eyemask/api/) + +- **`api.py`** - FastAPI endpoints: `/mask_list`, `/generate_mask`, `/static/{path}`, `/config.json` +- **`models.py`** - Pydantic request/response models +- **`utils.py`** - Base64 image encoding/decoding + +## Key Patterns + +**Dual-Mode Execution**: Standard mode runs as a separate script; embedded mode hooks into the generation pipeline for seamless integration. + +**Mask Types as List Indices**: Mask types stored in a list with constants for easy enable/disable. + +**Context Manager for Model Switching**: `SharedSettingsContext` preserves and restores checkpoint/VAE settings when temporarily switching models. + +**Wildcard System**: Files in `/wildcards/` directory; `_each` suffix enables sequential (vs random) line selection. + +**Dynamic Parameter Tracking**: `EM_DYNAMIC_PARAMS` list enables regex-based metadata updates in saved images. + +## Development + +**Dev Mode**: Enable `em_dev_mode` in settings to show a reload button that reloads all dynamic modules without restarting the UI. + +**Settings**: Registered in `em_settings.py`, persisted via web UI shared opts and JavaScript LocalStorage. + +**Contributing**: Submit PRs to the `develop` branch. + +## Dependencies + +- **dlib** (19.24.0) - Facial landmark detection +- **cmake** - Required for dlib compilation (may need manual install) +- **MiDaS** - Cloned automatically on first use for depth estimation +- Pre-trained model `shape_predictor_68_face_landmarks.dat` downloaded to `/models/` diff --git a/scripts/eyemask/modules/depthmap.py b/scripts/eyemask/modules/depthmap.py index 43c9dc4..01385fc 100644 --- a/scripts/eyemask/modules/depthmap.py +++ b/scripts/eyemask/modules/depthmap.py @@ -32,8 +32,6 @@ class SimpleDepthMapGenerator(object): model_dir = "./models/midas" # create path to model if not present os.makedirs(model_dir, exist_ok=True) - # print("Loading midas model weights ..") - device = torch.device("cuda" if torch.cuda.is_available() else "cpu") #"dpt_large" if model_type == 0: diff --git a/scripts/eyemask/script.py b/scripts/eyemask/script.py index 256f58a..d5375e5 100644 --- a/scripts/eyemask/script.py +++ b/scripts/eyemask/script.py @@ -4,7 +4,7 @@ import re import modules.shared as shared from modules import devices, images from modules.processing import fix_seed, process_images, Processed, StableDiffusionProcessingTxt2Img, StableDiffusionProcessingImg2Img -from . import mask_generator, utils, widlcards +from . import mask_generator, utils, wildcards from .state import SharedSettingsContext @@ -82,8 +82,8 @@ class EyeMasksCore(): is_txt2img = isinstance(p, StableDiffusionProcessingTxt2Img) is_img2img = not is_txt2img - wildcards_generator_original = widlcards.WildcardsGenerator() - wildcards_generator_mask = widlcards.WildcardsGenerator() + wildcards_generator_original = wildcards.WildcardsGenerator() + wildcards_generator_mask = wildcards.WildcardsGenerator() if (is_img2img): orig_image = p.init_images[0] diff --git a/scripts/eyemask/script_embedded.py b/scripts/eyemask/script_embedded.py index 5528e6f..03b2ee9 100644 --- a/scripts/eyemask/script_embedded.py +++ b/scripts/eyemask/script_embedded.py @@ -3,7 +3,7 @@ import gc import modules.shared as shared from modules import devices, images from modules.processing import fix_seed, process_images, StableDiffusionProcessingTxt2Img, StableDiffusionProcessingImg2Img -from . import widlcards +from . import wildcards from .state import SharedSettingsContext from .script import EyeMasksCore @@ -70,8 +70,8 @@ class EyeMasksEmbeddedCore(EyeMasksCore): is_txt2img = isinstance(p, StableDiffusionProcessingTxt2Img) - wildcards_generator_original = widlcards.WildcardsGenerator() - wildcards_generator_mask = widlcards.WildcardsGenerator() + wildcards_generator_original = wildcards.WildcardsGenerator() + wildcards_generator_mask = wildcards.WildcardsGenerator() p_em = StableDiffusionProcessingImg2Img( init_images=[processed.images[0]], diff --git a/scripts/eyemask/ui.py b/scripts/eyemask/ui.py index d037d64..4084471 100644 --- a/scripts/eyemask/ui.py +++ b/scripts/eyemask/ui.py @@ -5,7 +5,7 @@ import gradio as gr import modules.sd_models from modules.ui_components import ToolButton -from . import constants, script, script_embedded, utils, widlcards, state, mask_generator +from . import constants, script, script_embedded, utils, wildcards, state, mask_generator from modules import shared @@ -22,7 +22,7 @@ class EyeMaskUI(): # reimport all dynamic packs importlib.reload(utils) importlib.reload(state) - importlib.reload(widlcards) + importlib.reload(wildcards) importlib.reload(mask_generator) # instantiate again core logic if self.is_embedded: diff --git a/scripts/eyemask/widlcards.py b/scripts/eyemask/wildcards.py similarity index 100% rename from scripts/eyemask/widlcards.py rename to scripts/eyemask/wildcards.py