control process override improvements

This commit is contained in:
Vladimir Mandic
2024-01-29 12:57:46 -05:00
parent b13d40d52c
commit f74637e813
10 changed files with 45 additions and 37 deletions
+16 -8
View File
@@ -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
View File
@@ -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)
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+2 -2
View File
@@ -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',