diff --git a/CHANGELOG.md b/CHANGELOG.md index ab3a0783e..5fe980cb9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Change Log for SD.Next -## Update for 2025-11-01 +## Update for 2025-11-02 - **Features** - **detailer** @@ -10,17 +10,18 @@ - add inline wildcards using curly braces syntax - add setting to control `cudnn` enable/disable - **Fixes** + - fix: better handling of detailer settings, thanks @awsr - fix: cleanup `--optional` installer - fix: guard against multi-controlnet in hires - fix: update diffusers - - fix: inpaint - - fix: model type detection - - fix: version detection when cloned with `.git` suffix - - fix: init `sdnq` on video model load - - fix: add vae scale override for chrono - - fix: add tracing to model detection - - ui: fix full-screen image viewer buttons with non-standard ui theme - - ui: control tab show override section + - fix: inpaint handling + - fix: model type detection + - fix: version detection when cloned with `.git` suffix, thanks @awsr + - fix: init `sdnq` on video model load + - fix: add vae scale override for chrono + - fix: add tracing to model detection + - ui: fix full-screen image viewer buttons with non-standard ui theme + - ui: control tab show override section ## Update for 2025-10-31 diff --git a/modules/processing.py b/modules/processing.py index 2f8c0c7aa..22b852fd0 100644 --- a/modules/processing.py +++ b/modules/processing.py @@ -307,16 +307,15 @@ def process_samples(p: StableDiffusionProcessing, samples): info = create_infotext(p, p.prompts, p.seeds, p.subseeds, index=i) images.save_image(Image.fromarray(sample), path=p.outpath_samples, basename="", seed=p.seeds[i], prompt=p.prompts[i], extension=shared.opts.samples_format, info=info, p=p, suffix="-before-detailer") sample = detailer.detail(sample, p) - if sample is not None: - if isinstance(sample, list) and len(sample) > 1: + if isinstance(sample, list): + if len(sample) > 0: image = Image.fromarray(sample[0]) + if len(sample) > 1: annotated = Image.fromarray(sample[1]) out_images.append(annotated) out_infotexts.append("Detailer annotations") - elif isinstance(sample, list): - image = Image.fromarray(sample[0]) - else: - image = Image.fromarray(sample) + elif sample is not None: + image = Image.fromarray(sample) if p.color_corrections is not None and i < len(p.color_corrections): p.ops.append('color') diff --git a/modules/shared.py b/modules/shared.py index 35844e362..f12a6dea9 100644 --- a/modules/shared.py +++ b/modules/shared.py @@ -619,22 +619,6 @@ options_templates.update(options_section(('postprocessing', "Postprocessing"), { "initial_noise_multiplier": OptionInfo(1.0, "Noise multiplier for image processing", gr.Slider, {"minimum": 0.1, "maximum": 1.5, "step": 0.01, "visible": False}), "postprocessing_sep_detailer": OptionInfo("

Detailer

