mirror of
https://github.com/vladmandic/automatic
synced 2026-09-19 01:04:32 +02:00
control process override improvements
This commit is contained in:
@@ -4,7 +4,7 @@ import numpy as np
|
||||
from PIL import Image
|
||||
from modules.shared import log
|
||||
from modules.errors import display
|
||||
from modules import devices
|
||||
from modules import devices, images
|
||||
|
||||
from modules.control.proc.hed import HEDdetector
|
||||
from modules.control.proc.canny import CannyDetector
|
||||
@@ -33,6 +33,8 @@ cache_dir = 'models/control/processors'
|
||||
debug = log.trace if os.environ.get('SD_CONTROL_DEBUG', None) is not None else lambda *args, **kwargs: None
|
||||
debug('Trace: CONTROL')
|
||||
config = {
|
||||
# placeholder
|
||||
'None': {},
|
||||
# pose models
|
||||
'OpenPose': {'class': OpenposeDetector, 'checkpoint': True, 'params': {'include_body': True, 'include_hand': False, 'include_face': False}},
|
||||
'DWPose': {'class': DWposeDetector, 'checkpoint': False, 'model': 'Tiny', 'params': {'min_confidence': 0.3}},
|
||||
@@ -68,7 +70,7 @@ def list_models(refresh=False):
|
||||
global models # pylint: disable=global-statement
|
||||
if not refresh and len(models) > 0:
|
||||
return models
|
||||
models = ['None'] + list(config)
|
||||
models = list(config)
|
||||
debug(f'Control list processors: path={cache_dir} models={models}')
|
||||
return models
|
||||
|
||||
@@ -124,7 +126,7 @@ class Processor():
|
||||
def __init__(self, processor_id: str = None, resize = True):
|
||||
self.model = None
|
||||
self.processor_id = None
|
||||
self.override = None
|
||||
# self.override = None
|
||||
self.resize = resize
|
||||
self.reset()
|
||||
self.config(processor_id)
|
||||
@@ -133,7 +135,7 @@ class Processor():
|
||||
|
||||
def reset(self, processor_id: str = None):
|
||||
if self.model is not None:
|
||||
log.debug(f'Control Processor unloaded: id="{self.processor_id}"')
|
||||
debug(f'Control Processor unloaded: id="{self.processor_id}"')
|
||||
self.model = None
|
||||
self.processor_id = processor_id
|
||||
self.override = None
|
||||
@@ -204,14 +206,20 @@ class Processor():
|
||||
display(e, 'Control Processor load')
|
||||
return f'Processor load filed: {processor_id}'
|
||||
|
||||
def __call__(self, image_input: Image, mode: str = 'RGB'):
|
||||
def __call__(self, image_input: Image, mode: str = 'RGB', resize_mode: int = 0, resize_name: str = 'None', scale_tab: int = 1, scale_by: float = 1.0):
|
||||
if self.processor_id is None or self.processor_id == 'None':
|
||||
return image_input
|
||||
if self.override is not None:
|
||||
debug(f'Control Processor: id="{self.processor_id}" override={self.override}')
|
||||
image_input = self.override
|
||||
if resize_mode != 0 and resize_name != 'None':
|
||||
if scale_tab == 1:
|
||||
width_before, height_before = int(image_input.width * scale_by), int(image_input.height * scale_by)
|
||||
debug(f'Control resize: op=before image={image_input} width={width_before} height={height_before} mode={resize_mode} name={resize_name}')
|
||||
image_input = images.resize_image(resize_mode, image_input, width_before, height_before, resize_name)
|
||||
image_process = image_input
|
||||
if image_input is None:
|
||||
log.error('Control Processor: no input')
|
||||
# log.error('Control Processor: no input')
|
||||
return image_process
|
||||
if config[self.processor_id].get('dirty', False):
|
||||
processor_id = self.processor_id
|
||||
@@ -250,5 +258,5 @@ class Processor():
|
||||
input_image = modules.ui_control.input_source
|
||||
if isinstance(input_image, list):
|
||||
input_image = input_image[0]
|
||||
if isinstance(input_image, Image.Image):
|
||||
return self.__call__(input_image)
|
||||
debug('Control process preview')
|
||||
return self.__call__(input_image)
|
||||
|
||||
+20
-20
@@ -376,33 +376,33 @@ def control_run(units: List[unit.Unit], inputs, inits, mask, unit_type: str, is_
|
||||
p.height = input_image.height
|
||||
debug(f'Control: input image={input_image}')
|
||||
|
||||
# process
|
||||
if input_image is None:
|
||||
p.image = []
|
||||
debug(f'Control: process=None image={p.image} mask={mask}')
|
||||
elif len(active_process) == 0:
|
||||
# p.image = [masking.run_mask(input_image=input_image, input_mask=mask, return_type='Masked') if mask is not None else input_image]
|
||||
pass
|
||||
elif len(active_process) > 0:
|
||||
p.image = []
|
||||
masked_image = masking.run_mask(input_image=input_image, input_mask=mask, return_type='Masked') if mask is not None else input_image
|
||||
for i, process in enumerate(active_process): # list[image]
|
||||
image_mode = 'L' if unit_type == 'adapter' and len(active_model) > i and ('Canny' in active_model[i].model_id or 'Sketch' in active_model[i].model_id) else 'RGB' # t2iadapter canny and sketch work in grayscale only
|
||||
debug(f'Control: process="{process.processor_id}" i={i} image={p.image}')
|
||||
processed_image = process(masked_image, image_mode)
|
||||
p.image = []
|
||||
masked_image = masking.run_mask(input_image=input_image, input_mask=mask, return_type='Masked') if mask is not None else input_image
|
||||
for i, process in enumerate(active_process): # list[image]
|
||||
image_mode = 'L' if unit_type == 'adapter' and len(active_model) > i and ('Canny' in active_model[i].model_id or 'Sketch' in active_model[i].model_id) else 'RGB' # t2iadapter canny and sketch work in grayscale only
|
||||
debug(f'Control: i={i+1} process="{process.processor_id}" input={masked_image} override={process.override}')
|
||||
processed_image = process(
|
||||
image_input=masked_image,
|
||||
mode=image_mode,
|
||||
resize_mode=resize_mode_before,
|
||||
resize_name=resize_name_before,
|
||||
scale_tab=selected_scale_tab_before,
|
||||
scale_by=scale_by_before,
|
||||
)
|
||||
if processed_image is not None:
|
||||
p.image.append(processed_image)
|
||||
if shared.opts.control_unload_processor:
|
||||
processors.config[process.processor_id]['dirty'] = True # to force reload
|
||||
process.model = None
|
||||
if shared.opts.control_unload_processor:
|
||||
processors.config[process.processor_id]['dirty'] = True # to force reload
|
||||
process.model = None
|
||||
|
||||
if p.image is not None and len(p.image) > 0:
|
||||
p.init_images = p.image
|
||||
if len(p.image) > 0:
|
||||
p.extra_generation_params["Control process"] = [p.processor_id for p in active_process]
|
||||
if any(img is None for img in p.image):
|
||||
msg = 'Control: attempting process but output is none'
|
||||
shared.log.error(msg)
|
||||
shared.log.error(f'{msg}: {p.image}')
|
||||
restore_pipeline()
|
||||
return msg
|
||||
p.init_images = p.image
|
||||
processed_image = [np.array(i) for i in p.image]
|
||||
processed_image = util.blend(processed_image) # blend all processed images into one
|
||||
processed_image = Image.fromarray(processed_image)
|
||||
|
||||
@@ -111,7 +111,7 @@ class ControlNet():
|
||||
|
||||
def reset(self):
|
||||
if self.model is not None:
|
||||
log.debug(f'Control {what} model unloaded')
|
||||
debug(f'Control {what} model unloaded')
|
||||
self.model = None
|
||||
self.model_id = None
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ class ControlLLLite():
|
||||
|
||||
def reset(self):
|
||||
if self.model is not None:
|
||||
log.debug(f'Control {what} model unloaded')
|
||||
debug(f'Control {what} model unloaded')
|
||||
self.model = None
|
||||
self.model_id = None
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ class Adapter():
|
||||
|
||||
def reset(self):
|
||||
if self.model is not None:
|
||||
log.debug(f'Control {what} model unloaded')
|
||||
debug(f'Control {what} model unloaded')
|
||||
self.model = None
|
||||
self.model_id = None
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ class ControlNetXS():
|
||||
|
||||
def reset(self):
|
||||
if self.model is not None:
|
||||
log.debug(f'Control {what} model unloaded')
|
||||
debug(f'Control {what} model unloaded')
|
||||
self.model = None
|
||||
self.model_id = None
|
||||
|
||||
|
||||
@@ -155,7 +155,7 @@ def select_input(input_mode, input_image, selected_init, init_type, input_resize
|
||||
if selected_input is None:
|
||||
input_source = None
|
||||
busy = False
|
||||
debug('Control clear input')
|
||||
debug('Control input: none')
|
||||
return [gr.Tabs.update(), '']
|
||||
debug(f'Control select input: source={selected_input} init={selected_init} type={init_type} mode={input_mode}')
|
||||
input_type = type(selected_input)
|
||||
@@ -410,7 +410,7 @@ def create_ui(_blocks: gr.Blocks=None):
|
||||
reset_btn = ui_components.ToolButton(value=ui_symbols.reset)
|
||||
image_upload = gr.UploadButton(label=ui_symbols.upload, file_types=['image'], elem_classes=['form', 'gradio-button', 'tool'])
|
||||
process_btn= ui_components.ToolButton(value=ui_symbols.preview)
|
||||
image_preview = gr.Image(label="Input", show_label=False, type="pil", source="upload", interactive=False, height=128, width=128, visible=False)
|
||||
image_preview = gr.Image(label="Input", type="pil", source="upload", height=128, width=128, visible=False, interactive=True, show_label=False, show_download_button=False, container=False)
|
||||
controlnet_ui_units.append(unit_ui)
|
||||
units.append(unit.Unit(
|
||||
unit_type = 'controlnet',
|
||||
|
||||
Reference in New Issue
Block a user