mirror of
https://github.com/vladmandic/automatic
synced 2026-09-19 09:14:35 +02:00
ipadapter optional face autocrop input image
This commit is contained in:
@@ -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!
|
||||
|
||||
+2
-2
@@ -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)
|
||||
|
||||
+1
-1
@@ -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)
|
||||
|
||||
"""
|
||||
|
||||
Executable
+59
@@ -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)
|
||||
+1
-1
@@ -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)
|
||||
|
||||
+1
-1
@@ -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)
|
||||
|
||||
+1
-1
@@ -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()
|
||||
|
||||
+1
-1
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
|
||||
+1
-1
@@ -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)
|
||||
|
||||
+1
-1
@@ -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)
|
||||
|
||||
+1
-1
@@ -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)
|
||||
|
||||
+28
-20
@@ -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"
|
||||
},
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 58 KiB |
|
Before Width: | Height: | Size: 79 KiB After Width: | Height: | Size: 79 KiB |
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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])
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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:
|
||||
|
||||
+34
-2
@@ -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)
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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('<a href="https://huggingface.co/docs/diffusers/main/en/using-diffusers/ip_adapter#style--layout-control" target="_blank">InstantStyle: advanced layer activation</a>', 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)
|
||||
|
||||
Reference in New Issue
Block a user