", "", gr.HTML), - "detailer_model": OptionInfo("Detailer", "Detailer model", gr.Radio, lambda: {"choices": [x.name() for x in detailers], "visible": False}), - "detailer_classes": OptionInfo("", "Detailer classes", gr.Textbox, { "visible": False}), - "detailer_conf": OptionInfo(0.6, "Min confidence", gr.Slider, {"minimum": 0.0, "maximum": 1.0, "step": 0.05, "visible": False}), - "detailer_max": OptionInfo(2, "Max detected", gr.Slider, {"minimum": 1, "maximum": 10, "step": 1, "visible": False}), - "detailer_iou": OptionInfo(0.5, "Max overlap", gr.Slider, {"minimum": 0, "maximum": 1.0, "step": 0.05, "visible": False}), - "detailer_sigma_adjust": OptionInfo(1.0, "Detailer sigma adjust", gr.Slider, {"minimum": 0, "maximum": 1.0, "step": 0.05, "visible": False}), - "detailer_sigma_adjust_max": OptionInfo(1.0, "Detailer sigma end", gr.Slider, {"minimum": 0, "maximum": 1.0, "step": 0.05, "visible": False}), - "detailer_min_size": OptionInfo(0.0, "Min object size", gr.Slider, {"minimum": 0.0, "maximum": 1.0, "step": 0.05, "visible": False}), - "detailer_max_size": OptionInfo(1.0, "Max object size", gr.Slider, {"minimum": 0.0, "maximum": 1.0, "step": 0.05, "visible": False}), - "detailer_padding": OptionInfo(20, "Item padding", gr.Slider, {"minimum": 0, "maximum": 100, "step": 1, "visible": False}), - "detailer_blur": OptionInfo(10, "Item edge blur", gr.Slider, {"minimum": 0, "maximum": 100, "step": 1, "visible": False}), - "detailer_models": OptionInfo(['face-yolo8n'], "Detailer models", gr.Dropdown, lambda: {"multiselect":True, "choices": list(yolo.list), "visible": False}), - "detailer_args": OptionInfo("", "Detailer args", gr.Textbox, { "visible": False}), - "detailer_merge": OptionInfo(False, "Merge multiple results from each detailer model", gr.Checkbox, {"visible": False}), - "detailer_sort": OptionInfo(False, "Sort detailer output by location", gr.Checkbox, {"visible": False}), - "detailer_save": OptionInfo(False, "Include detection results", gr.Checkbox, {"visible": False}), "detailer_unload": OptionInfo(False, "Move detailer model to CPU when complete"), "detailer_augment": OptionInfo(True, "Detailer use model augment"), @@ -789,6 +773,24 @@ options_templates.update(options_section(('hidden_options', "Hidden options"), { 'schedulers_max_shift': OptionInfo(1.15, "Sampler max shift", gr.Slider, {"minimum": 0.0, "maximum": 4.0, "step": 0.01, "visible": False}), 'uni_pc_variant': OptionInfo("bh2", "UniPC variant", gr.Radio, {"choices": ["bh1", "bh2", "vary_coeff"], "visible": False}), 'uni_pc_skip_type': OptionInfo("time_uniform", "UniPC skip type", gr.Radio, {"choices": ["time_uniform", "time_quadratic", "logSNR"], "visible": False}), + + # detailer settings are handled separately + "detailer_model": OptionInfo("Detailer", "Detailer model", gr.Radio, lambda: {"choices": [x.name() for x in detailers], "visible": False}), + "detailer_classes": OptionInfo("", "Detailer classes", gr.Textbox, { "visible": False}), + "detailer_conf": OptionInfo(0.6, "Min confidence", gr.Slider, {"minimum": 0.0, "maximum": 1.0, "step": 0.05, "visible": False}), + "detailer_max": OptionInfo(2, "Max detected", gr.Slider, {"minimum": 1, "maximum": 10, "step": 1, "visible": False}), + "detailer_iou": OptionInfo(0.5, "Max overlap", gr.Slider, {"minimum": 0, "maximum": 1.0, "step": 0.05, "visible": False}), + "detailer_sigma_adjust": OptionInfo(1.0, "Detailer sigma adjust", gr.Slider, {"minimum": 0, "maximum": 1.0, "step": 0.05, "visible": False}), + "detailer_sigma_adjust_max": OptionInfo(1.0, "Detailer sigma end", gr.Slider, {"minimum": 0, "maximum": 1.0, "step": 0.05, "visible": False}), + "detailer_min_size": OptionInfo(0.0, "Min object size", gr.Slider, {"minimum": 0.0, "maximum": 1.0, "step": 0.05, "visible": False}), + "detailer_max_size": OptionInfo(1.0, "Max object size", gr.Slider, {"minimum": 0.0, "maximum": 1.0, "step": 0.05, "visible": False}), + "detailer_padding": OptionInfo(20, "Item padding", gr.Slider, {"minimum": 0, "maximum": 100, "step": 1, "visible": False}), + "detailer_blur": OptionInfo(10, "Item edge blur", gr.Slider, {"minimum": 0, "maximum": 100, "step": 1, "visible": False}), + "detailer_models": OptionInfo(['face-yolo8n'], "Detailer models", gr.Dropdown, lambda: {"multiselect":True, "choices": list(yolo.list), "visible": False}), + "detailer_args": OptionInfo("", "Detailer args", gr.Textbox, { "visible": False}), + "detailer_merge": OptionInfo(False, "Merge multiple results from each detailer model", gr.Checkbox, {"visible": False}), + "detailer_sort": OptionInfo(False, "Sort detailer output by location", gr.Checkbox, {"visible": False}), + "detailer_save": OptionInfo(False, "Include detection results", gr.Checkbox, {"visible": False}), })) diff --git a/modules/timer.py b/modules/timer.py index d94735902..082e293b6 100644 --- a/modules/timer.py +++ b/modules/timer.py @@ -4,7 +4,7 @@ import sys try: - default_min_time = float(os.environ.get('SD_MIN_TIMER', '0.05')) + default_min_time = float(os.environ.get('SD_MIN_TIMER', '0.1')) except Exception: default_min_time = 0.1 diff --git a/modules/ui_settings.py b/modules/ui_settings.py index 880871530..5a3cc5cdf 100644 --- a/modules/ui_settings.py +++ b/modules/ui_settings.py @@ -208,7 +208,6 @@ def create_ui(): if (section_id, section_text) not in sections: sections.append((section_id, section_text)) - shared.log.debug(f'Settings: sections={len(sections)} settings={len(shared.opts.list())}/{len(list(shared.opts.data_labels))} quicksettings={len(quicksettings_list)}') with gr.Tabs(elem_id="settings"): quicksettings_list.clear() for (section_id, section_text) in sections: @@ -241,6 +240,8 @@ def create_ui(): create_dirty_indicator("show_all_pages", []) request_notifications = gr.Button(value='Request browser notifications', elem_id="request_notifications", visible=False) + shared.log.debug(f'Settings: sections={len(sections)} settings={len(shared.opts.list())}/{len(list(shared.opts.data_labels))} quicksettings={len(quicksettings_list)}') + with gr.TabItem("Update", id="system_update", elem_id="tab_update"): from modules import update update.create_ui() diff --git a/wiki b/wiki index 213bdc836..6fc069677 160000 --- a/wiki +++ b/wiki @@ -1 +1 @@ -Subproject commit 213bdc836534bc29ed353dc89b5b582e455a9bf5 +Subproject commit 6fc0696770923e78e1ae07cb849942568ec11dde