From 68a8ffa3cfd87ec77990b57f2d42848343b5810b Mon Sep 17 00:00:00 2001 From: Vladimir Mandic Date: Thu, 29 Aug 2024 14:09:22 -0400 Subject: [PATCH] ipadapter optional face autocrop input image --- CHANGELOG.md | 1 + cli/api-control.py | 4 +- cli/api-faceid.py | 2 +- cli/api-faces.py | 59 ++++++++++++++++++ cli/api-img2img.py | 2 +- cli/api-info.py | 2 +- cli/api-json.py | 2 +- cli/api-mask.py | 2 +- cli/api-preprocess.py | 2 +- cli/api-txt2img.py | 2 +- cli/api-upscale.py | 2 +- cli/api-vqa.py | 2 +- html/reference.json | 48 ++++++++------ ...ixArt-alpha--PixArt-Sigma-XL-2-1024-MS.jpg | Bin 0 -> 58864 bytes ...rt-XL-2-512x512 - Copy.jpg:Zone.Identifier | 0 ...l--AuraFlow.jpg => fal--AuraFlow-v0.3.jpg} | Bin modules/api/api.py | 1 + modules/api/control.py | 2 +- modules/api/generate.py | 2 + modules/api/process.py | 22 +++++++ modules/control/processors.py | 2 - modules/ipadapter.py | 36 ++++++++++- modules/processing.py | 2 +- modules/processing_class.py | 1 + modules/sd_models.py | 3 +- scripts/face_details.py | 6 +- scripts/ipadapter.py | 14 +++-- 27 files changed, 176 insertions(+), 45 deletions(-) create mode 100755 cli/api-faces.py create mode 100644 models/Reference/PixArt-alpha--PixArt-Sigma-XL-2-1024-MS.jpg create mode 100644 models/Reference/PixArt-alpha--PixArt-XL-2-512x512 - Copy.jpg:Zone.Identifier rename models/Reference/{fal--AuraFlow.jpg => fal--AuraFlow-v0.3.jpg} (100%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4babaa918..fdfc2a7db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -76,6 +76,7 @@ To use and of the new models, simply select model from *Networks -> Reference* a for example: set size->before->method:nearest, mode:fixed or mode:fill - control tab includes superset of txt and img scripts - automatically offload disabled controlnet units +- ipadapter option to auto-crop input images to faces to improve efficiency of face-transfter ipadapters - update **IPEX** to 2.1.40+xpu on Linux, thanks @Disty0! - general **ROCm** fixes, thanks @lshqqytiger! - support for HIP SDK 6.1 on ZLUDA backend, thanks @lshqqytiger! diff --git a/cli/api-control.py b/cli/api-control.py index a735bce4f..79667a2e9 100755 --- a/cli/api-control.py +++ b/cli/api-control.py @@ -132,7 +132,7 @@ def generate(args): # pylint: disable=redefined-outer-name if __name__ == "__main__": - parser = argparse.ArgumentParser(description = 'api-img2img') + parser = argparse.ArgumentParser(description = 'api-control') parser.add_argument('--init', required=False, default=None, help='init image') parser.add_argument('--input', required=False, default=None, help='input image') parser.add_argument('--mask', required=False, help='mask image') @@ -148,5 +148,5 @@ if __name__ == "__main__": parser.add_argument('--control', required=False, help='control units') parser.add_argument('--ipadapter', required=False, help='ipadapter units') args = parser.parse_args() - log.info(f'img2img: {args}') + log.info(f'api-control: {args}') generate(args) diff --git a/cli/api-faceid.py b/cli/api-faceid.py index dd9645cea..e656a4a47 100755 --- a/cli/api-faceid.py +++ b/cli/api-faceid.py @@ -95,7 +95,7 @@ if __name__ == "__main__": parser.add_argument('--output', required=False, default=None, help='output image file') parser.add_argument('--model', required=False, help='model name') args = parser.parse_args() - log.info(f'img2img: {args}') + log.info(f'api-faceid: {args}') generate(args) """ diff --git a/cli/api-faces.py b/cli/api-faces.py new file mode 100755 index 000000000..0a98843c0 --- /dev/null +++ b/cli/api-faces.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python +import os +import io +import base64 +import logging +import argparse +import requests +import urllib3 +from PIL import Image + +sd_url = os.environ.get('SDAPI_URL', "http://127.0.0.1:7860") +sd_username = os.environ.get('SDAPI_USR', None) +sd_password = os.environ.get('SDAPI_PWD', None) + +logging.basicConfig(level = logging.INFO, format = '%(asctime)s %(levelname)s: %(message)s') +log = logging.getLogger(__name__) +urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) + + +def auth(): + if sd_username is not None and sd_password is not None: + return requests.auth.HTTPBasicAuth(sd_username, sd_password) + return None + + +def post(endpoint: str, dct: dict = None): + req = requests.post(f'{sd_url}{endpoint}', json = dct, timeout=300, verify=False, auth=auth()) + if req.status_code != 200: + return { 'error': req.status_code, 'reason': req.reason, 'url': req.url } + else: + return req.json() + + +def encode(f): + image = Image.open(f) + if image.mode == 'RGBA': + image = image.convert('RGB') + with io.BytesIO() as stream: + image.save(stream, 'JPEG') + image.close() + values = stream.getvalue() + encoded = base64.b64encode(values).decode() + return encoded + + +def detect(args): # pylint: disable=redefined-outer-name + data = post('/sdapi/v1/faces', { 'image': encode(args.image) }) + for face in zip(data['images'], data['scores']): + log.info(f'Face: score={face[1]}') + image = Image.open(io.BytesIO(base64.b64decode(face[0]))) + image.save(f'/tmp/face_{face[1]}.jpg') + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description = 'api-faces') + parser.add_argument('--image', required=True, help='input image') + args = parser.parse_args() + log.info(f'api-faces: {args}') + detect(args) diff --git a/cli/api-img2img.py b/cli/api-img2img.py index 3a2961e5b..99ab5ac34 100755 --- a/cli/api-img2img.py +++ b/cli/api-img2img.py @@ -94,5 +94,5 @@ if __name__ == "__main__": parser.add_argument('--output', required=False, default=None, help='output image file') parser.add_argument('--model', required=False, help='model name') args = parser.parse_args() - log.info(f'img2img: {args}') + log.info(f'api-img2img: {args}') generate(args) diff --git a/cli/api-info.py b/cli/api-info.py index 83e4dfe2e..1056ddf2a 100755 --- a/cli/api-info.py +++ b/cli/api-info.py @@ -53,5 +53,5 @@ if __name__ == "__main__": parser = argparse.ArgumentParser(description = 'api-info') parser.add_argument('--input', required=True, help='input image') args = parser.parse_args() - log.info(f'info: {args}') + log.info(f'api-info: {args}') info(args) diff --git a/cli/api-json.py b/cli/api-json.py index e8c5270fb..79c0ebc3b 100755 --- a/cli/api-json.py +++ b/cli/api-json.py @@ -38,7 +38,7 @@ def post(endpoint: str, payload: dict = None): if __name__ == "__main__": - parser = argparse.ArgumentParser(description = 'api-txt2img') + parser = argparse.ArgumentParser(description = 'api-json') parser.add_argument('endpoint', nargs=1, help='endpoint') parser.add_argument('json', nargs=1, help='json data or file') args = parser.parse_args() diff --git a/cli/api-mask.py b/cli/api-mask.py index 0a1372138..38aae3018 100755 --- a/cli/api-mask.py +++ b/cli/api-mask.py @@ -79,5 +79,5 @@ if __name__ == "__main__": parser.add_argument('--type', required=False, help='output mask type') parser.add_argument('--output', required=False, help='output image') args = parser.parse_args() - log.info(f'info: {args}') + log.info(f'api-mask: {args}') info(args) diff --git a/cli/api-preprocess.py b/cli/api-preprocess.py index 084f6a0b4..abb6a9d2f 100755 --- a/cli/api-preprocess.py +++ b/cli/api-preprocess.py @@ -72,5 +72,5 @@ if __name__ == "__main__": parser.add_argument('--model', required=True, help='preprocessing model') parser.add_argument('--output', required=False, help='output image') args = parser.parse_args() - log.info(f'info: {args}') + log.info(f'api-preprocess: {args}') info(args) diff --git a/cli/api-txt2img.py b/cli/api-txt2img.py index a00515fe5..fe085e7f1 100755 --- a/cli/api-txt2img.py +++ b/cli/api-txt2img.py @@ -80,5 +80,5 @@ if __name__ == "__main__": parser.add_argument('--output', required=False, default=None, help='output image file') parser.add_argument('--model', required=False, help='model name') args = parser.parse_args() - log.info(f'txt2img: {args}') + log.info(f'api-txt2img: {args}') generate(args) diff --git a/cli/api-upscale.py b/cli/api-upscale.py index 082e008a8..7f188650f 100755 --- a/cli/api-upscale.py +++ b/cli/api-upscale.py @@ -86,5 +86,5 @@ if __name__ == "__main__": parser.add_argument('--upscaler', required=False, default='Nearest', help='upscaler name') parser.add_argument('--scale', required=False, default=2, help='upscaler scale') args = parser.parse_args() - log.info(f'upscale: {args}') + log.info(f'api-upscale: {args}') upscale(args) diff --git a/cli/api-vqa.py b/cli/api-vqa.py index 73de8dbc8..87a3ef2b6 100755 --- a/cli/api-vqa.py +++ b/cli/api-vqa.py @@ -60,5 +60,5 @@ if __name__ == "__main__": parser.add_argument('--model', required=False, help='vqa model') parser.add_argument('--question', required=False, help='question') args = parser.parse_args() - log.info(f'info: {args}') + log.info(f'api-vqa: {args}') info(args) diff --git a/html/reference.json b/html/reference.json index 0f9294ad2..c75d48466 100644 --- a/html/reference.json +++ b/html/reference.json @@ -1,4 +1,29 @@ { + "Juggernaut SD-XL XI": { + "path": "juggernautXL_juggXIByRundiffusion.safetensors@https://civitai.com/api/download/models/782002", + "preview": "juggernautXL_v9Rundiffusionphoto2.jpg", + "desc": "Showcase finetuned model based on Stable diffusion XL", + "extras": "width: 1024, height: 1024, sampler: DEIS, steps: 20, cfg_scale: 6.0" + }, + "Juggernaut SD-XL X Hyper": { + "path": "Juggernaut_X_RunDiffusion_Hyper.safetensors@https://civitai.com/api/download/models/471120", + "preview": "juggernautXL_v9Rundiffusionphoto2.jpg", + "desc": "Showcase finetuned model based on Stable diffusion XL", + "extras": "width: 1024, height: 1024, sampler: DEIS, steps: 20, cfg_scale: 6.0" + }, + "Juggernaut SD-XL IX Lightning": { + "path": "juggernautXL_v9Rdphoto2Lightning.safetensors@https://civitai.com/api/download/models/357609", + "preview": "juggernautXL_v9Rdphoto2Lightning.jpg", + "desc": "Showcase finetuned model based on Stable diffusion XL", + "extras": "width: 1024, height: 1024, sampler: DPM SDE, steps: 6, cfg_scale: 2.0" + }, + "Juggernaut SD Reborn": { + "original": true, + "path": "juggernaut_reborn.safetensors@https://civitai.com/api/download/models/274039", + "preview": "juggernaut_reborn.jpg", + "desc": "Showcase finetuned model based on Stable diffusion 1.5", + "extras": "width: 512, height: 512, sampler: DEIS, steps: 20, cfg_scale: 6.0" + }, "DreamShaper SD v8": { "original": true, @@ -19,31 +44,14 @@ "desc": "Showcase finetuned model based on Stable diffusion XL", "extras": "width: 1024, height: 1024, sampler: DPM SDE, steps: 8, cfg_scale: 2.0" }, - "Juggernaut SD Reborn": { - "original": true, - "path": "juggernaut_reborn.safetensors@https://civitai.com/api/download/models/274039", - "preview": "juggernaut_reborn.jpg", - "desc": "Showcase finetuned model based on Stable diffusion 1.5", - "extras": "width: 512, height: 512, sampler: DEIS, steps: 20, cfg_scale: 6.0" - }, - "Juggernaut SD-XL v9": { - "path": "juggernautXL_v9Rundiffusionphoto2.safetensors@https://civitai.com/api/download/models/348913", - "preview": "juggernautXL_v9Rundiffusionphoto2.jpg", - "desc": "Showcase finetuned model based on Stable diffusion XL", - "extras": "width: 1024, height: 1024, sampler: DEIS, steps: 20, cfg_scale: 6.0" - }, - "Juggernaut SD-XL v9 Lightning": { - "path": "juggernautXL_v9Rdphoto2Lightning.safetensors@https://civitai.com/api/download/models/357609", - "preview": "juggernautXL_v9Rdphoto2Lightning.jpg", - "desc": "Showcase finetuned model based on Stable diffusion XL", - "extras": "width: 1024, height: 1024, sampler: DPM SDE, steps: 6, cfg_scale: 2.0" - }, + "Tempest SD-XL v0.1": { "path": "TempestV0.1-Artistic.safetensors@https://huggingface.co/dataautogpt3/TempestV0.1/resolve/main/TempestV0.1-Artistic.safetensors?download=true", "preview": "TempestV0.1-Artistic.jpg", "desc": "The TempestV0.1 Initiative is a powerhouse in image generation, leveraging an unparalleled dataset of over 6 million images. The collection's vast scale, with resolutions from 1400x2100 to 4800x7200, encompasses 200GB of high-quality content.", "extras": "width: 2048, height: 1024, sampler: DEIS, steps: 40, cfg_scale: 6.0" }, + "SDXS DreamShaper 512": { "path": "IDKiro/sdxs-512-dreamshaper", "preview": "IDKiro--sdxs-512-dreamshaper.jpg", @@ -152,7 +160,7 @@ "AuraFlow 0.3": { "path": "fal/AuraFlow-v0.3", "desc": "AuraFlow v0.3 is the fully open-sourced flow-based text-to-image generation model. The model was trained with more compute compared to the previous version, AuraFlow-v0.2. Compared to AuraFlow-v0.2, the model is fine-tuned on more aesthetic datasets and now supports various aspect ratio, (now width and height up to 1536 pixels).", - "preview": "fal--AuraFlow.jpg", + "preview": "fal--AuraFlow-v0.3.jpg", "skip": true, "extras": "width: 1024, height: 1024" }, diff --git a/models/Reference/PixArt-alpha--PixArt-Sigma-XL-2-1024-MS.jpg b/models/Reference/PixArt-alpha--PixArt-Sigma-XL-2-1024-MS.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d1a808760cb3e64cf2ac24238a05f9e23de1ab19 GIT binary patch literal 58864 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 literal 0 HcmV?d00001 diff --git a/models/Reference/PixArt-alpha--PixArt-XL-2-512x512 - Copy.jpg:Zone.Identifier b/models/Reference/PixArt-alpha--PixArt-XL-2-512x512 - Copy.jpg:Zone.Identifier new file mode 100644 index 000000000..e69de29bb diff --git a/models/Reference/fal--AuraFlow.jpg b/models/Reference/fal--AuraFlow-v0.3.jpg similarity index 100% rename from models/Reference/fal--AuraFlow.jpg rename to models/Reference/fal--AuraFlow-v0.3.jpg diff --git a/modules/api/api.py b/modules/api/api.py index e4dce4cec..890a18733 100644 --- a/modules/api/api.py +++ b/modules/api/api.py @@ -55,6 +55,7 @@ class Api: self.add_api_route("/sdapi/v1/extra-batch-images", self.extras_batch_images_api, methods=["POST"], response_model=models.ResProcessBatch) self.add_api_route("/sdapi/v1/preprocess", self.process.post_preprocess, methods=["POST"]) self.add_api_route("/sdapi/v1/mask", self.process.post_mask, methods=["POST"]) + self.add_api_route("/sdapi/v1/faces", self.process.post_face, methods=["POST"]) # api dealing with optional scripts self.add_api_route("/sdapi/v1/scripts", script.get_scripts_list, methods=["GET"], response_model=models.ResScripts) diff --git a/modules/api/control.py b/modules/api/control.py index b90dba049..9c93b6bc6 100644 --- a/modules/api/control.py +++ b/modules/api/control.py @@ -95,7 +95,7 @@ class APIControl(): def prepare_ip_adapter(self, request): if hasattr(request, "ip_adapter") and request.ip_adapter: - args = { 'ip_adapter_names': [], 'ip_adapter_scales': [], 'ip_adapter_starts': [], 'ip_adapter_ends': [], 'ip_adapter_images': [], 'ip_adapter_masks': [] } + args = { 'ip_adapter_names': [], 'ip_adapter_scales': [], 'ip_adapter_crops': [], 'ip_adapter_starts': [], 'ip_adapter_ends': [], 'ip_adapter_images': [], 'ip_adapter_masks': [] } for ipadapter in request.ip_adapter: if not ipadapter.images or len(ipadapter.images) == 0: continue diff --git a/modules/api/generate.py b/modules/api/generate.py index 371f3c0bf..aeafa05a0 100644 --- a/modules/api/generate.py +++ b/modules/api/generate.py @@ -64,6 +64,7 @@ class APIGenerate(): if hasattr(request, "ip_adapter") and request.ip_adapter: p.ip_adapter_names = [] p.ip_adapter_scales = [] + p.ip_adapter_crops = [] p.ip_adapter_starts = [] p.ip_adapter_ends = [] p.ip_adapter_images = [] @@ -72,6 +73,7 @@ class APIGenerate(): continue p.ip_adapter_names.append(ipadapter.adapter) p.ip_adapter_scales.append(ipadapter.scale) + p.ip_adapter_crops.append(ipadapter.crop) p.ip_adapter_starts.append(ipadapter.start) p.ip_adapter_ends.append(ipadapter.end) p.ip_adapter_images.append([helpers.decode_base64_to_image(x) for x in ipadapter.images]) diff --git a/modules/api/process.py b/modules/api/process.py index 830aa14d9..6dd5e701e 100644 --- a/modules/api/process.py +++ b/modules/api/process.py @@ -26,6 +26,13 @@ class ReqMask(BaseModel): model: Optional[str] = Field(title="Model", description="The model to use for preprocessing") params: Optional[dict] = Field(default={}, title="Settings", description="Preprocessor settings") +class ReqFace(BaseModel): + image: str = Field(title="Image", description="The base64 encoded image") + +class ResFace(BaseModel): + images: List[str] = Field(title="Image", description="The base64 encoded images of detected faces") + scores: List[float] = Field(title="Scores", description="The scores of the detected faces") + class ResMask(BaseModel): mask: str = Field(default='', title="Image", description="The processed image in base64 format") @@ -98,3 +105,18 @@ class APIProcess(): return JSONResponse(status_code=400, content={"error": "Mask is none"}) image = encode_pil_to_base64(processed) return ResMask(mask=image) + + def post_face(self, req: ReqFace): + from scripts.face_details import yolo # pylint: disable=no-name-in-module + image = decode_base64_to_image(req.image) + shared.state.begin('API-FACE', api=True) + images = [] + scores = [] + with self.queue_lock: + yolo.load() + faces = yolo.predict(image) + for face in faces: + images.append(encode_pil_to_base64(face.face)) + scores.append(face.score) + shared.state.end(api=False) + return ResFace(images=images, scores=scores) diff --git a/modules/control/processors.py b/modules/control/processors.py index 6c405ce59..92cf61629 100644 --- a/modules/control/processors.py +++ b/modules/control/processors.py @@ -212,7 +212,6 @@ class Processor(): 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, local_config: dict = {}): if self.override is not None: debug(f'Control Processor: id="{self.processor_id}" override={self.override}') - print('HERE1', image_input) if image_input is not None and image_input.size != self.override.size: debug(f'Control resize: op=override image={self.override} width={image_input.width} height={image_input.height} mode={resize_mode} name={resize_name}') image_input = images.resize_image(resize_mode, self.override, image_input.width, image_input.height, resize_name) @@ -224,7 +223,6 @@ class Processor(): 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) if self.processor_id is None or self.processor_id == 'None': - print('HERE3', self.override) return image_input image_process = image_input if image_input is None: diff --git a/modules/ipadapter.py b/modules/ipadapter.py index f1fa60197..e8476a1b7 100644 --- a/modules/ipadapter.py +++ b/modules/ipadapter.py @@ -72,6 +72,34 @@ def get_scales(adapter_scales, adapter_images): return output_scales +def get_crops(adapter_crops, adapter_images): + output_crops = [adapter_crops] if not isinstance(adapter_crops, list) else adapter_crops + while len(output_crops) < len(adapter_images): + output_crops.append(output_crops[-1]) + return output_crops + + +def crop_images(images, crops): + try: + for i in range(len(images)): + if crops[i]: + from scripts.face_details import yolo # pylint: disable=no-name-in-module + yolo.load() + cropped = [] + for image in images[i]: + faces = yolo.predict(image) + if len(faces) > 0: + cropped.append(faces[0].face) + if len(cropped) == len(images[i]): + print('HERE0') + images[i] = cropped + else: + shared.log.error(f'IP adapter: failed to crop image: source={len(images[i])} faces={len(cropped)}') + except Exception as e: + shared.log.error(f'IP adapter: failed to crop image: {e}') + return images + + def unapply(pipe): # pylint: disable=arguments-differ try: if hasattr(pipe, 'set_ip_adapter_scale'): @@ -84,7 +112,7 @@ def unapply(pipe): # pylint: disable=arguments-differ pass -def apply(pipe, p: processing.StableDiffusionProcessing, adapter_names=[], adapter_scales=[1.0], adapter_starts=[0.0], adapter_ends=[1.0], adapter_images=[]): +def apply(pipe, p: processing.StableDiffusionProcessing, adapter_names=[], adapter_scales=[1.0], adapter_crops=[False], adapter_starts=[0.0], adapter_ends=[1.0], adapter_images=[]): global clip_loaded # pylint: disable=global-statement # overrides if hasattr(p, 'ip_adapter_names'): @@ -104,6 +132,8 @@ def apply(pipe, p: processing.StableDiffusionProcessing, adapter_names=[], adapt return False if hasattr(p, 'ip_adapter_scales'): adapter_scales = p.ip_adapter_scales + if hasattr(p, 'ip_adapter_crops'): + adapter_crops = p.ip_adapter_crops if hasattr(p, 'ip_adapter_starts'): adapter_starts = p.ip_adapter_starts if hasattr(p, 'ip_adapter_ends'): @@ -131,6 +161,8 @@ def apply(pipe, p: processing.StableDiffusionProcessing, adapter_names=[], adapt return False adapter_scales = get_scales(adapter_scales, adapter_images) p.ip_adapter_scales = adapter_scales.copy() + adapter_crops = get_crops(adapter_crops, adapter_images) + p.ip_adapter_crops = adapter_crops.copy() adapter_starts = get_scales(adapter_starts, adapter_images) p.ip_adapter_starts = adapter_starts.copy() adapter_ends = get_scales(adapter_ends, adapter_images) @@ -202,7 +234,7 @@ def apply(pipe, p: processing.StableDiffusionProcessing, adapter_names=[], adapt adapter_scales[i] = 0.00 pipe.set_ip_adapter_scale(adapter_scales) ip_str = [f'{os.path.splitext(adapter)[0]}:{scale}:{start}:{end}' for adapter, scale, start, end in zip(adapter_names, adapter_scales, adapter_starts, adapter_ends)] - p.task_args['ip_adapter_image'] = adapter_images + p.task_args['ip_adapter_image'] = crop_images(adapter_images, adapter_crops) if len(adapter_masks) > 0: p.cross_attention_kwargs = { 'ip_adapter_masks': adapter_masks } p.extra_generation_params["IP Adapter"] = ';'.join(ip_str) diff --git a/modules/processing.py b/modules/processing.py index 173d85564..5c7390903 100644 --- a/modules/processing.py +++ b/modules/processing.py @@ -328,7 +328,7 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed: p.scripts.postprocess_batch_list(p, batch_params, batch_number=n) x_samples_ddim = batch_params.images - def infotext(index): # pylint: disable=function-redefined # noqa: F811 + def infotext(index): # pylint: disable=function-redefined return create_infotext(p, p.prompts, p.seeds, p.subseeds, index=index, all_negative_prompts=p.negative_prompts) for i, x_sample in enumerate(x_samples_ddim): diff --git a/modules/processing_class.py b/modules/processing_class.py index e61cbe401..ad083ec5a 100644 --- a/modules/processing_class.py +++ b/modules/processing_class.py @@ -122,6 +122,7 @@ class StableDiffusionProcessing: self.ip_adapter_images = [] self.ip_adapter_starts = [0.0] self.ip_adapter_ends = [1.0] + self.ip_adapter_crops = [] # hdr self.hdr_mode=hdr_mode self.hdr_brightness=hdr_brightness diff --git a/modules/sd_models.py b/modules/sd_models.py index 8c07d022d..0a3ceca81 100644 --- a/modules/sd_models.py +++ b/modules/sd_models.py @@ -211,7 +211,8 @@ def get_closet_checkpoint_match(search_string): if found and len(found) > 0: return found[0] for v in shared.reference_models.values(): - if search_string in v['path'] or os.path.basename(search_string) in v['path']: + pth = v['path'].split('@')[-1] + if search_string in pth or os.path.basename(search_string) in pth: model_name = search_string.replace('huggingface/', '') checkpoint_info = CheckpointInfo(v['path']) # create a virutal model info checkpoint_info.type = 'huggingface' diff --git a/scripts/face_details.py b/scripts/face_details.py index 1a1fce944..004c775f6 100644 --- a/scripts/face_details.py +++ b/scripts/face_details.py @@ -7,10 +7,11 @@ from modules import devices, processing_class class YoLoResult: - def __init__(self, score: float, box: list[int], mask: Image.Image = None, size: float = 0, width = 0, height = 0, args = {}): + def __init__(self, score: float, box: list[int], mask: Image.Image = None, face: Image.Image = None, size: float = 0, width = 0, height = 0, args = {}): self.score = score self.box = box self.mask = mask + self.face = face self.size = size self.width = width self.height = height @@ -82,7 +83,8 @@ class FaceRestorerYolo(FaceRestoration): mask_image = Image.new('L', image.size, 0) draw = ImageDraw.Draw(mask_image) draw.rectangle(box, fill="white", outline=None, width=0) - result.append(YoLoResult(score=round(score, 2), box=box, mask=mask_image, size=size, width=w, height=h, args=args)) + face_image = image.crop(box) + result.append(YoLoResult(score=round(score, 2), box=box, mask=mask_image, face=face_image, size=size, width=w, height=h, args=args)) return result def load(self): diff --git a/scripts/ipadapter.py b/scripts/ipadapter.py index dab1e0fba..c7fcb3053 100644 --- a/scripts/ipadapter.py +++ b/scripts/ipadapter.py @@ -51,6 +51,7 @@ class Script(scripts.Script): starts = [] ends = [] files = [] + crops = [] masks = [] image_galleries = [] mask_galleries = [] @@ -61,6 +62,7 @@ class Script(scripts.Script): with gr.Row(): adapters.append(gr.Dropdown(label='Adapter', choices=list(ipadapter.ADAPTERS), value='None')) scales.append(gr.Slider(label='Scale', minimum=0.0, maximum=1.0, step=0.01, value=0.5)) + crops.append(gr.Checkbox(label='Crop', default=False, interactive=True)) with gr.Row(): starts.append(gr.Slider(label='Start', minimum=0.0, maximum=1.0, step=0.1, value=0)) ends.append(gr.Slider(label='End', minimum=0.0, maximum=1.0, step=0.1, value=1)) @@ -80,7 +82,7 @@ class Script(scripts.Script): layers_label = gr.HTML('InstantStyle: advanced layer activation', visible=False) layers = gr.Text(label='Layer scales', placeholder='{\n"down": {"block_2": [0.0, 1.0]},\n"up": {"block_0": [0.0, 1.0, 0.0]}\n}', rows=1, type='text', interactive=True, lines=5, visible=False, show_label=False) layers_active.change(fn=self.display_advanced, inputs=[layers_active], outputs=[layers_label, layers]) - return [num_adapters] + adapters + scales + files + starts + ends + masks + [layers_active] + [layers] + return [num_adapters] + adapters + scales + files + crops + starts + ends + masks + [layers_active] + [layers] def process(self, p: processing.StableDiffusionProcessing, *args): # pylint: disable=arguments-differ if not shared.native: @@ -95,14 +97,16 @@ class Script(scripts.Script): p.ip_adapter_scales = args[MAX_ADAPTERS:MAX_ADAPTERS*2][:units] if getattr(p, 'ip_adapter_images', []) == []: p.ip_adapter_images = args[MAX_ADAPTERS*2:MAX_ADAPTERS*3][:units] + if getattr(p, 'ip_adapter_crops', []) == []: + p.ip_adapter_crops = args[MAX_ADAPTERS*3:MAX_ADAPTERS*4][:units] if getattr(p, 'ip_adapter_starts', [0.0]) == [0.0]: - p.ip_adapter_starts = args[MAX_ADAPTERS*3:MAX_ADAPTERS*4][:units] + p.ip_adapter_starts = args[MAX_ADAPTERS*4:MAX_ADAPTERS*5][:units] if getattr(p, 'ip_adapter_ends', [1.0]) == [1.0]: - p.ip_adapter_ends = args[MAX_ADAPTERS*4:MAX_ADAPTERS*5][:units] + p.ip_adapter_ends = args[MAX_ADAPTERS*5:MAX_ADAPTERS*6][:units] if getattr(p, 'ip_adapter_masks', []) == []: - p.ip_adapter_masks = args[MAX_ADAPTERS*5:MAX_ADAPTERS*6][:units] + p.ip_adapter_masks = args[MAX_ADAPTERS*6:MAX_ADAPTERS*7][:units] p.ip_adapter_masks = [x for x in p.ip_adapter_masks if x] - layers_active, layers = args[MAX_ADAPTERS*6:MAX_ADAPTERS*7] + layers_active, layers = args[MAX_ADAPTERS*7:MAX_ADAPTERS*8] if layers_active and len(layers) > 0: try: layers = json.loads(layers)