mirror of
https://github.com/vladmandic/automatic
synced 2026-09-20 01:31:13 +02:00
+4
-1
@@ -6,7 +6,7 @@
|
||||
- [CircleStone Anima 1.0](https://huggingface.co/circlestone-labs/Anima) in *Base* and *Turbo* (distilled) variants
|
||||
in both original precision and SDNQ-4bit quantiztion
|
||||
- **Features**
|
||||
- **SDNQ** additional quantization algorithm: *Hadamard Rotations*
|
||||
- **SDNQ** new quantization algorithm: *Hadamard Rotations*
|
||||
much higher quality than base SDNQ, but runs slightly slower
|
||||
still faster than SVD and can be combined together with SVD for combined benefits
|
||||
- **Metadata**
|
||||
@@ -15,6 +15,8 @@
|
||||
- **Captioning** new feature: analyze existing images for prompt adherence
|
||||
*tip*: image analysis requires larger VLM model to produce quality output
|
||||
new api endpoint: `/sdapi/v1/analyze`
|
||||
- **Masking** updated interface and capabilities
|
||||
you can now also select mask type instead of focing alpha mask with all models
|
||||
- **HF download** use `XET` by default
|
||||
see *settings -> huggingface -> download method* for options
|
||||
- **Nunchaku** consider DEV builds when auto-installing
|
||||
@@ -46,6 +48,7 @@
|
||||
- improve `settings` search
|
||||
- `nunchaku` z-image loader
|
||||
- `ui` server log monitor
|
||||
- `kanvas` enable toolbar on *send-to* action
|
||||
|
||||
## Update for 2026-05-13
|
||||
|
||||
|
||||
Submodule extensions-builtin/sdnext-kanvas updated: 4fa1f5e38d...343d75019c
+1
-1
@@ -4957,7 +4957,7 @@
|
||||
},
|
||||
{
|
||||
"id": 33,
|
||||
"label": "Inpaint masked only",
|
||||
"label": "Focus mask",
|
||||
"localized": "التلوين للمناطق المقنعة فقط",
|
||||
"reload": "",
|
||||
"hint": ""
|
||||
|
||||
+1
-1
@@ -4957,7 +4957,7 @@
|
||||
},
|
||||
{
|
||||
"id": 33,
|
||||
"label": "Inpaint masked only",
|
||||
"label": "Focus mask",
|
||||
"localized": "শুধুমাত্র মাস্কড অংশ ইনপেইন্ট করুন",
|
||||
"reload": "",
|
||||
"hint": ""
|
||||
|
||||
+1
-1
@@ -4957,7 +4957,7 @@
|
||||
},
|
||||
{
|
||||
"id": 34,
|
||||
"label": "Inpaint masked only",
|
||||
"label": "Focus mask",
|
||||
"localized": "Nur maskiertes Inpaint",
|
||||
"reload": "",
|
||||
"hint": "Nur maskiertes Inpaint"
|
||||
|
||||
+1
-1
@@ -730,7 +730,7 @@
|
||||
{"id":"","label":"Include images","localized":"","hint":"","ui":"script_xyz_grid_script"},
|
||||
{"id":"","label":"invert","localized":"","hint":"","ui":"img2img"},
|
||||
{"id":"","label":"Init image same as control","localized":"","hint":"Will additionally treat any image placed into the Control input window as a source for img2img type tasks, an image to modify for example.","ui":"control"},
|
||||
{"id":"","label":"Inpaint masked only","localized":"","hint":"Crop the masked region, denoise it at full resolution, then paste the result back into the original image.<br>Best for small detail edits where you want maximum quality on the masked area without spending compute denoising the rest of the image. Detail in unmasked regions stays untouched.<br><br>Tradeoff: the model only sees the cropped region, so it loses global context. The inpainted content may not match the surrounding scene's lighting, perspective, or style, and visible seams can appear at the crop boundary. Mitigate with <b><i>Dilate</i></b> + <b><i>Blur</i></b> on the mask, or disable this option to denoise the full image together.<br>When off, the whole image is denoised at the generation resolution and the unmasked area is restored from the original via the mask blend, which preserves global coherence at the cost of detail in the masked region.<br><br>Default off.","ui":"control"},
|
||||
{"id":"","label":"Focus mask","localized":"","hint":"Crop the masked region, denoise it at full resolution, then paste the result back into the original image.<br>Best for small detail edits where you want maximum quality on the masked area without spending compute denoising the rest of the image. Detail in unmasked regions stays untouched.<br><br>Tradeoff: the model only sees the cropped region, so it loses global context. The inpainted content may not match the surrounding scene's lighting, perspective, or style, and visible seams can appear at the crop boundary. Mitigate with <b><i>Dilate</i></b> + <b><i>Blur</i></b> on the mask, or disable this option to denoise the full image together.<br>When off, the whole image is denoised at the generation resolution and the unmasked area is restored from the original via the mask blend, which preserves global coherence at the cost of detail in the masked region.<br><br>Default off.","ui":"control"},
|
||||
{"id":"","label":"Invert mask","localized":"","hint":"Swaps which area is treated as masked.<br>Useful when you have painted the region to <b>preserve</b> instead of the region to <b>modify</b>: enable this to flip the interpretation without redoing the mask.<br><br>Default off.","ui":"control"},
|
||||
{"id":"","label":"IOU","localized":"","hint":"","ui":"control"},
|
||||
{"id":"","label":"Init strength","localized":"","hint":"","ui":"video"},
|
||||
|
||||
+1
-1
@@ -4957,7 +4957,7 @@
|
||||
},
|
||||
{
|
||||
"id": 33,
|
||||
"label": "Inpaint masked only",
|
||||
"label": "Focus mask",
|
||||
"localized": "Inpaint solo en máscara",
|
||||
"reload": "",
|
||||
"hint": ""
|
||||
|
||||
+1
-1
@@ -4957,7 +4957,7 @@
|
||||
},
|
||||
{
|
||||
"id": 33,
|
||||
"label": "Inpaint masked only",
|
||||
"label": "Focus mask",
|
||||
"localized": "Inpaint uniquement masqué",
|
||||
"reload": "",
|
||||
"hint": ""
|
||||
|
||||
+1
-1
@@ -4957,7 +4957,7 @@
|
||||
},
|
||||
{
|
||||
"id": 33,
|
||||
"label": "Inpaint masked only",
|
||||
"label": "Focus mask",
|
||||
"localized": "מילוי (Inpaint) של האזור המסומן בלבד",
|
||||
"reload": "",
|
||||
"hint": ""
|
||||
|
||||
+1
-1
@@ -4957,7 +4957,7 @@
|
||||
},
|
||||
{
|
||||
"id": 33,
|
||||
"label": "Inpaint masked only",
|
||||
"label": "Focus mask",
|
||||
"localized": "केवल मास्क किया गया इनपेंट करें",
|
||||
"reload": "n/a",
|
||||
"hint": ""
|
||||
|
||||
+1
-1
@@ -4964,7 +4964,7 @@
|
||||
},
|
||||
{
|
||||
"id": 0,
|
||||
"label": "Inpaint masked only",
|
||||
"label": "Focus mask",
|
||||
"localized": "Inpaintaj samo maskirano",
|
||||
"reload": "",
|
||||
"hint": ""
|
||||
|
||||
+1
-1
@@ -4957,7 +4957,7 @@
|
||||
},
|
||||
{
|
||||
"id": 33,
|
||||
"label": "Inpaint masked only",
|
||||
"label": "Focus mask",
|
||||
"localized": "Inpaint hanya bagian yang ditopeng",
|
||||
"reload": "n/a",
|
||||
"hint": ""
|
||||
|
||||
+1
-1
@@ -4957,7 +4957,7 @@
|
||||
},
|
||||
{
|
||||
"id": 34,
|
||||
"label": "Inpaint masked only",
|
||||
"label": "Focus mask",
|
||||
"localized": "Inpaint solo maschera",
|
||||
"reload": "n/a",
|
||||
"hint": "Esegui il processo di inpainting solo sull'area mascherata"
|
||||
|
||||
+2
-2
@@ -4957,9 +4957,9 @@
|
||||
},
|
||||
{
|
||||
"id": 33,
|
||||
"label": "Inpaint masked only",
|
||||
"label": "Focus mask",
|
||||
"localized": "マスクされた部分のみインペイント",
|
||||
"reload": "Inpaint masked only",
|
||||
"reload": "Focus mask",
|
||||
"hint": ""
|
||||
},
|
||||
{
|
||||
|
||||
+1
-1
@@ -4957,7 +4957,7 @@
|
||||
},
|
||||
{
|
||||
"id": 33,
|
||||
"label": "Inpaint masked only",
|
||||
"label": "Focus mask",
|
||||
"localized": "마스크된 영역만 인페인트",
|
||||
"reload": "n/a",
|
||||
"hint": ""
|
||||
|
||||
+2
-2
@@ -4957,8 +4957,8 @@
|
||||
},
|
||||
{
|
||||
"id": 33,
|
||||
"label": "Inpaint masked only",
|
||||
"localized": "Inpaint masked only",
|
||||
"label": "Focus mask",
|
||||
"localized": "Focus mask",
|
||||
"reload": "",
|
||||
"hint": "Only change the area you have painted over."
|
||||
},
|
||||
|
||||
+1
-1
@@ -4957,7 +4957,7 @@
|
||||
},
|
||||
{
|
||||
"id": 33,
|
||||
"label": "Inpaint masked only",
|
||||
"label": "Focus mask",
|
||||
"localized": "Inpaint tylko zamaskowanego",
|
||||
"reload": "",
|
||||
"hint": "Wypełniaj tylko zamaskowany obszar"
|
||||
|
||||
+1
-1
@@ -4957,7 +4957,7 @@
|
||||
},
|
||||
{
|
||||
"id": 33,
|
||||
"label": "Inpaint masked only",
|
||||
"label": "Focus mask",
|
||||
"localized": "Inpaint apenas na máscara",
|
||||
"reload": "",
|
||||
"hint": ""
|
||||
|
||||
+1
-1
@@ -4957,7 +4957,7 @@
|
||||
},
|
||||
{
|
||||
"id": 0,
|
||||
"label": "Inpaint masked only",
|
||||
"label": "Focus mask",
|
||||
"localized": "Inpaint solum obductum",
|
||||
"reload": "n/a",
|
||||
"hint": ""
|
||||
|
||||
+1
-1
@@ -4957,7 +4957,7 @@
|
||||
},
|
||||
{
|
||||
"id": 34,
|
||||
"label": "Inpaint masked only",
|
||||
"label": "Focus mask",
|
||||
"localized": "Закрашивать только маску",
|
||||
"reload": "",
|
||||
"hint": "Ограничить Inpaint только замаскированной областью"
|
||||
|
||||
+1
-1
@@ -4957,7 +4957,7 @@
|
||||
},
|
||||
{
|
||||
"id": 34,
|
||||
"label": "Inpaint masked only",
|
||||
"label": "Focus mask",
|
||||
"localized": "Inpaint samo maskiranog",
|
||||
"reload": "",
|
||||
"hint": ""
|
||||
|
||||
+1
-1
@@ -4957,7 +4957,7 @@
|
||||
},
|
||||
{
|
||||
"id": 33,
|
||||
"label": "Inpaint masked only",
|
||||
"label": "Focus mask",
|
||||
"localized": "Isolated Patching",
|
||||
"reload": "",
|
||||
"hint": "Restrict processing vectors strictly to masked coordinate zones"
|
||||
|
||||
@@ -4957,7 +4957,7 @@
|
||||
},
|
||||
{
|
||||
"id": 34,
|
||||
"label": "Inpaint masked only",
|
||||
"label": "Focus mask",
|
||||
"localized": "Inpaint masked",
|
||||
"reload": "",
|
||||
"hint": "Inpaint masked"
|
||||
|
||||
+1
-1
@@ -4957,7 +4957,7 @@
|
||||
},
|
||||
{
|
||||
"id": 34,
|
||||
"label": "Inpaint masked only",
|
||||
"label": "Focus mask",
|
||||
"localized": "Sadece maskeli alanı inpaint et",
|
||||
"reload": "",
|
||||
"hint": ""
|
||||
|
||||
+1
-1
@@ -4957,7 +4957,7 @@
|
||||
},
|
||||
{
|
||||
"id": 33,
|
||||
"label": "Inpaint masked only",
|
||||
"label": "Focus mask",
|
||||
"localized": "صرف ماسک شدہ حصہ ان پینٹ کریں",
|
||||
"reload": "",
|
||||
"hint": ""
|
||||
|
||||
+1
-1
@@ -4957,7 +4957,7 @@
|
||||
},
|
||||
{
|
||||
"id": 33,
|
||||
"label": "Inpaint masked only",
|
||||
"label": "Focus mask",
|
||||
"localized": "Chỉ inpaint vùng được che",
|
||||
"reload": "",
|
||||
"hint": "Chỉ thực hiện vẽ lại trên vùng mặt nạ được chỉ định"
|
||||
|
||||
+1
-1
@@ -4957,7 +4957,7 @@
|
||||
},
|
||||
{
|
||||
"id": 33,
|
||||
"label": "Inpaint masked only",
|
||||
"label": "Focus mask",
|
||||
"localized": "Inpaint nur maskitan",
|
||||
"reload": "",
|
||||
"hint": "Inpaint nur maskitan"
|
||||
|
||||
+1
-1
@@ -4957,7 +4957,7 @@
|
||||
},
|
||||
{
|
||||
"id": 33,
|
||||
"label": "Inpaint masked only",
|
||||
"label": "Focus mask",
|
||||
"localized": "仅重绘蒙版区域",
|
||||
"reload": "",
|
||||
"hint": ""
|
||||
|
||||
@@ -110,7 +110,7 @@ def preprocess_image(
|
||||
if input_mask is not None:
|
||||
p.extra_generation_params["Mask only"] = masking.opts.mask_only if masking.opts.mask_only else None
|
||||
p.extra_generation_params["Mask auto"] = masking.opts.auto_mask if masking.opts.auto_mask != 'None' else None
|
||||
p.extra_generation_params["Mask invert"] = masking.opts.invert if masking.opts.invert else None
|
||||
p.extra_generation_params["Mask invert"] = masking.opts.mask_invert if masking.opts.mask_invert else None
|
||||
p.extra_generation_params["Mask blur"] = masking.opts.mask_blur if masking.opts.mask_blur > 0 else None
|
||||
p.extra_generation_params["Mask erode"] = masking.opts.mask_erode if masking.opts.mask_erode > 0 else None
|
||||
p.extra_generation_params["Mask dilate"] = masking.opts.mask_dilate if masking.opts.mask_dilate > 0 else None
|
||||
|
||||
@@ -382,8 +382,6 @@ def control_run(state: str = '', # pylint: disable=keyword-arg-before-vararg
|
||||
save_images_before_highres_fix: bool | None = None, save_images_before_refiner: bool | None = None,
|
||||
save_images_before_detailer: bool | None = None, save_images_before_color_correction: bool | None = None,
|
||||
grid_save: bool | None = None, grid_format: str | None = None, return_grid: bool | None = None,
|
||||
save_mask: bool | None = None, save_mask_composite: bool | None = None,
|
||||
return_mask: bool | None = None, return_mask_composite: bool | None = None,
|
||||
keep_incomplete: bool | None = None, image_metadata: bool | None = None, jpeg_quality: int | None = None,
|
||||
# scheduler/noise overrides
|
||||
schedulers_prediction_type: str | None = None, schedulers_beta_schedule: str | None = None, schedulers_timesteps: str | None = None,
|
||||
@@ -545,12 +543,10 @@ def control_run(state: str = '', # pylint: disable=keyword-arg-before-vararg
|
||||
save_images_before_highres_fix=save_images_before_highres_fix, save_images_before_refiner=save_images_before_refiner,
|
||||
save_images_before_detailer=save_images_before_detailer, save_images_before_color_correction=save_images_before_color_correction,
|
||||
grid_save=grid_save, grid_format=grid_format, return_grid=return_grid,
|
||||
save_mask=save_mask, save_mask_composite=save_mask_composite,
|
||||
return_mask=return_mask, return_mask_composite=return_mask_composite,
|
||||
keep_incomplete=keep_incomplete, image_metadata=image_metadata, jpeg_quality=jpeg_quality,
|
||||
# inpaint
|
||||
inpaint_full_res = masking.opts.mask_only,
|
||||
inpainting_mask_invert = 1 if masking.opts.invert else 0,
|
||||
inpainting_mask_invert = 1 if masking.opts.mask_invert else 0,
|
||||
# hdr
|
||||
hdr_mode=hdr_mode, hdr_brightness=hdr_brightness, hdr_color=hdr_color, hdr_sharpen=hdr_sharpen, hdr_clamp=hdr_clamp,
|
||||
hdr_boundary=hdr_boundary, hdr_threshold=hdr_threshold, hdr_maximize=hdr_maximize, hdr_max_center=hdr_max_center, hdr_max_boundary=hdr_max_boundary, hdr_color_picker=hdr_color_picker, hdr_tint_ratio=hdr_tint_ratio, hdr_apply_hires=hdr_apply_hires,
|
||||
|
||||
+35
-55
@@ -142,7 +142,7 @@ MODELS = {
|
||||
'Rembg ISNet anime': 'isnet-anime',
|
||||
}
|
||||
COLORMAP = ['autumn', 'bone', 'jet', 'winter', 'rainbow', 'ocean', 'summer', 'spring', 'cool', 'hsv', 'pink', 'hot', 'parula', 'magma', 'inferno', 'plasma', 'viridis', 'cividis', 'twilight', 'shifted', 'turbo', 'deepgreen']
|
||||
TYPES = ['None', 'Opaque', 'Binary', 'Masked', 'Grayscale', 'Color', 'Composite']
|
||||
TYPES = ['Exact', 'Opaque', 'Binary', 'Masked', 'Grayscale', 'Color', 'Composite']
|
||||
cache_dir = 'models/control/segment'
|
||||
generator: MaskGenerationPipeline = None
|
||||
busy = False
|
||||
@@ -151,13 +151,16 @@ btn_lama = None
|
||||
lama_model = None
|
||||
controls = []
|
||||
opts = SimpleNamespace(**{
|
||||
'model': None,
|
||||
'auto_mask': 'None',
|
||||
'auto_segment': 'None',
|
||||
'mask_only': False,
|
||||
'mask_blur': 0,
|
||||
'mask_erode': 0,
|
||||
'mask_dilate': 0,
|
||||
'mask_only': False,
|
||||
'mask_invert': False,
|
||||
'mask_return': False,
|
||||
'mask_type': 'Grayscale',
|
||||
'model': None,
|
||||
'auto_mask': 'None',
|
||||
'auto_segment': 'None',
|
||||
'seg_iou_thresh': 0.5,
|
||||
'seg_score_thresh': 0.8,
|
||||
'seg_nms_thresh': 0.5,
|
||||
@@ -165,12 +168,10 @@ opts = SimpleNamespace(**{
|
||||
'seg_points_per_batch': 64,
|
||||
'seg_topK': 50,
|
||||
'seg_colormap': 'pink',
|
||||
'preview_type': 'Composite',
|
||||
'seg_live': True,
|
||||
'weight_original': 0.5,
|
||||
'weight_mask': 0.5,
|
||||
'kernel_iterations': 1,
|
||||
'invert': False
|
||||
'kernel_iterations': 1
|
||||
})
|
||||
|
||||
|
||||
@@ -408,7 +409,7 @@ def run_mask(input_image: Image.Image, input_mask: Image.Image | None = None, re
|
||||
except Exception:
|
||||
return input_mask
|
||||
if invert is not None:
|
||||
opts.invert = invert
|
||||
opts.mask_invert = invert
|
||||
|
||||
# set legacy mask args
|
||||
if mask_blur is not None or mask_padding is not None:
|
||||
@@ -461,12 +462,12 @@ def run_mask(input_image: Image.Image, input_mask: Image.Image | None = None, re
|
||||
debug(f'Mask blur={opts.mask_blur:.3f} x={sigmax} y={sigmay} mask={mask.shape}')
|
||||
except Exception as e:
|
||||
log.error(f'Mask blur: {e}')
|
||||
if opts.invert:
|
||||
if opts.mask_invert:
|
||||
mask = np.invert(mask)
|
||||
|
||||
return_type = return_type or opts.preview_type
|
||||
return_type = return_type or opts.mask_type
|
||||
|
||||
if return_type == 'None':
|
||||
if return_type == 'Exact':
|
||||
return input_mask
|
||||
elif return_type == 'Opaque':
|
||||
binary_mask = cv2.threshold(mask, 0, 255, cv2.THRESH_BINARY)[1]
|
||||
@@ -520,59 +521,41 @@ def run_lama(input_image: gr.Image, input_mask: gr.Image = None):
|
||||
return result
|
||||
|
||||
|
||||
def run_mask_live(input_image: gr.Image):
|
||||
global busy # pylint: disable=global-statement
|
||||
if opts.seg_live:
|
||||
if not busy:
|
||||
busy = True
|
||||
res = run_mask(input_image)
|
||||
busy = False
|
||||
return res
|
||||
return None
|
||||
|
||||
|
||||
def create_segment_ui():
|
||||
def update_opts(*args):
|
||||
opts.seg_live = args[0]
|
||||
opts.mask_only = args[1]
|
||||
opts.invert = args[2]
|
||||
opts.mask_dilate = args[3]
|
||||
opts.mask_erode = args[4]
|
||||
opts.mask_blur = args[5]
|
||||
opts.seg_score_thresh = args[6]
|
||||
opts.auto_segment = args[7]
|
||||
opts.auto_mask = args[8]
|
||||
opts.seg_iou_thresh = args[9]
|
||||
opts.seg_nms_thresh = args[10]
|
||||
opts.preview_type = args[11]
|
||||
opts.seg_colormap = args[12]
|
||||
# opts.seg_live
|
||||
opts.mask_dilate, opts.mask_erode, opts.mask_blur, \
|
||||
opts.mask_only, opts.mask_invert, opts.mask_return, \
|
||||
opts.mask_type, opts.mask_colormap, \
|
||||
opts.auto_segment, opts.auto_mask, opts.seg_score_thresh, opts.seg_iou_thresh, opts.seg_nms_thresh = args
|
||||
debug(f'Update mask opts: {args}')
|
||||
|
||||
global btn_mask, btn_lama # pylint: disable=global-statement
|
||||
with gr.Accordion(open=False, label="Mask", elem_id="control_mask", elem_classes=["small-accordion"]):
|
||||
controls.clear()
|
||||
with gr.Row():
|
||||
controls.append(gr.Checkbox(label="Live update", value=False, visible=False, elem_id="control_mask_live_update"))
|
||||
with gr.Row():
|
||||
controls.append(gr.Checkbox(label="Inpaint masked only", value=False, elem_id="control_mask_only", ))
|
||||
controls.append(gr.Checkbox(label="Invert mask", value=False, elem_id="control_mask_invert"))
|
||||
with gr.Row():
|
||||
controls.append(gr.Slider(minimum=0.0, maximum=1.0, step=0.01, label='Dilate', value=0, elem_id="control_mask_dilate"))
|
||||
controls.append(gr.Slider(minimum=0.0, maximum=1.0, step=0.01, label='Erode', value=0, elem_id="control_mask_erode"))
|
||||
with gr.Row():
|
||||
controls.append(gr.Slider(minimum=0.0, maximum=1.0, step=0.01, label='Blur', value=0, elem_id="control_mask_blur"))
|
||||
controls.append(gr.Slider(minimum=0.0, maximum=1.0, step=0.01, label='Auto min score', value=0.8, elem_id="control_mask_score"))
|
||||
with gr.Row():
|
||||
controls.append(gr.Dropdown(label="Auto-segment", choices=MODELS.keys(), value='None', elem_id="control_mask_segment"))
|
||||
controls.append(gr.Dropdown(label="Auto-mask", choices=['None', 'Threshold', 'Edge', 'Grayscale'], value='None', elem_id="control_mask_auto"))
|
||||
controls.append(gr.Checkbox(label="Focus mask", value=False, elem_id="control_mask_only", ))
|
||||
controls.append(gr.Checkbox(label="Invert mask", value=False, elem_id="control_mask_invert"))
|
||||
controls.append(gr.Checkbox(label="Include mask", value=False, elem_id="control_mask_return"))
|
||||
with gr.Row():
|
||||
controls.append(gr.Slider(minimum=0.0, maximum=1.0, step=0.01, label='IOU', value=0.5, visible=False, elem_id="control_mask_iou"))
|
||||
controls.append(gr.Slider(minimum=0.0, maximum=1.0, step=0.01, label='NMS', value=0.5, visible=False, elem_id="control_mask_nms"))
|
||||
controls.append(gr.Dropdown(label="Mask type", choices=TYPES, value='Grayscale', elem_id="control_mask_preview"))
|
||||
controls.append(gr.Dropdown(label="Mask Colormap", choices=COLORMAP, value='pink', elem_id="control_mask_colormap", visible=False))
|
||||
with gr.Accordion(open=False, label="Auto masking",elem_classes=["small-accordion"]):
|
||||
with gr.Row():
|
||||
controls.append(gr.Dropdown(label="Auto-segment", choices=MODELS.keys(), value='None', elem_id="control_mask_segment"))
|
||||
controls.append(gr.Dropdown(label="Auto-mask", choices=['None', 'Threshold', 'Edge', 'Grayscale'], value='None', elem_id="control_mask_auto"))
|
||||
controls.append(gr.Slider(minimum=0.0, maximum=1.0, step=0.01, label='Auto min score', value=0.8, elem_id="control_mask_score"))
|
||||
with gr.Row():
|
||||
btn_lama = gr.Button("LaMa remove", elem_id="control_mask_remove")
|
||||
with gr.Row():
|
||||
controls.append(gr.Slider(minimum=0.0, maximum=1.0, step=0.01, label='IOU', value=0.5, visible=False, elem_id="control_mask_iou"))
|
||||
controls.append(gr.Slider(minimum=0.0, maximum=1.0, step=0.01, label='NMS', value=0.5, visible=False, elem_id="control_mask_nms"))
|
||||
with gr.Row():
|
||||
controls.append(gr.Dropdown(label="Preview", choices=['None', 'Masked', 'Binary', 'Grayscale', 'Color', 'Composite'], value='Composite', elem_id="control_mask_preview"))
|
||||
controls.append(gr.Dropdown(label="Colormap", choices=COLORMAP, value='pink', elem_id="control_mask_colormap"))
|
||||
with gr.Row():
|
||||
btn_mask = gr.Button("Run Preview", elem_id="control_mask_refresh", )
|
||||
btn_lama = gr.Button("LaMa Remove", elem_id="control_mask_remove")
|
||||
btn_mask = gr.Button("Run preview", elem_id="control_mask_refresh", )
|
||||
|
||||
for control in controls:
|
||||
control.change(fn=update_opts, inputs=controls, outputs=[])
|
||||
@@ -583,9 +566,6 @@ def bind_controls(image_controls: list[gr.Image], output_image: gr.Image):
|
||||
for image_control in image_controls:
|
||||
btn_mask.click(run_mask, inputs=[image_control], outputs=[output_image])
|
||||
btn_lama.click(run_lama, inputs=[image_control], outputs=[output_image])
|
||||
image_control.edit(fn=run_mask_live, inputs=[image_control], outputs=[output_image])
|
||||
for control in controls:
|
||||
control.change(fn=run_mask_live, inputs=[image_control], outputs=[output_image])
|
||||
|
||||
|
||||
def process_kanvas(kanvas_data):
|
||||
|
||||
+8
-23
@@ -3,7 +3,7 @@ import json
|
||||
import time
|
||||
import numpy as np
|
||||
from PIL import Image, ImageOps
|
||||
from modules import shared, devices, errors, images, scripts_manager, memstats, script_callbacks, extra_networks, detailer, sd_models, sd_checkpoint, sd_vae, processing_helpers, processing_grading, timer
|
||||
from modules import shared, devices, errors, images, scripts_manager, memstats, script_callbacks, extra_networks, detailer, sd_models, sd_checkpoint, sd_vae, processing_helpers, processing_grading, timer, masking
|
||||
from modules.logger import log
|
||||
from modules.sd_hijack_hypertile import context_hypertile_vae, context_hypertile_unet
|
||||
from modules.processing_class import ( # pylint: disable=unused-import
|
||||
@@ -373,28 +373,12 @@ def process_samples(p: StableDiffusionProcessing, samples):
|
||||
if _overlay:
|
||||
image = apply_overlay(image, p.paste_to, i, p.overlay_images)
|
||||
|
||||
_save_mask = get_opt(p, 'save_mask')
|
||||
_save_mask_composite = get_opt(p, 'save_mask_composite')
|
||||
_return_mask = get_opt(p, 'return_mask')
|
||||
_return_mask_composite = get_opt(p, 'return_mask_composite')
|
||||
if hasattr(p, 'mask_for_overlay') and p.mask_for_overlay and any([_save_mask, _save_mask_composite, _return_mask, _return_mask_composite]):
|
||||
image_mask = p.mask_for_overlay.convert('RGB')
|
||||
image1 = image.convert('RGBA').convert('RGBa')
|
||||
image2 = Image.new('RGBa', image.size)
|
||||
mask = images.resize_image(3, p.mask_for_overlay, image.width, image.height).convert('L')
|
||||
image_mask_composite = Image.composite(image1, image2, mask).convert('RGBA')
|
||||
info = create_infotext(p, p.prompts, p.seeds, p.subseeds, index=i)
|
||||
_fmt = get_opt(p, 'samples_format')
|
||||
if _save_mask:
|
||||
images.save_image(image_mask, p.outpath_samples, "", p.seeds[i], p.prompts[i], _fmt, info=info, p=p, suffix="-mask")
|
||||
if _save_mask_composite:
|
||||
images.save_image(image_mask_composite, p.outpath_samples, "", p.seeds[i], p.prompts[i], _fmt, info=info, p=p, suffix="-mask-composite")
|
||||
if _return_mask:
|
||||
out_infotexts.append(info)
|
||||
out_images.append(image_mask)
|
||||
if _return_mask_composite:
|
||||
out_infotexts.append(info)
|
||||
out_images.append(image_mask_composite)
|
||||
if masking.opts.mask_return and p.image_mask is not None:
|
||||
out_infotexts.append(create_infotext(p, all_prompts=['Mask']))
|
||||
if p.mask_for_overlay is not None:
|
||||
out_images.append(p.mask_for_overlay.convert('RGB'))
|
||||
else:
|
||||
out_images.append(p.image_mask.convert('RGB'))
|
||||
|
||||
_inc_mask = getattr(p, 'include_mask', None)
|
||||
if _inc_mask is None:
|
||||
@@ -426,6 +410,7 @@ def process_samples(p: StableDiffusionProcessing, samples):
|
||||
image.info["parameters"] = info
|
||||
out_infotexts.append(info)
|
||||
out_images.append(image)
|
||||
|
||||
shared.history.add(None, info=out_infotexts, ops=p.ops, images=out_images)
|
||||
return out_images, out_infotexts
|
||||
|
||||
|
||||
@@ -106,10 +106,6 @@ class StableDiffusionProcessing:
|
||||
grid_save: bool | None = None,
|
||||
grid_format: str | None = None,
|
||||
return_grid: bool | None = None,
|
||||
save_mask: bool | None = None,
|
||||
save_mask_composite: bool | None = None,
|
||||
return_mask: bool | None = None,
|
||||
return_mask_composite: bool | None = None,
|
||||
keep_incomplete: bool | None = None,
|
||||
image_metadata: bool | None = None,
|
||||
jpeg_quality: int | None = None,
|
||||
@@ -390,10 +386,6 @@ class StableDiffusionProcessing:
|
||||
self.grid_save = grid_save
|
||||
self.grid_format = grid_format
|
||||
self.return_grid = return_grid
|
||||
self.save_mask = save_mask
|
||||
self.save_mask_composite = save_mask_composite
|
||||
self.return_mask = return_mask
|
||||
self.return_mask_composite = return_mask_composite
|
||||
self.keep_incomplete = keep_incomplete
|
||||
self.image_metadata = image_metadata
|
||||
self.jpeg_quality = jpeg_quality
|
||||
@@ -778,9 +770,9 @@ class StableDiffusionProcessingImg2Img(StableDiffusionProcessing):
|
||||
if type(self.image_mask) == list:
|
||||
self.image_mask = self.image_mask[0]
|
||||
if 'Control' in self.__class__.__name__:
|
||||
self.image_mask = masking.run_mask(input_image=self.init_images, input_mask=self.image_mask, return_type='Grayscale', invert=self.inpainting_mask_invert==1) # blur/padding are handled in masking module
|
||||
self.image_mask = masking.run_mask(input_image=self.init_images, input_mask=self.image_mask, invert=self.inpainting_mask_invert==1) # blur/padding are handled in masking module
|
||||
elif self.image_mask is not None:
|
||||
self.image_mask = masking.run_mask(input_image=self.init_images, input_mask=self.image_mask, return_type='Grayscale', invert=self.inpainting_mask_invert==1, mask_blur=self.mask_blur, mask_padding=self.inpaint_full_res_padding) # old img2img
|
||||
self.image_mask = masking.run_mask(input_image=self.init_images, input_mask=self.image_mask, invert=self.inpainting_mask_invert==1, mask_blur=self.mask_blur, mask_padding=self.inpaint_full_res_padding) # old img2img
|
||||
if self.inpaint_full_res and self.image_mask is not None: # mask only inpaint
|
||||
self.mask_for_overlay = self.image_mask
|
||||
mask = self.image_mask.convert('L')
|
||||
|
||||
@@ -163,7 +163,7 @@ def select_input(input_mode, init_type, input_video, input_batch, input_folder,
|
||||
# control inputs
|
||||
if isinstance(selected_input, Image.Image): # image via upload -> image
|
||||
if input_mode == 'Outpaint':
|
||||
masking.opts.invert = True
|
||||
masking.opts.mask_invert = True
|
||||
selected_input, input_mask = masking.outpaint(input_image=selected_input)
|
||||
input_source = [selected_input]
|
||||
input_type = 'PIL.Image'
|
||||
|
||||
@@ -450,8 +450,6 @@ def create_settings(cmd_opts):
|
||||
"save_images_before_refiner": OptionInfo(False, "Save image before refiner"),
|
||||
"save_images_before_detailer": OptionInfo(False, "Save image before detailer"),
|
||||
"save_images_before_color_correction": OptionInfo(False, "Save image before color correction"),
|
||||
"save_mask": OptionInfo(False, "Save inpainting mask"),
|
||||
"save_mask_composite": OptionInfo(False, "Save inpainting masked composite"),
|
||||
"gradio_skip_video": OptionInfo(False, "Do not display video output in UI"),
|
||||
|
||||
"image_sep_watermark": OptionInfo("<h2>Watermarking</h2>", "", gr.HTML),
|
||||
@@ -552,8 +550,6 @@ def create_settings(cmd_opts):
|
||||
|
||||
"images_sep_ui": OptionInfo("<h2>Outputs & Images</h2>", "", gr.HTML),
|
||||
"return_grid": OptionInfo(True, "Show grid in results"),
|
||||
"return_mask": OptionInfo(False, "Inpainting include greyscale mask in results"),
|
||||
"return_mask_composite": OptionInfo(False, "Inpainting include masked composite in results"),
|
||||
"send_seed": OptionInfo(True, "Send seed when sending prompt or image to other interface", gr.Checkbox, {"visible": False}),
|
||||
"send_size": OptionInfo(False, "Send size when sending prompt or image to another interface", gr.Checkbox, {"visible": False}),
|
||||
}))
|
||||
|
||||
Reference in New Issue
Block a user