diff --git a/analGapeCreampieLora_v3.safetensors b/analGapeCreampieLora_v3.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..d011d7feb0b0d279aacabb91ba1461e8806227b5
--- /dev/null
+++ b/analGapeCreampieLora_v3.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:aee78fef1e88080e0a8dc1d1d32dee0386cb7685d3bf3707f56b991fa7b234ed
+size 151121086
diff --git a/barbarianWoman_v10.safetensors b/barbarianWoman_v10.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..cdfeef1d02bdfd85edec72c8b5a04a2a16a27b10
--- /dev/null
+++ b/barbarianWoman_v10.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d363c6078e23f2c7cb30b36b75c5d2af811c7a1ea22b9aa4f8d33b8aa65dc547
+size 151113528
diff --git a/braBeautifulRealistic_brav3.safetensors b/braBeautifulRealistic_brav3.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..323d71d18fd57958ec36f329daca4f564d8306fc
--- /dev/null
+++ b/braBeautifulRealistic_brav3.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:6c646be99050f3a7337748c7d5078649b016b849c1d0c6339bce8e35ed0ab11c
+size 2132625918
diff --git a/bukkakAI.pt b/bukkakAI.pt
new file mode 100644
index 0000000000000000000000000000000000000000..4c7f02f0511626a98cd8d768c4f8479f92dd7b6e
--- /dev/null
+++ b/bukkakAI.pt
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:e8ae6ae855ebc1b0fdefc5263a61fc35331ac4f57cbd4e3ac165f2706edf7603
+size 10155
diff --git a/creampieHairyPussy_creampieV11.safetensors b/creampieHairyPussy_creampieV11.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..c7049ecf3530bd6aa41567d045c9ca498b86afd6
--- /dev/null
+++ b/creampieHairyPussy_creampieV11.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:826d251c22ebad508061ed14bf016e90b7461dcbbc07aba734466251e3ed061f
+size 37861700
diff --git a/ddetailer.py b/ddetailer.py
new file mode 100644
index 0000000000000000000000000000000000000000..54970f53b322ebead8931bbe97b1f2351051e7b6
--- /dev/null
+++ b/ddetailer.py
@@ -0,0 +1,542 @@
+import os
+import sys
+import cv2
+from PIL import Image
+import numpy as np
+import gradio as gr
+
+from modules import processing, images
+from modules import scripts, script_callbacks, shared, devices, modelloader
+from modules.processing import Processed, StableDiffusionProcessingTxt2Img, StableDiffusionProcessingImg2Img
+from modules.shared import opts, cmd_opts, state
+from modules.sd_models import model_hash
+from modules.paths import models_path
+from basicsr.utils.download_util import load_file_from_url
+
+dd_models_path = os.path.join(models_path, "mmdet")
+
+def list_models(model_path):
+ model_list = modelloader.load_models(model_path=model_path, ext_filter=[".pth"])
+
+ def modeltitle(path, shorthash):
+ abspath = os.path.abspath(path)
+
+ if abspath.startswith(model_path):
+ name = abspath.replace(model_path, '')
+ else:
+ name = os.path.basename(path)
+
+ if name.startswith("\\") or name.startswith("/"):
+ name = name[1:]
+
+ shortname = os.path.splitext(name.replace("/", "_").replace("\\", "_"))[0]
+
+ return f'{name} [{shorthash}]', shortname
+
+ models = []
+ for filename in model_list:
+ h = model_hash(filename)
+ title, short_model_name = modeltitle(filename, h)
+ models.append(title)
+
+ return models
+
+def startup():
+ from launch import is_installed, run
+ if not is_installed("mmdet"):
+ python = sys.executable
+ run(f'"{python}" -m pip install -U openmim==0.3.7', desc="Installing openmim", errdesc="Couldn't install openmim")
+ run(f'"{python}" -m mim install mmcv-full==1.7.1', desc=f"Installing mmcv-full", errdesc=f"Couldn't install mmcv-full")
+ run(f'"{python}" -m pip install mmdet==2.28.2', desc=f"Installing mmdet", errdesc=f"Couldn't install mmdet")
+
+ if (len(list_models(dd_models_path)) == 0):
+ print("No detection models found, downloading...")
+ bbox_path = os.path.join(dd_models_path, "bbox")
+ segm_path = os.path.join(dd_models_path, "segm")
+ load_file_from_url("https://huggingface.co/dustysys/ddetailer/resolve/main/mmdet/bbox/mmdet_anime-face_yolov3.pth", bbox_path)
+ load_file_from_url("https://huggingface.co/dustysys/ddetailer/raw/main/mmdet/bbox/mmdet_anime-face_yolov3.py", bbox_path)
+ load_file_from_url("https://huggingface.co/dustysys/ddetailer/resolve/main/mmdet/segm/mmdet_dd-person_mask2former.pth", segm_path)
+ load_file_from_url("https://huggingface.co/dustysys/ddetailer/raw/main/mmdet/segm/mmdet_dd-person_mask2former.py", segm_path)
+
+startup()
+
+def gr_show(visible=True):
+ return {"visible": visible, "__type__": "update"}
+
+class DetectionDetailerScript(scripts.Script):
+ def title(self):
+ return "Detection Detailer"
+
+ def show(self, is_img2img):
+ return True
+
+ def ui(self, is_img2img):
+ import modules.ui
+
+ model_list = list_models(dd_models_path)
+ model_list.insert(0, "None")
+ if is_img2img:
+ info = gr.HTML("
Recommended settings: Use from inpaint tab, inpaint at full res ON, denoise <0.5
")
+ else:
+ info = gr.HTML("")
+ with gr.Group():
+ with gr.Row():
+ dd_model_a = gr.Dropdown(label="Primary detection model (A)", choices=model_list,value = "None", visible=True, type="value")
+
+ with gr.Row():
+ dd_conf_a = gr.Slider(label='Detection confidence threshold % (A)', minimum=0, maximum=100, step=1, value=30, visible=False)
+ dd_dilation_factor_a = gr.Slider(label='Dilation factor (A)', minimum=0, maximum=255, step=1, value=4, visible=False)
+
+ with gr.Row():
+ dd_offset_x_a = gr.Slider(label='X offset (A)', minimum=-200, maximum=200, step=1, value=0, visible=False)
+ dd_offset_y_a = gr.Slider(label='Y offset (A)', minimum=-200, maximum=200, step=1, value=0, visible=False)
+
+ with gr.Row():
+ dd_preprocess_b = gr.Checkbox(label='Inpaint model B detections before model A runs', value=False, visible=False)
+ dd_bitwise_op = gr.Radio(label='Bitwise operation', choices=['None', 'A&B', 'A-B'], value="None", visible=False)
+
+ br = gr.HTML("
")
+
+ with gr.Group():
+ with gr.Row():
+ dd_model_b = gr.Dropdown(label="Secondary detection model (B) (optional)", choices=model_list,value = "None", visible =False, type="value")
+
+ with gr.Row():
+ dd_conf_b = gr.Slider(label='Detection confidence threshold % (B)', minimum=0, maximum=100, step=1, value=30, visible=False)
+ dd_dilation_factor_b = gr.Slider(label='Dilation factor (B)', minimum=0, maximum=255, step=1, value=4, visible=False)
+
+ with gr.Row():
+ dd_offset_x_b = gr.Slider(label='X offset (B)', minimum=-200, maximum=200, step=1, value=0, visible=False)
+ dd_offset_y_b = gr.Slider(label='Y offset (B)', minimum=-200, maximum=200, step=1, value=0, visible=False)
+
+ with gr.Group():
+ with gr.Row():
+ dd_mask_blur = gr.Slider(label='Mask blur ', minimum=0, maximum=64, step=1, value=4, visible=(not is_img2img))
+ dd_denoising_strength = gr.Slider(label='Denoising strength (Inpaint)', minimum=0.0, maximum=1.0, step=0.01, value=0.4, visible=(not is_img2img))
+
+ with gr.Row():
+ dd_inpaint_full_res = gr.Checkbox(label='Inpaint at full resolution ', value=True, visible = (not is_img2img))
+ dd_inpaint_full_res_padding = gr.Slider(label='Inpaint at full resolution padding, pixels ', minimum=0, maximum=256, step=4, value=32, visible=(not is_img2img))
+
+ with gr.Row():
+ dd_mimic_cfg = gr.Slider(label='Mimic CFG Scale', minimum=0, maximum=30, step=0.5, value=7, visible=True)
+
+ dd_model_a.change(
+ lambda modelname: {
+ dd_model_b:gr_show( modelname != "None" ),
+ dd_conf_a:gr_show( modelname != "None" ),
+ dd_dilation_factor_a:gr_show( modelname != "None"),
+ dd_offset_x_a:gr_show( modelname != "None" ),
+ dd_offset_y_a:gr_show( modelname != "None" )
+
+ },
+ inputs= [dd_model_a],
+ outputs =[dd_model_b, dd_conf_a, dd_dilation_factor_a, dd_offset_x_a, dd_offset_y_a]
+ )
+
+ dd_model_b.change(
+ lambda modelname: {
+ dd_preprocess_b:gr_show( modelname != "None" ),
+ dd_bitwise_op:gr_show( modelname != "None" ),
+ dd_conf_b:gr_show( modelname != "None" ),
+ dd_dilation_factor_b:gr_show( modelname != "None"),
+ dd_offset_x_b:gr_show( modelname != "None" ),
+ dd_offset_y_b:gr_show( modelname != "None" )
+ },
+ inputs= [dd_model_b],
+ outputs =[dd_preprocess_b, dd_bitwise_op, dd_conf_b, dd_dilation_factor_b, dd_offset_x_b, dd_offset_y_b]
+ )
+
+ return [info,
+ dd_model_a,
+ dd_conf_a, dd_dilation_factor_a,
+ dd_offset_x_a, dd_offset_y_a,
+ dd_preprocess_b, dd_bitwise_op,
+ br,
+ dd_model_b,
+ dd_conf_b, dd_dilation_factor_b,
+ dd_offset_x_b, dd_offset_y_b,
+ dd_mask_blur, dd_denoising_strength,
+ dd_inpaint_full_res, dd_inpaint_full_res_padding,
+ dd_mimic_cfg
+ ]
+
+ def run(self, p, info,
+ dd_model_a,
+ dd_conf_a, dd_dilation_factor_a,
+ dd_offset_x_a, dd_offset_y_a,
+ dd_preprocess_b, dd_bitwise_op,
+ br,
+ dd_model_b,
+ dd_conf_b, dd_dilation_factor_b,
+ dd_offset_x_b, dd_offset_y_b,
+ dd_mask_blur, dd_denoising_strength,
+ dd_inpaint_full_res, dd_inpaint_full_res_padding,
+ dd_mimic_cfg):
+
+ processing.fix_seed(p)
+ initial_info = None
+ seed = p.seed
+ p.batch_size = 1
+ ddetail_count = p.n_iter
+ p.n_iter = 1
+ p.do_not_save_grid = True
+ p.do_not_save_samples = True
+ is_txt2img = isinstance(p, StableDiffusionProcessingTxt2Img)
+ if (not is_txt2img):
+ orig_image = p.init_images[0]
+ else:
+ p_txt = p
+ print(f"mimic_scale = {dd_mimic_cfg}")
+ p = StableDiffusionProcessingImg2Img(
+ init_images = None,
+ resize_mode = 0,
+ denoising_strength = dd_denoising_strength,
+ mask = None,
+ mask_blur= dd_mask_blur,
+ inpainting_fill = 1,
+ inpaint_full_res = dd_inpaint_full_res,
+ inpaint_full_res_padding= dd_inpaint_full_res_padding,
+ inpainting_mask_invert= 0,
+ sd_model=p_txt.sd_model,
+ outpath_samples=p_txt.outpath_samples,
+ outpath_grids=p_txt.outpath_grids,
+ prompt=p_txt.prompt,
+ negative_prompt=p_txt.negative_prompt,
+ styles=p_txt.styles,
+ seed=p_txt.seed,
+ subseed=p_txt.subseed,
+ subseed_strength=p_txt.subseed_strength,
+ seed_resize_from_h=p_txt.seed_resize_from_h,
+ seed_resize_from_w=p_txt.seed_resize_from_w,
+ sampler_name=p_txt.sampler_name,
+ n_iter=p_txt.n_iter,
+ steps=p_txt.steps,
+ cfg_scale=dd_mimic_cfg,
+ width=p_txt.width,
+ height=p_txt.height,
+ tiling=p_txt.tiling,
+ )
+ p.do_not_save_grid = True
+ p.do_not_save_samples = True
+ output_images = []
+ state.job_count = ddetail_count
+ for n in range(ddetail_count):
+ devices.torch_gc()
+ start_seed = seed + n
+ if ( is_txt2img ):
+ print(f"Processing initial image for output generation {n + 1}.")
+ p_txt.seed = start_seed
+ processed = processing.process_images(p_txt)
+ init_image = processed.images[0]
+ else:
+ init_image = orig_image
+
+ output_images.append(init_image)
+ masks_a = []
+ masks_b_pre = []
+
+ # Optional secondary pre-processing run
+ if (dd_model_b != "None" and dd_preprocess_b):
+ label_b_pre = "B"
+ results_b_pre = inference(init_image, dd_model_b, dd_conf_b/100.0, label_b_pre)
+ masks_b_pre = create_segmasks(results_b_pre)
+ masks_b_pre = dilate_masks(masks_b_pre, dd_dilation_factor_b, 1)
+ masks_b_pre = offset_masks(masks_b_pre,dd_offset_x_b, dd_offset_y_b)
+ if (len(masks_b_pre) > 0):
+ results_b_pre = update_result_masks(results_b_pre, masks_b_pre)
+ segmask_preview_b = create_segmask_preview(results_b_pre, init_image)
+ shared.state.current_image = segmask_preview_b
+ if ( opts.dd_save_previews):
+ images.save_image(segmask_preview_b, opts.outdir_ddetailer_previews, "", start_seed, p.prompt, opts.samples_format, p=p)
+ gen_count = len(masks_b_pre)
+ state.job_count += gen_count
+ print(f"Processing {gen_count} model {label_b_pre} detections for output generation {n + 1}.")
+ p.seed = start_seed
+ p.init_images = [init_image]
+
+ for i in range(gen_count):
+ p.image_mask = masks_b_pre[i]
+ if ( opts.dd_save_masks):
+ images.save_image(masks_b_pre[i], opts.outdir_ddetailer_masks, "", start_seed, p.prompt, opts.samples_format, p=p)
+ processed = processing.process_images(p)
+ p.seed = processed.seed + 1
+ p.init_images = processed.images
+
+ if (gen_count > 0):
+ output_images[n] = processed.images[0]
+ init_image = processed.images[0]
+
+ else:
+ print(f"No model B detections for output generation {n} with current settings.")
+
+ # Primary run
+ if (dd_model_a != "None"):
+ label_a = "A"
+ if (dd_model_b != "None" and dd_bitwise_op != "None"):
+ label_a = dd_bitwise_op
+ results_a = inference(init_image, dd_model_a, dd_conf_a/100.0, label_a)
+ masks_a = create_segmasks(results_a)
+ masks_a = dilate_masks(masks_a, dd_dilation_factor_a, 1)
+ masks_a = offset_masks(masks_a,dd_offset_x_a, dd_offset_y_a)
+ if (dd_model_b != "None" and dd_bitwise_op != "None"):
+ label_b = "B"
+ results_b = inference(init_image, dd_model_b, dd_conf_b/100.0, label_b)
+ masks_b = create_segmasks(results_b)
+ masks_b = dilate_masks(masks_b, dd_dilation_factor_b, 1)
+ masks_b = offset_masks(masks_b,dd_offset_x_b, dd_offset_y_b)
+ if (len(masks_b) > 0):
+ combined_mask_b = combine_masks(masks_b)
+ for i in reversed(range(len(masks_a))):
+ if (dd_bitwise_op == "A&B"):
+ masks_a[i] = bitwise_and_masks(masks_a[i], combined_mask_b)
+ elif (dd_bitwise_op == "A-B"):
+ masks_a[i] = subtract_masks(masks_a[i], combined_mask_b)
+ if (is_allblack(masks_a[i])):
+ del masks_a[i]
+ for result in results_a:
+ del result[i]
+
+ else:
+ print("No model B detections to overlap with model A masks")
+ results_a = []
+ masks_a = []
+
+ if (len(masks_a) > 0):
+ results_a = update_result_masks(results_a, masks_a)
+ segmask_preview_a = create_segmask_preview(results_a, init_image)
+ shared.state.current_image = segmask_preview_a
+ if ( opts.dd_save_previews):
+ images.save_image(segmask_preview_a, opts.outdir_ddetailer_previews, "", start_seed, p.prompt, opts.samples_format, p=p)
+ gen_count = len(masks_a)
+ state.job_count += gen_count
+ print(f"Processing {gen_count} model {label_a} detections for output generation {n + 1}.")
+ p.seed = start_seed
+ p.init_images = [init_image]
+
+ for i in range(gen_count):
+ p.image_mask = masks_a[i]
+ if ( opts.dd_save_masks):
+ images.save_image(masks_a[i], opts.outdir_ddetailer_masks, "", start_seed, p.prompt, opts.samples_format, p=p)
+
+ processed = processing.process_images(p)
+ if initial_info is None:
+ initial_info = processed.info
+ p.seed = processed.seed + 1
+ p.init_images = processed.images
+
+ if (gen_count > 0):
+ output_images[n] = processed.images[0]
+ if ( opts.samples_save ):
+ images.save_image(processed.images[0], p.outpath_samples, "", start_seed, p.prompt, opts.samples_format, info=initial_info, p=p)
+
+ else:
+ print(f"No model {label_a} detections for output generation {n} with current settings.")
+ state.job = f"Generation {n + 1} out of {state.job_count}"
+ if (initial_info is None):
+ initial_info = "No detections found."
+
+ return Processed(p, output_images, seed, initial_info)
+
+def modeldataset(model_shortname):
+ path = modelpath(model_shortname)
+ if ("mmdet" in path and "segm" in path):
+ dataset = 'coco'
+ else:
+ dataset = 'bbox'
+ return dataset
+
+def modelpath(model_shortname):
+ model_list = modelloader.load_models(model_path=dd_models_path, ext_filter=[".pth"])
+ model_h = model_shortname.split("[")[-1].split("]")[0]
+ for path in model_list:
+ if ( model_hash(path) == model_h):
+ return path
+
+def update_result_masks(results, masks):
+ for i in range(len(masks)):
+ boolmask = np.array(masks[i], dtype=bool)
+ results[2][i] = boolmask
+ return results
+
+def create_segmask_preview(results, image):
+ labels = results[0]
+ bboxes = results[1]
+ segms = results[2]
+
+ cv2_image = np.array(image)
+ cv2_image = cv2_image[:, :, ::-1].copy()
+
+ for i in range(len(segms)):
+ color = np.full_like(cv2_image, np.random.randint(100, 256, (1, 3), dtype=np.uint8))
+ alpha = 0.2
+ color_image = cv2.addWeighted(cv2_image, alpha, color, 1-alpha, 0)
+ cv2_mask = segms[i].astype(np.uint8) * 255
+ cv2_mask_bool = np.array(segms[i], dtype=bool)
+ centroid = np.mean(np.argwhere(cv2_mask_bool),axis=0)
+ centroid_x, centroid_y = int(centroid[1]), int(centroid[0])
+
+ cv2_mask_rgb = cv2.merge((cv2_mask, cv2_mask, cv2_mask))
+ cv2_image = np.where(cv2_mask_rgb == 255, color_image, cv2_image)
+ text_color = tuple([int(x) for x in ( color[0][0] - 100 )])
+ name = labels[i]
+ score = bboxes[i][4]
+ score = str(score)[:4]
+ text = name + ":" + score
+ cv2.putText(cv2_image, text, (centroid_x - 30, centroid_y), cv2.FONT_HERSHEY_DUPLEX, 0.4, text_color, 1, cv2.LINE_AA)
+
+ if ( len(segms) > 0):
+ preview_image = Image.fromarray(cv2.cvtColor(cv2_image, cv2.COLOR_BGR2RGB))
+ else:
+ preview_image = image
+
+ return preview_image
+
+def is_allblack(mask):
+ cv2_mask = np.array(mask)
+ return cv2.countNonZero(cv2_mask) == 0
+
+def bitwise_and_masks(mask1, mask2):
+ cv2_mask1 = np.array(mask1)
+ cv2_mask2 = np.array(mask2)
+ cv2_mask = cv2.bitwise_and(cv2_mask1, cv2_mask2)
+ mask = Image.fromarray(cv2_mask)
+ return mask
+
+def subtract_masks(mask1, mask2):
+ cv2_mask1 = np.array(mask1)
+ cv2_mask2 = np.array(mask2)
+ cv2_mask = cv2.subtract(cv2_mask1, cv2_mask2)
+ mask = Image.fromarray(cv2_mask)
+ return mask
+
+def dilate_masks(masks, dilation_factor, iter=1):
+ if dilation_factor == 0:
+ return masks
+ dilated_masks = []
+ kernel = np.ones((dilation_factor,dilation_factor), np.uint8)
+ for i in range(len(masks)):
+ cv2_mask = np.array(masks[i])
+ dilated_mask = cv2.dilate(cv2_mask, kernel, iter)
+ dilated_masks.append(Image.fromarray(dilated_mask))
+ return dilated_masks
+
+def offset_masks(masks, offset_x, offset_y):
+ if (offset_x == 0 and offset_y == 0):
+ return masks
+ offset_masks = []
+ for i in range(len(masks)):
+ cv2_mask = np.array(masks[i])
+ offset_mask = cv2_mask.copy()
+ offset_mask = np.roll(offset_mask, -offset_y, axis=0)
+ offset_mask = np.roll(offset_mask, offset_x, axis=1)
+
+ offset_masks.append(Image.fromarray(offset_mask))
+ return offset_masks
+
+def combine_masks(masks):
+ initial_cv2_mask = np.array(masks[0])
+ combined_cv2_mask = initial_cv2_mask
+ for i in range(1, len(masks)):
+ cv2_mask = np.array(masks[i])
+ combined_cv2_mask = cv2.bitwise_or(combined_cv2_mask, cv2_mask)
+
+ combined_mask = Image.fromarray(combined_cv2_mask)
+ return combined_mask
+
+def on_ui_settings():
+ shared.opts.add_option("dd_save_previews", shared.OptionInfo(False, "Save mask previews", section=("ddetailer", "Detection Detailer")))
+ shared.opts.add_option("outdir_ddetailer_previews", shared.OptionInfo("extensions/ddetailer/outputs/masks-previews", 'Output directory for mask previews', section=("ddetailer", "Detection Detailer")))
+ shared.opts.add_option("dd_save_masks", shared.OptionInfo(False, "Save masks", section=("ddetailer", "Detection Detailer")))
+ shared.opts.add_option("outdir_ddetailer_masks", shared.OptionInfo("extensions/ddetailer/outputs/masks", 'Output directory for masks', section=("ddetailer", "Detection Detailer")))
+
+def create_segmasks(results):
+ segms = results[2]
+ segmasks = []
+ for i in range(len(segms)):
+ cv2_mask = segms[i].astype(np.uint8) * 255
+ mask = Image.fromarray(cv2_mask)
+ segmasks.append(mask)
+
+ return segmasks
+
+import mmcv
+from mmdet.core import get_classes
+from mmdet.apis import (inference_detector,
+ init_detector)
+
+def get_device():
+ device_id = shared.cmd_opts.device_id
+ if device_id is not None:
+ cuda_device = f"cuda:{device_id}"
+ else:
+ cuda_device = "cpu"
+ return cuda_device
+
+def inference(image, modelname, conf_thres, label):
+ path = modelpath(modelname)
+ if ( "mmdet" in path and "bbox" in path ):
+ results = inference_mmdet_bbox(image, modelname, conf_thres, label)
+ elif ( "mmdet" in path and "segm" in path):
+ results = inference_mmdet_segm(image, modelname, conf_thres, label)
+ return results
+
+def inference_mmdet_segm(image, modelname, conf_thres, label):
+ model_checkpoint = modelpath(modelname)
+ model_config = os.path.splitext(model_checkpoint)[0] + ".py"
+ model_device = get_device()
+ model = init_detector(model_config, model_checkpoint, device=model_device)
+ mmdet_results = inference_detector(model, np.array(image))
+ bbox_results, segm_results = mmdet_results
+ dataset = modeldataset(modelname)
+ classes = get_classes(dataset)
+ labels = [
+ np.full(bbox.shape[0], i, dtype=np.int32)
+ for i, bbox in enumerate(bbox_results)
+ ]
+ n,m = bbox_results[0].shape
+ if (n == 0):
+ return [[],[],[]]
+ labels = np.concatenate(labels)
+ bboxes = np.vstack(bbox_results)
+ segms = mmcv.concat_list(segm_results)
+ filter_inds = np.where(bboxes[:,-1] > conf_thres)[0]
+ results = [[],[],[]]
+ for i in filter_inds:
+ results[0].append(label + "-" + classes[labels[i]])
+ results[1].append(bboxes[i])
+ results[2].append(segms[i])
+
+ return results
+
+def inference_mmdet_bbox(image, modelname, conf_thres, label):
+ model_checkpoint = modelpath(modelname)
+ model_config = os.path.splitext(model_checkpoint)[0] + ".py"
+ model_device = get_device()
+ model = init_detector(model_config, model_checkpoint, device=model_device)
+ results = inference_detector(model, np.array(image))
+ cv2_image = np.array(image)
+ cv2_image = cv2_image[:, :, ::-1].copy()
+ cv2_gray = cv2.cvtColor(cv2_image, cv2.COLOR_BGR2GRAY)
+
+ segms = []
+ for (x0, y0, x1, y1, conf) in results[0]:
+ cv2_mask = np.zeros((cv2_gray.shape), np.uint8)
+ cv2.rectangle(cv2_mask, (int(x0), int(y0)), (int(x1), int(y1)), 255, -1)
+ cv2_mask_bool = cv2_mask.astype(bool)
+ segms.append(cv2_mask_bool)
+
+ n,m = results[0].shape
+ if (n == 0):
+ return [[],[],[]]
+ bboxes = np.vstack(results[0])
+ filter_inds = np.where(bboxes[:,-1] > conf_thres)[0]
+ results = [[],[],[]]
+ for i in filter_inds:
+ results[0].append(label)
+ results[1].append(bboxes[i])
+ results[2].append(segms[i])
+
+ return results
+
+script_callbacks.on_ui_settings(on_ui_settings)
diff --git a/ddsd.py b/ddsd.py
new file mode 100644
index 0000000000000000000000000000000000000000..ce90e61790e3e2ce355c197ea5d7e9bf3c20bc38
--- /dev/null
+++ b/ddsd.py
@@ -0,0 +1,604 @@
+import os
+import sys
+import cv2
+import math
+import copy
+
+import modules.scripts as scripts
+import gradio as gr
+import numpy as np
+from PIL import Image
+
+from modules import processing, shared, sd_samplers, images, devices, scripts, script_callbacks, modelloader
+from modules.processing import Processed, process_images, fix_seed, StableDiffusionProcessingImg2Img, StableDiffusionProcessingTxt2Img
+from modules.shared import opts, cmd_opts, state
+
+from modules.sd_models import model_hash
+from modules.paths import models_path
+from basicsr.utils.download_util import load_file_from_url
+
+dd_models_path = os.path.join(models_path, "mmdet")
+
+
+def list_models(model_path):
+ model_list = modelloader.load_models(model_path=model_path, ext_filter=[".pth"])
+
+ def modeltitle(path, shorthash):
+ abspath = os.path.abspath(path)
+
+ if abspath.startswith(model_path):
+ name = abspath.replace(model_path, '')
+ else:
+ name = os.path.basename(path)
+
+ if name.startswith("\\") or name.startswith("/"):
+ name = name[1:]
+
+ shortname = os.path.splitext(name.replace("/", "_").replace("\\", "_"))[0]
+
+ return f'{name} [{shorthash}]', shortname
+
+ models = []
+ for filename in model_list:
+ h = model_hash(filename)
+ title, short_model_name = modeltitle(filename, h)
+ models.append(title)
+
+ return models
+
+def startup():
+ from launch import is_installed, run
+ if not is_installed("mmdet"):
+ python = sys.executable
+ run(f'"{python}" -m pip install -U openmim==0.3.7', desc="Installing openmim", errdesc="Couldn't install openmim")
+ run(f'"{python}" -m mim install mmcv-full==1.7.1', desc=f"Installing mmcv-full", errdesc=f"Couldn't install mmcv-full")
+ run(f'"{python}" -m pip install mmdet==2.28.2', desc=f"Installing mmdet", errdesc=f"Couldn't install mmdet")
+
+ if (len(list_models(dd_models_path)) == 0):
+ print("No detection models found, downloading...")
+ bbox_path = os.path.join(dd_models_path, "bbox")
+ segm_path = os.path.join(dd_models_path, "segm")
+ load_file_from_url("https://huggingface.co/dustysys/ddetailer/resolve/main/mmdet/bbox/mmdet_anime-face_yolov3.pth", bbox_path)
+ load_file_from_url("https://huggingface.co/dustysys/ddetailer/raw/main/mmdet/bbox/mmdet_anime-face_yolov3.py", bbox_path)
+ load_file_from_url("https://huggingface.co/dustysys/ddetailer/resolve/main/mmdet/segm/mmdet_dd-person_mask2former.pth", segm_path)
+ load_file_from_url("https://huggingface.co/dustysys/ddetailer/raw/main/mmdet/segm/mmdet_dd-person_mask2former.py", segm_path)
+
+startup()
+
+def gr_show(visible=True):
+ return {"visible": visible, "__type__": "update"}
+
+class Script(scripts.Script):
+ def title(self):
+ return "ddetailer + sdupscale"
+
+ def show(self, is_img2img):
+ return not is_img2img
+
+ def ui(self, is_img2img):
+ import modules.ui
+
+ sample_list = [x.name for x in shared.list_samplers()]
+ sample_list.remove('PLMS')
+ sample_list.remove('UniPC')
+ sample_list.remove('DDIM')
+ sample_list.insert(0,"Original")
+ model_list = list_models(dd_models_path)
+ model_list.insert(0, "None")
+
+ enable_script_names = gr.Textbox(label="Enable Script(Extension)", elem_id="t2i_dd_prompt", value='dynamic_thresholding;dynamic_prompting',show_label=True, lines=1, placeholder="Extension python file name(ex - dynamic_thresholding;dynamic_prompting)")
+ scalevalue = gr.Slider(minimum=1, maximum=16, step=0.5, label='Resize', value=2)
+ overlap = gr.Slider(minimum=0, maximum=256, step=32, label='Tile overlap', value=32)
+ rewidth = gr.Slider(minimum=0, maximum=1024, step=64, label='Width', value=512)
+ reheight = gr.Slider(minimum=0, maximum=1024, step=64, label='Height', value=512)
+ upscaler_index = gr.Radio(label='Upscaler', choices=[x.name for x in shared.sd_upscalers], value='R-ESRGAN 4x+ Anime6B', type="index")
+ denoising_strength = gr.Slider(minimum=0, maximum=1.0, step=0.01, label='Denoising strength', value=0)
+ upscaler_sample = gr.Dropdown(label='Upscaler Sampling', choices=sample_list, value=sample_list[0], visible=True, type="value")
+ detailer_sample = gr.Dropdown(label='Detailer Sampling', choices=sample_list, value=sample_list[0], visible=True, type="value")
+
+
+ ret = [enable_script_names, scalevalue, upscaler_sample, detailer_sample, overlap, upscaler_index, rewidth, reheight, denoising_strength]
+
+ with gr.Group():
+ if not is_img2img:
+ with gr.Row():
+ dd_prompt = gr.Textbox(label="dd_prompt", elem_id="t2i_dd_prompt", show_label=False, lines=3, placeholder="Ddetailer Prompt")
+
+ with gr.Row():
+ dd_neg_prompt = gr.Textbox(label="dd_neg_prompt", elem_id="t2i_dd_neg_prompt", show_label=False, lines=2, placeholder="Ddetailer Negative prompt")
+
+ with gr.Row():
+ dd_model_a = gr.Dropdown(label="Primary detection model (A)", choices=model_list,value = model_list[2], visible=True, type="value")
+
+ with gr.Row():
+ dd_conf_a = gr.Slider(label='Detection confidence threshold % (A)', minimum=0, maximum=100, step=1, value=30, visible=True)
+ dd_dilation_factor_a = gr.Slider(label='Dilation factor (A)', minimum=0, maximum=255, step=1, value=20, visible=True)
+
+ with gr.Row():
+ dd_offset_x_a = gr.Slider(label='X offset (A)', minimum=-200, maximum=200, step=1, value=0, visible=True)
+ dd_offset_y_a = gr.Slider(label='Y offset (A)', minimum=-200, maximum=200, step=1, value=0, visible=True)
+
+ with gr.Row():
+ dd_bitwise_op = gr.Radio(label='Bitwise operation', choices=['None', 'A&B', 'A-B'], value="A&B", visible=True)
+
+ br = gr.HTML("
")
+
+ with gr.Group():
+ with gr.Row():
+ dd_model_b = gr.Dropdown(label="Secondary detection model (B) (optional)", choices=model_list,value = model_list[1], visible =True, type="value")
+
+ with gr.Row():
+ dd_conf_b = gr.Slider(label='Detection confidence threshold % (B)', minimum=0, maximum=100, step=1, value=30, visible=True)
+ dd_dilation_factor_b = gr.Slider(label='Dilation factor (B)', minimum=0, maximum=255, step=1, value=10, visible=True)
+
+ with gr.Row():
+ dd_offset_x_b = gr.Slider(label='X offset (B)', minimum=-200, maximum=200, step=1, value=0, visible=True)
+ dd_offset_y_b = gr.Slider(label='Y offset (B)', minimum=-200, maximum=200, step=1, value=0, visible=True)
+
+ with gr.Group():
+ with gr.Row():
+ dd_mask_blur = gr.Slider(label='Mask blur ', minimum=0, maximum=64, step=1, value=4, visible=(not is_img2img))
+ dd_denoising_strength = gr.Slider(label='Denoising strength (Inpaint)', minimum=0.0, maximum=1.0, step=0.01, value=0.4, visible=(not is_img2img))
+
+ with gr.Row():
+ dd_inpaint_full_res = gr.Checkbox(label='Inpaint at full resolution ', value=True, visible = (not is_img2img))
+ dd_inpaint_full_res_padding = gr.Slider(label='Inpaint at full resolution padding, pixels ', minimum=0, maximum=256, step=4, value=32, visible=(not is_img2img))
+
+ dd_model_a.change(
+ lambda modelname: {
+ dd_model_b:gr_show( modelname != "None" ),
+ dd_conf_a:gr_show( modelname != "None" ),
+ dd_dilation_factor_a:gr_show( modelname != "None"),
+ dd_offset_x_a:gr_show( modelname != "None" ),
+ dd_offset_y_a:gr_show( modelname != "None" )
+
+ },
+ inputs= [dd_model_a],
+ outputs =[dd_model_b, dd_conf_a, dd_dilation_factor_a, dd_offset_x_a, dd_offset_y_a]
+ )
+
+ dd_model_b.change(
+ lambda modelname: {
+ dd_bitwise_op:gr_show( modelname != "None" ),
+ dd_conf_b:gr_show( modelname != "None" ),
+ dd_dilation_factor_b:gr_show( modelname != "None"),
+ dd_offset_x_b:gr_show( modelname != "None" ),
+ dd_offset_y_b:gr_show( modelname != "None" )
+ },
+ inputs= [dd_model_b],
+ outputs =[dd_bitwise_op, dd_conf_b, dd_dilation_factor_b, dd_offset_x_b, dd_offset_y_b]
+ )
+
+ ret += [dd_model_a,
+ dd_conf_a, dd_dilation_factor_a,
+ dd_offset_x_a, dd_offset_y_a,
+ dd_bitwise_op,
+ br,
+ dd_model_b,
+ dd_conf_b, dd_dilation_factor_b,
+ dd_offset_x_b, dd_offset_y_b,
+ dd_mask_blur, dd_denoising_strength,
+ dd_inpaint_full_res, dd_inpaint_full_res_padding
+ ]
+ if not is_img2img:
+ ret += [dd_prompt, dd_neg_prompt]
+
+ return ret
+
+ def run(self, p, enable_script_names, scalevalue, upscaler_sample, detailer_sample, overlap, upscaler_index, rewidth, reheight, denoising_strength,
+ dd_model_a,
+ dd_conf_a, dd_dilation_factor_a,
+ dd_offset_x_a, dd_offset_y_a,
+ dd_bitwise_op,
+ br,
+ dd_model_b,
+ dd_conf_b, dd_dilation_factor_b,
+ dd_offset_x_b, dd_offset_y_b,
+ dd_mask_blur, dd_denoising_strength,
+ dd_inpaint_full_res, dd_inpaint_full_res_padding,
+ dd_prompt=None, dd_neg_prompt=None):
+ processing.fix_seed(p)
+ initial_info = []
+ initial_prompt = []
+ initial_negative = []
+ p.batch_size = 1
+ ddetail_count = p.n_iter
+ p.n_iter = 1
+ p.do_not_save_grid = True
+ p.do_not_save_samples = True
+ p_txt = p
+ i2i_sample = ''
+ if detailer_sample == 'Original':
+ i2i_sample = 'Euler' if p_txt.sampler_name in ['PLMS', 'UniPC', 'DDIM'] else p_txt.sampler_name
+ else:
+ i2i_sample = detailer_sample
+ p = StableDiffusionProcessingImg2Img(
+ init_images = None,
+ resize_mode = 0,
+ denoising_strength = dd_denoising_strength,
+ mask = None,
+ mask_blur= dd_mask_blur,
+ inpainting_fill = 1,
+ inpaint_full_res = dd_inpaint_full_res,
+ inpaint_full_res_padding= dd_inpaint_full_res_padding,
+ inpainting_mask_invert= 0,
+ sd_model=p_txt.sd_model,
+ outpath_samples=p_txt.outpath_samples,
+ outpath_grids=p_txt.outpath_grids,
+ prompt='',
+ negative_prompt='',
+ styles=p_txt.styles,
+ seed=p_txt.seed,
+ subseed=p_txt.subseed,
+ subseed_strength=p_txt.subseed_strength,
+ seed_resize_from_h=p_txt.seed_resize_from_h,
+ seed_resize_from_w=p_txt.seed_resize_from_w,
+ sampler_name=i2i_sample,
+ n_iter=p_txt.n_iter,
+ steps=p_txt.steps,
+ cfg_scale=p_txt.cfg_scale,
+ width=p_txt.width,
+ height=p_txt.height,
+ tiling=p_txt.tiling,
+ )
+ p.do_not_save_grid = True
+ p.do_not_save_samples = True
+ p.override_settings = {}
+
+ if upscaler_sample == 'Original':
+ i2i_sample = 'Euler' if p_txt.sampler_name in ['PLMS', 'UniPC', 'DDIM'] else p_txt.sampler_name
+ else:
+ i2i_sample = upscaler_sample
+ p2 = StableDiffusionProcessingImg2Img(
+ sd_model=p_txt.sd_model,
+ outpath_samples=p_txt.outpath_samples,
+ outpath_grids=p_txt.outpath_grids,
+ prompt='',
+ negative_prompt='',
+ styles=p_txt.styles,
+ seed=p_txt.seed,
+ subseed=p_txt.subseed,
+ subseed_strength=p_txt.subseed_strength,
+ seed_resize_from_h=p_txt.seed_resize_from_h,
+ seed_resize_from_w=p_txt.seed_resize_from_w,
+ seed_enable_extras=True,
+ sampler_name=i2i_sample,
+ batch_size=1,
+ n_iter=1,
+ steps=p_txt.steps,
+ cfg_scale=p_txt.cfg_scale,
+ width=rewidth,
+ height=reheight,
+ restore_faces=p_txt.restore_faces,
+ tiling=p_txt.tiling,
+ init_images=[],
+ mask=None,
+ mask_blur=dd_mask_blur,
+ inpainting_fill=1,
+ resize_mode=0,
+ denoising_strength=denoising_strength,
+ inpaint_full_res=dd_inpaint_full_res,
+ inpaint_full_res_padding=dd_inpaint_full_res_padding,
+ inpainting_mask_invert=0,
+ )
+ p2.do_not_save_grid = True
+ p2.do_not_save_samples = True
+ p2.override_settings = {}
+
+ upscaler = shared.sd_upscalers[upscaler_index]
+ script_names_list = [x.strip()+'.py' for x in enable_script_names.split(';') if len(x) > 1]
+ processing.fix_seed(p2)
+ seed = p_txt.seed
+
+ p_txt.scripts.scripts = [x for x in p_txt.scripts.scripts if os.path.basename(x.filename) not in [__file__]]
+ t2i_scripts = p_txt.scripts.scripts.copy()
+ i2i_scripts = [x for x in t2i_scripts if os.path.basename(x.filename) in script_names_list]
+ t2i_scripts_always = p_txt.scripts.alwayson_scripts.copy()
+ i2i_scripts_always = [x for x in t2i_scripts_always if os.path.basename(x.filename) in script_names_list]
+ p.scripts = p_txt.scripts
+ p.script_args = p_txt.script_args
+ p2.scripts = p_txt.scripts
+ p2.script_args = p_txt.script_args
+
+ p_txt.extra_generation_params["Tile upscale value"] = scalevalue
+ p_txt.extra_generation_params["Tile upscale width"] = rewidth
+ p_txt.extra_generation_params["Tile upscale height"] = reheight
+ p_txt.extra_generation_params["Tile upscale overlap"] = overlap
+ p_txt.extra_generation_params["Tile upscale upscaler"] = upscaler.name
+
+ print(f"DDetailer {p.width}x{p.height}.")
+
+ output_images = []
+ result_images = []
+ state.job_count += ddetail_count
+ for n in range(ddetail_count):
+ devices.torch_gc()
+ start_seed = seed + n
+ print(f"Processing initial image for output generation {n + 1} (T2I).")
+ p_txt.seed = start_seed
+ p_txt.scripts.scripts = t2i_scripts
+ p_txt.scripts.alwayson_scripts = t2i_scripts_always
+ processed = processing.process_images(p_txt)
+ initial_info.append(processed.info)
+ posi, nega = processed.all_prompts[0], processed.all_negative_prompts[0]
+ initial_prompt.append(posi)
+ initial_negative.append(nega)
+ p.prompt = posi if not dd_prompt else dd_prompt
+ p.negative_prompt = nega if not dd_neg_prompt else dd_neg_prompt
+ init_image = processed.images[0]
+
+ output_images.append(init_image)
+ masks_a = []
+
+ # Primary run
+ if (dd_model_a != "None"):
+ label_a = "A"
+ if (dd_model_b != "None" and dd_bitwise_op != "None"):
+ label_a = dd_bitwise_op
+ results_a = inference(init_image, dd_model_a, dd_conf_a/100.0, label_a)
+ masks_a = create_segmasks(results_a)
+ masks_a = dilate_masks(masks_a, dd_dilation_factor_a, 1)
+ masks_a = offset_masks(masks_a,dd_offset_x_a, dd_offset_y_a)
+ if (dd_model_b != "None" and dd_bitwise_op != "None"):
+ label_b = "B"
+ results_b = inference(init_image, dd_model_b, dd_conf_b/100.0, label_b)
+ masks_b = create_segmasks(results_b)
+ masks_b = dilate_masks(masks_b, dd_dilation_factor_b, 1)
+ masks_b = offset_masks(masks_b,dd_offset_x_b, dd_offset_y_b)
+ if (len(masks_b) > 0):
+ combined_mask_b = combine_masks(masks_b)
+ for i in reversed(range(len(masks_a))):
+ if (dd_bitwise_op == "A&B"):
+ masks_a[i] = bitwise_and_masks(masks_a[i], combined_mask_b)
+ elif (dd_bitwise_op == "A-B"):
+ masks_a[i] = subtract_masks(masks_a[i], combined_mask_b)
+ if (is_allblack(masks_a[i])):
+ del masks_a[i]
+ for result in results_a:
+ del result[i]
+
+ else:
+ print("No model B detections to overlap with model A masks")
+ results_a = []
+ masks_a = []
+
+ if (len(masks_a) > 0):
+ results_a = update_result_masks(results_a, masks_a)
+ gen_count = len(masks_a)
+ state.job_count += gen_count
+ print(f"Processing {gen_count} model {label_a} detections for output generation {n + 1} (I2I).")
+ p.seed = start_seed
+ p.init_images = [init_image]
+
+ for i in range(gen_count):
+ p.image_mask = masks_a[i]
+
+ p.scripts.scripts = i2i_scripts
+ p.scripts.alwayson_scripts = i2i_scripts_always
+ processed = processing.process_images(p)
+ p.seed = processed.seed + 1
+ p.init_images = processed.images
+
+ if (gen_count > 0):
+ output_images[n] = processed.images[0]
+
+ else:
+ print(f"No model {label_a} detections for output generation {n} with current settings.")
+
+ state.job = f"Generation {n + 1} out of {state.job_count} DDetailer"
+
+ p2.init_images = [output_images[n]]
+ p2.prompt = initial_prompt[n]
+ p2.negative_prompt = initial_negative[n]
+
+ init_img = output_images[n]
+
+ if(upscaler.name != "None"):
+ img = upscaler.scaler.upscale(init_img, scalevalue, upscaler.data_path)
+ else:
+ img = init_img
+
+ devices.torch_gc()
+
+ grid = images.split_grid(img, tile_w=rewidth, tile_h=reheight, overlap=overlap)
+
+ batch_size = p2.batch_size
+
+ work = []
+
+ for y, h, row in grid.tiles:
+ for tiledata in row:
+ work.append(tiledata[2])
+
+ batch_count = math.ceil(len(work) / batch_size)
+ state.job_count += batch_count
+
+ print(f"Tile upscaling will process a total of {len(work)} images tiled as {len(grid.tiles[0][2])}x{len(grid.tiles)} per upscale in a total of {state.job_count} batches (I2I).")
+
+ p2.seed = start_seed
+
+ work_results = []
+ for i in range(batch_count):
+ p2.batch_size = batch_size
+ p2.init_images = work[i*batch_size:(i+1)*batch_size]
+
+ state.job = f"Batch {i + 1 + n * batch_count} out of {state.job_count}"
+ p2.scripts.scripts = i2i_scripts
+ p2.scripts.alwayson_scripts = i2i_scripts_always
+ processed = processing.process_images(p2)
+
+ p2.seed = processed.seed + 1
+ work_results += processed.images
+
+ image_index = 0
+ for y, h, row in grid.tiles:
+ for tiledata in row:
+ tiledata[2] = work_results[image_index] if image_index < len(work_results) else Image.new("RGB", (rewidth, reheight))
+ image_index += 1
+ combined_image = images.combine_grid(grid)
+ result_images.append(combined_image)
+ images.save_image(combined_image, p.outpath_samples, "", start_seed, initial_prompt[n], opts.samples_format, info=initial_info[n], p=p_txt)
+
+ return Processed(p_txt, result_images, start_seed, initial_info[0], all_prompts=initial_prompt, all_negative_prompts=initial_negative, infotexts=initial_info)
+
+def modeldataset(model_shortname):
+ path = modelpath(model_shortname)
+ if ("mmdet" in path and "segm" in path):
+ dataset = 'coco'
+ else:
+ dataset = 'bbox'
+ return dataset
+
+def modelpath(model_shortname):
+ model_list = modelloader.load_models(model_path=dd_models_path, ext_filter=[".pth"])
+ model_h = model_shortname.split("[")[-1].split("]")[0]
+ for path in model_list:
+ if ( model_hash(path) == model_h):
+ return path
+
+def update_result_masks(results, masks):
+ for i in range(len(masks)):
+ boolmask = np.array(masks[i], dtype=bool)
+ results[2][i] = boolmask
+ return results
+
+def is_allblack(mask):
+ cv2_mask = np.array(mask)
+ return cv2.countNonZero(cv2_mask) == 0
+
+def bitwise_and_masks(mask1, mask2):
+ cv2_mask1 = np.array(mask1)
+ cv2_mask2 = np.array(mask2)
+ cv2_mask = cv2.bitwise_and(cv2_mask1, cv2_mask2)
+ mask = Image.fromarray(cv2_mask)
+ return mask
+
+def subtract_masks(mask1, mask2):
+ cv2_mask1 = np.array(mask1)
+ cv2_mask2 = np.array(mask2)
+ cv2_mask = cv2.subtract(cv2_mask1, cv2_mask2)
+ mask = Image.fromarray(cv2_mask)
+ return mask
+
+def dilate_masks(masks, dilation_factor, iter=1):
+ if dilation_factor == 0:
+ return masks
+ dilated_masks = []
+ kernel = np.ones((dilation_factor,dilation_factor), np.uint8)
+ for i in range(len(masks)):
+ cv2_mask = np.array(masks[i])
+ dilated_mask = cv2.dilate(cv2_mask, kernel, iter)
+ dilated_masks.append(Image.fromarray(dilated_mask))
+ return dilated_masks
+
+def offset_masks(masks, offset_x, offset_y):
+ if (offset_x == 0 and offset_y == 0):
+ return masks
+ offset_masks = []
+ for i in range(len(masks)):
+ cv2_mask = np.array(masks[i])
+ offset_mask = cv2_mask.copy()
+ offset_mask = np.roll(offset_mask, -offset_y, axis=0)
+ offset_mask = np.roll(offset_mask, offset_x, axis=1)
+
+ offset_masks.append(Image.fromarray(offset_mask))
+ return offset_masks
+
+def combine_masks(masks):
+ initial_cv2_mask = np.array(masks[0])
+ combined_cv2_mask = initial_cv2_mask
+ for i in range(1, len(masks)):
+ cv2_mask = np.array(masks[i])
+ combined_cv2_mask = cv2.bitwise_or(combined_cv2_mask, cv2_mask)
+
+ combined_mask = Image.fromarray(combined_cv2_mask)
+ return combined_mask
+
+def create_segmasks(results):
+ segms = results[2]
+ segmasks = []
+ for i in range(len(segms)):
+ cv2_mask = segms[i].astype(np.uint8) * 255
+ mask = Image.fromarray(cv2_mask)
+ segmasks.append(mask)
+
+ return segmasks
+
+import mmcv
+from mmdet.core import get_classes
+from mmdet.apis import (inference_detector,
+ init_detector)
+
+def get_device():
+ device_id = shared.cmd_opts.device_id
+ if device_id is not None:
+ cuda_device = f"cuda:{device_id}"
+ else:
+ cuda_device = "cpu"
+ return cuda_device
+
+def inference(image, modelname, conf_thres, label):
+ path = modelpath(modelname)
+ if ( "mmdet" in path and "bbox" in path ):
+ results = inference_mmdet_bbox(image, modelname, conf_thres, label)
+ elif ( "mmdet" in path and "segm" in path):
+ results = inference_mmdet_segm(image, modelname, conf_thres, label)
+ return results
+
+def inference_mmdet_segm(image, modelname, conf_thres, label):
+ model_checkpoint = modelpath(modelname)
+ model_config = os.path.splitext(model_checkpoint)[0] + ".py"
+ model_device = get_device()
+ model = init_detector(model_config, model_checkpoint, device=model_device)
+ mmdet_results = inference_detector(model, np.array(image))
+ bbox_results, segm_results = mmdet_results
+ dataset = modeldataset(modelname)
+ classes = get_classes(dataset)
+ labels = [
+ np.full(bbox.shape[0], i, dtype=np.int32)
+ for i, bbox in enumerate(bbox_results)
+ ]
+ n,m = bbox_results[0].shape
+ if (n == 0):
+ return [[],[],[]]
+ labels = np.concatenate(labels)
+ bboxes = np.vstack(bbox_results)
+ segms = mmcv.concat_list(segm_results)
+ filter_inds = np.where(bboxes[:,-1] > conf_thres)[0]
+ results = [[],[],[]]
+ for i in filter_inds:
+ results[0].append(label + "-" + classes[labels[i]])
+ results[1].append(bboxes[i])
+ results[2].append(segms[i])
+
+ return results
+
+def inference_mmdet_bbox(image, modelname, conf_thres, label):
+ model_checkpoint = modelpath(modelname)
+ model_config = os.path.splitext(model_checkpoint)[0] + ".py"
+ model_device = get_device()
+ model = init_detector(model_config, model_checkpoint, device=model_device)
+ results = inference_detector(model, np.array(image))
+ cv2_image = np.array(image)
+ cv2_image = cv2_image[:, :, ::-1].copy()
+ cv2_gray = cv2.cvtColor(cv2_image, cv2.COLOR_BGR2GRAY)
+
+ segms = []
+ for (x0, y0, x1, y1, conf) in results[0]:
+ cv2_mask = np.zeros((cv2_gray.shape), np.uint8)
+ cv2.rectangle(cv2_mask, (int(x0), int(y0)), (int(x1), int(y1)), 255, -1)
+ cv2_mask_bool = cv2_mask.astype(bool)
+ segms.append(cv2_mask_bool)
+
+ n,m = results[0].shape
+ if (n == 0):
+ return [[],[],[]]
+ bboxes = np.vstack(results[0])
+ filter_inds = np.where(bboxes[:,-1] > conf_thres)[0]
+ results = [[],[],[]]
+ for i in filter_inds:
+ results[0].append(label)
+ results[1].append(bboxes[i])
+ results[2].append(segms[i])
+
+ return results
\ No newline at end of file
diff --git a/hauteCouture_v11.safetensors b/hauteCouture_v11.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..4b8f55b8ad409e02e773f586aa613bc8c416b90e
--- /dev/null
+++ b/hauteCouture_v11.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:dd2d6348ed24cba19cb606c3cd2c23ed02092f728fc499906a08c6eaa99b2d2d
+size 151113439
diff --git a/jkBigNippleTipLite_V01.safetensors b/jkBigNippleTipLite_V01.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..1434c1a1216e2d382b986cb850f19f590626a2a7
--- /dev/null
+++ b/jkBigNippleTipLite_V01.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:26be3fd584511d40258d20fc8fa6c136404cbb93459d121f9608501426b0e0d0
+size 37868009
diff --git a/jkPuffyNipples_V01.safetensors b/jkPuffyNipples_V01.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..c34e41fc7a381f1fa058245df9e5e4c08e6f3485
--- /dev/null
+++ b/jkPuffyNipples_V01.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ae5398b1bf167237aaa23e04d7ca400c6cda5f4135e2275c9afac82807d24e1b
+size 4834292
diff --git a/k-military2-01.safetensors b/k-military2-01.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..c4557c2eef3de7790ebbe48b3c8a282f676e6a45
--- /dev/null
+++ b/k-military2-01.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:0cba07ad23b0a9f16da6c696a3121b90980f002ca73018999ccaa62f06b72c19
+size 37866495
diff --git a/k-military2-02.safetensors b/k-military2-02.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..98c1d7d955b4f564958e34efce3522f3fbafc9a1
--- /dev/null
+++ b/k-military2-02.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:1265bc09daa7818529c78fee931d10c674cab56eef2774c787400ca81af1b8f0
+size 37866493
diff --git a/k-military2-03.safetensors b/k-military2-03.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..1612ae08aa2abce2bce29ff181192811e3df4912
--- /dev/null
+++ b/k-military2-03.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:e49356652784ac07ff09bd0a4fff4f20a75237db24aa047ef4f015d211281c05
+size 37866495
diff --git a/k-military2-04.safetensors b/k-military2-04.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..b6606ccda695106a05468045d3ea91d6c984951a
--- /dev/null
+++ b/k-military2-04.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:83374a9d5e1cfa5af68448cf7b2ccb8798a3e86bd616b4e752b20e29435cff33
+size 37866495
diff --git a/k-military2-05.safetensors b/k-military2-05.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..38d7566d0702f0c8b33206e04a3a9a90dd691ff6
--- /dev/null
+++ b/k-military2-05.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:3c880ca5eeaf41af306cccf7a1c72f9d44cebede47212b338c6a9850fcde0ba9
+size 37866495
diff --git a/k-military2-06.safetensors b/k-military2-06.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..69fc2da7c17bbaec20fcb4946e2179b789be4abd
--- /dev/null
+++ b/k-military2-06.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:4036b60f5d4b489eabaffeeea2cdf13c01bf3f520cff78876c475aa9d7c96c55
+size 37866494
diff --git a/k-military2-07.safetensors b/k-military2-07.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..77d3c49aa16ed3e79de3686de422ba663103a5af
--- /dev/null
+++ b/k-military2-07.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:77e908e9340dc506e3db67e87d585fcc5d970d4744c5872d12038749fe9972e0
+size 37866495
diff --git a/k-military2-08.safetensors b/k-military2-08.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..3a1583e7fc695c9ddfd5ec09ad474bfacc6ae6e1
--- /dev/null
+++ b/k-military2-08.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:fb88cb5eb73e32e98621a2379a515f21951208a14fdd4e05810785198eea551c
+size 37866494
diff --git a/k-military2-09.safetensors b/k-military2-09.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..090a4363a86fa45bd4791df0781ef14edce37a85
--- /dev/null
+++ b/k-military2-09.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:c60d12c4deb1c33d3ad8c35d0d9113a27803447afd8cbe718b9bbfceda78bead
+size 37866494
diff --git a/k-military2-10.safetensors b/k-military2-10.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..1cb45756f77ce24e84dd580d757c436b458bdd76
--- /dev/null
+++ b/k-military2-10.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:373318e7d075b08af0dfda04ff5b718ca91e4e7f186a242487353f517d0cfc52
+size 37866496
diff --git a/latexIDLoraLatex_loconV02.safetensors b/latexIDLoraLatex_loconV02.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..ad0adf97bf205e22ec18b015dcf410e98774b3d5
--- /dev/null
+++ b/latexIDLoraLatex_loconV02.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:3a2ac8f0aa468c231c26e5b5b98dc1f09c278a7dff5031e88fc11362e6878acf
+size 11997284
diff --git a/lightAndShadow_v10.safetensors b/lightAndShadow_v10.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..78c7b3628f28b12f709dd21838fd3fc9c60af06a
--- /dev/null
+++ b/lightAndShadow_v10.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:15a630ab2255460b2e99b1e5a6765a1cedcd210e2ffca32474bd02df24232624
+size 151110122
diff --git a/nippleHeartPiercing_2.safetensors b/nippleHeartPiercing_2.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..1a84497eea0a73abe811917e958fce137f6d9a8d
--- /dev/null
+++ b/nippleHeartPiercing_2.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:041b3839f66e4949538e4c9eb87be1102994cdb4c56db3e816e05ade42b7c33f
+size 37866880
diff --git a/nipplePiercing_v20.safetensors b/nipplePiercing_v20.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..939382b4a860469d9353a172bbba29ed8fdd19b5
--- /dev/null
+++ b/nipplePiercing_v20.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:9c45e83d7b6b35f9153cddd1012269313977b28cb395b7a8e31556018a3b4edf
+size 151111469
diff --git a/nymphs_v10.safetensors b/nymphs_v10.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..a440da411512010e83dfd85463049c9c7a97b167
--- /dev/null
+++ b/nymphs_v10.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:1fcb6d23a534a58bfa6d6626246f6a9e093a2032c425e65e7e4b41c524869dfb
+size 151112325
diff --git a/oversizedHoodie_oversizedHoodieV10.safetensors b/oversizedHoodie_oversizedHoodieV10.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..bbbf7fd67c4b18ff8bf4ac133022a8c0454b0497
--- /dev/null
+++ b/oversizedHoodie_oversizedHoodieV10.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:fef13d4fab0763a07972b73b872317836bc54aa55a68f479100f22995c6eaee0
+size 37868596
diff --git a/photorealisticQueenOf_v202.safetensors b/photorealisticQueenOf_v202.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..c8c56fc733347e9f11544650ef85c752637b0f5a
--- /dev/null
+++ b/photorealisticQueenOf_v202.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f99a692c9776ca9aef81242664e735941668145b3155294cf1c647ab5f7f0dc9
+size 75612193
diff --git a/photorealisticWombTattoos_401.safetensors b/photorealisticWombTattoos_401.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..dc2db49b40cc218902b57f89b9e2e8d36f846600
--- /dev/null
+++ b/photorealisticWombTattoos_401.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:79aff61f8d2265653cb958bc2c18f89ebcde838e6705c06861c525cd2197d91b
+size 37864053
diff --git a/povMissionaryAnal_v5.safetensors b/povMissionaryAnal_v5.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..759d2ec249efd044e12d52e71b31ed60deafdc05
--- /dev/null
+++ b/povMissionaryAnal_v5.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:2ff7df71766918601b3cf64ced49838f784b3d499a07e8778fb54c7c015c787e
+size 151114260
diff --git a/pregnant_v10.safetensors b/pregnant_v10.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..85f3397a4f94cebdfc2e6f647a87ddedb6d032b8
--- /dev/null
+++ b/pregnant_v10.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:8e2168832614e4e8191a2fcd1b5526bc630ba0332aaffdefff5c01437d719b43
+size 172345376
diff --git a/ridingDildoSexActLora_v11.safetensors b/ridingDildoSexActLora_v11.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..baea3095b19dfb1b524169b26fc1fb0b472924b8
--- /dev/null
+++ b/ridingDildoSexActLora_v11.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:4352bb7a1c87684d662b212bf7578c54641daef7c1b30064ad8b64a48901bb83
+size 9618189
diff --git a/schoolUniform_naughty.safetensors b/schoolUniform_naughty.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..4a9ed10820da92c4a8ead5a110263b8f671618f7
--- /dev/null
+++ b/schoolUniform_naughty.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f9928f7a675b11b0c43c36e9f5cf4f847ad95ef98d6f8f17af3dc5571e0469b9
+size 56749594
diff --git a/sexyCostume_1.safetensors b/sexyCostume_1.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..4790512f8b4c4df55c601498503a37f3a786e857
--- /dev/null
+++ b/sexyCostume_1.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:1628891bf53cc19a5ead96c277392d0c3880b41457d07d46f1fa2b0d2393559d
+size 113391649
diff --git a/shinyOiledSkin_v1.safetensors b/shinyOiledSkin_v1.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..d97a642408b070810ee597e9fb5a6ffd8d52c573
--- /dev/null
+++ b/shinyOiledSkin_v1.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ddfd403ac5d244c48531973130c7416d2e345a17af53e843a8e31d9adafbe861
+size 75613273
diff --git a/sittingPussyPosition_highPrecision.pt b/sittingPussyPosition_highPrecision.pt
new file mode 100644
index 0000000000000000000000000000000000000000..2d6554f0c3aa54f54bdbd0dcc8e19989137c2a27
--- /dev/null
+++ b/sittingPussyPosition_highPrecision.pt
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:e7ffb3e5218eb04d98ae2c661eb4371bde62f76487f2c36612a5f7309a03c489
+size 377832529
diff --git a/ssb_v17-40.safetensors b/ssb_v17-40.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..b681e325dff65e06d7bcf6d7e85c41aea7080903
--- /dev/null
+++ b/ssb_v17-40.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:63cb1b8aa403e8241a0c5aa4644db7b8c51a3fa9c43b4a3794b75460a2edf970
+size 37865658
diff --git a/ssb_v18-10.safetensors b/ssb_v18-10.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..5a14497e8b6d5814fa8be33dd8bdf44007b283ee
--- /dev/null
+++ b/ssb_v18-10.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f09b518a94753981e472df5c0984705ac0cbad24c267805910cea051fa7e3cea
+size 37865658
diff --git a/ssb_v18-12.safetensors b/ssb_v18-12.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..dd0b34589ee67e95aa0b8b9fef0e30d40987a81a
--- /dev/null
+++ b/ssb_v18-12.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:a0c6537adef43a5e4f730e422b7adc89adb6ab3a36a2fa7488d4d84133ab3a4e
+size 37865656
diff --git a/ssb_v18-14.safetensors b/ssb_v18-14.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..26ec1b9d0e80250b29908cceb2ec50de15020c4c
--- /dev/null
+++ b/ssb_v18-14.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:eaf8f94d2458e257ca3fddb209b985ae8c044f7d07d95cf28087c81ba4d82c18
+size 37865657
diff --git a/ssb_v18-16.safetensors b/ssb_v18-16.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..7749ccb47b3e17a7a4a8231673515738139760ec
--- /dev/null
+++ b/ssb_v18-16.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:3881676645abd7dd337c37e845b2445e4b73434ad8b3edfe3f8046ae947d15a0
+size 37865657
diff --git a/ssb_v18-18.safetensors b/ssb_v18-18.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..f62f40ae0b0e9c5ca66f042697118a54d482a3ca
--- /dev/null
+++ b/ssb_v18-18.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:edd663f69e68b7c89928f742b79bfa751339ae92a5120a57b8a04c0c5e7c0f9d
+size 37865657
diff --git a/ssb_v18-20.safetensors b/ssb_v18-20.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..0160ba04f6a77cd7d1ebf8fd05b1277fb09d823f
--- /dev/null
+++ b/ssb_v18-20.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:df8e2370136354472c4288ba71dca28389991bac6196448909c47ab98f4b6744
+size 37865658
diff --git a/ssb_v21-80.safetensors b/ssb_v21-80.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..8fd8d47b49022778ab283b140a6b8dbb913292fd
--- /dev/null
+++ b/ssb_v21-80.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:89fa5e6b88e438754394c4fc6a3ddf4c55d13a79f8af58da68394fdaa516f211
+size 37865655
diff --git a/ssb_v21-90.safetensors b/ssb_v21-90.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..e17766afa206db64cc7d5f36fff08db53be1513c
--- /dev/null
+++ b/ssb_v21-90.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f7971b8cb99d8695acac2ad68304d82d9f278561aeb9d97a2a4159f84088fd0b
+size 37865655
diff --git a/ssb_v7-10.safetensors b/ssb_v7-10.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..624b7496ac50eca8556ac98f6ef967d8187cf951
--- /dev/null
+++ b/ssb_v7-10.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:5410c50847b6fd2ec3519efbb75e835b630ead361a9db67ec3f07df789dbeb93
+size 18988594
diff --git a/ssb_v8-30.safetensors b/ssb_v8-30.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..dc9b4e8554cdf37c289e0cc27cc83b562e9a91e1
--- /dev/null
+++ b/ssb_v8-30.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:07891e6094480fe3c928ec20d5310b2c42892154e470ebca5723b4dcac36d494
+size 18988595
diff --git a/ssb_v9-000001.safetensors b/ssb_v9-000001.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..eb4264a5ca404f53c75fdbb39fb1fa24fede17bc
--- /dev/null
+++ b/ssb_v9-000001.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:c157d67bd945614e9ee705a05dd9279cc203d0a0de0c6bc89065dfe3a17997a0
+size 75613498
diff --git a/ssb_v9-000002.safetensors b/ssb_v9-000002.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..75d43f59e89905197c05b3fb8b114e6cfccf487c
--- /dev/null
+++ b/ssb_v9-000002.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:602be6fdddcf29dcd6fc5b21b3e8e019ac3a65c3eb234d37bfe5c5563145de17
+size 75613499
diff --git a/ssb_v9-000003.safetensors b/ssb_v9-000003.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..1d761af7f1e6709f833f5ebf3146377104fcb28a
--- /dev/null
+++ b/ssb_v9-000003.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:776b416f4f6e8cfb5fa51e4fb9ec43c4737797b544fdd40eacbf4ed82cd2ae01
+size 75613499
diff --git a/ssb_v9-000004.safetensors b/ssb_v9-000004.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..a34e4157975e4a52243fe0cb6fe7a13d5ef56591
--- /dev/null
+++ b/ssb_v9-000004.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:743d1c663b18e70db261706d1503a05f57d5904b1d6b6e8f3dd248363af5bfbf
+size 75613499
diff --git a/ssb_v9-000005.safetensors b/ssb_v9-000005.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..737cb60259d1aa2de57d1e924922d4ccdf43d810
--- /dev/null
+++ b/ssb_v9-000005.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ab6bc3763e9fb08795876d9683ab1ef8f9a8e977aa371189c677e63023ec632f
+size 75613499
diff --git a/ssb_v9-000006.safetensors b/ssb_v9-000006.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..1042d12d6fdf4deb43d396145cdc43bd447ea414
--- /dev/null
+++ b/ssb_v9-000006.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:e82f2000b0bf0b032cbc1608fba728fda6fc071ae89e453a5088fec540bdbc2a
+size 75613499
diff --git a/ssb_v9-000007.safetensors b/ssb_v9-000007.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..e5750fa6a08760d5c20baa2a05eff5e90ff585d4
--- /dev/null
+++ b/ssb_v9-000007.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:6f0dbd46cfb389f4ec7547c65845de5c694f55fe2a0ab45450616194165eeeca
+size 75613498
diff --git a/ssb_v9-000008.safetensors b/ssb_v9-000008.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..a496a1ba5fa3c714674db3e5eb6e63a5e5523289
--- /dev/null
+++ b/ssb_v9-000008.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:8a5a990512d980566b99e49608b050befbca8461b8e062d52475bbb2ffc035d9
+size 75613499
diff --git a/ssb_v9-000009.safetensors b/ssb_v9-000009.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..d8e73aad91ab95799862bad7bbab815df42bf004
--- /dev/null
+++ b/ssb_v9-000009.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ab2e55348215864f239bfcb35f70ace2893932109cf049a2bc8e73f35b2bae55
+size 75613499
diff --git a/ssb_v9.safetensors b/ssb_v9.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..dac1bc35bc53980af1d1b67f5ab2fbf375da0209
--- /dev/null
+++ b/ssb_v9.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:b541a6adfa69a5e9b40e6c520f6908d76fb64bd482aeb2951ffe46cf22e22283
+size 75613500
diff --git a/tgirls_V3b.safetensors b/tgirls_V3b.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..b03d90f5cc494abba3eba8dceb7508db39e7e7a2
--- /dev/null
+++ b/tgirls_V3b.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:7ab5518969515ced2b5c30b62c2c055ceb512a4c0c3fcde81eb4d2b7773c97af
+size 37930419
diff --git a/thatsMyBush_v10.safetensors b/thatsMyBush_v10.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..181f12c2c79fb683a9fa437c867c96739377fc2c
--- /dev/null
+++ b/thatsMyBush_v10.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:9db2dae4aeeba1bd64cc397f7843e1eb1f07172b8b164b431e07f44ccc3d9463
+size 151119541
diff --git a/tonguedropAhegaoALoraIn_tonguedropV1.safetensors b/tonguedropAhegaoALoraIn_tonguedropV1.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..a6fbffd17d0d85157023682c425e236c31fa1314
--- /dev/null
+++ b/tonguedropAhegaoALoraIn_tonguedropV1.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f0faaf87028b1693b420ed92a081d3039fa0de46564406de4b8c3bdf8622bb70
+size 75636176
diff --git a/unchiLoraAlpha_v10.safetensors b/unchiLoraAlpha_v10.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..ae0b44e50bbb309012d03b7aeadf41c901ddac21
--- /dev/null
+++ b/unchiLoraAlpha_v10.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:64d9f7d2a3d3eba0ef32033a08da7ff37a4fc10ecb6a71282c66e133c8659abe
+size 37861176
diff --git a/whiteNun_v10.safetensors b/whiteNun_v10.safetensors
new file mode 100644
index 0000000000000000000000000000000000000000..408ef9c823f3c42f7165f23d1f1522396b8f16ee
--- /dev/null
+++ b/whiteNun_v10.safetensors
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:50bd079559da715c4e496583d222cd5c73bd03b26eb5b37bce1f12c1c2f3fbb2
+size 37863857