feat: SDXL refiner support for Detailer
feat: controlnet for SEGS fix: tile size bug
This commit is contained in:
@@ -34,6 +34,9 @@ This custom node helps to conveniently enhance images through Detector, Detailer
|
||||
* As a result, it outputs the `combined_mask`, which is a unified mask, and `batch_masks`, which are multiple masks grouped together in batch form.
|
||||
* While `batch_masks` may not be completely separated, it provides functionality to perform some level of segmentation.
|
||||
* Simple Detector (SEGS) - Operating primarily with `BBOX_DETECTOR`, and with the additional provision of `SAM_MODEL` or `SEGM_DETECTOR`, this node internally generates improved SEGS through mask operations on both *bbox* and *silhouette*. It serves as a convenient tool to simplify a somewhat intricate workflow.
|
||||
|
||||
* ControlNetApply (SEGS) - To apply ControlNet in SEGS, you need to use the Preprocessor Provider node from the Inspire Pack to utilize this node.
|
||||
|
||||
* Bitwise(SEGS & SEGS) - Performs a 'bitwise and' operation between two SEGS.
|
||||
* Bitwise(SEGS - SEGS) - Subtracts one SEGS from another.
|
||||
* Bitwise(SEGS & MASK) - Performs a bitwise AND operation between SEGS and MASK.
|
||||
@@ -57,6 +60,8 @@ This custom node helps to conveniently enhance images through Detector, Detailer
|
||||
* FaceDetailer - Easily detects faces and improves them.
|
||||
* FaceDetailer (pipe) - Easily detects faces and improves them (for multipass).
|
||||
|
||||
* `FaceDetailer (SDXL/pipe), BasicPipe -> DetailerPipe (SDXL), Edit DetailerPipe (SDXL)` - These are pipe functions used in Detailer for utilizing the refiner model of SDXL.
|
||||
|
||||
* SEGSDetailer - Performs detailed work on SEGS without pasting it back onto the original image.
|
||||
* SEGSPaste - Pastes the results of SEGS onto the original image.
|
||||
* If `ref_image_opt` is present, the images contained within SEGS are ignored. Instead, the image within `ref_image_opt` corresponding to the crop area of SEGS is taken and pasted. The size of the image in `ref_image_opt` should be the same as the original image size.
|
||||
|
||||
+10
@@ -121,15 +121,19 @@ NODE_CLASS_MAPPINGS = {
|
||||
"FaceDetailerPipe": FaceDetailerPipe,
|
||||
|
||||
"ToDetailerPipe": ToDetailerPipe,
|
||||
"ToDetailerPipeSDXL": ToDetailerPipeSDXL,
|
||||
"FromDetailerPipe": FromDetailerPipe,
|
||||
"FromDetailerPipe_v2": FromDetailerPipe_v2,
|
||||
"FromDetailerPipeSDXL": FromDetailerPipe_SDXL,
|
||||
"ToBasicPipe": ToBasicPipe,
|
||||
"FromBasicPipe": FromBasicPipe,
|
||||
"FromBasicPipe_v2": FromBasicPipe_v2,
|
||||
"BasicPipeToDetailerPipe": BasicPipeToDetailerPipe,
|
||||
"BasicPipeToDetailerPipeSDXL": BasicPipeToDetailerPipeSDXL,
|
||||
"DetailerPipeToBasicPipe": DetailerPipeToBasicPipe,
|
||||
"EditBasicPipe": EditBasicPipe,
|
||||
"EditDetailerPipe": EditDetailerPipe,
|
||||
"EditDetailerPipeSDXL": EditDetailerPipeSDXL,
|
||||
|
||||
"LatentPixelScale": LatentPixelScale,
|
||||
"PixelKSampleUpscalerProvider": PixelKSampleUpscalerProvider,
|
||||
@@ -163,6 +167,7 @@ NODE_CLASS_MAPPINGS = {
|
||||
"ONNXDetectorSEGS": ONNXDetectorForEach,
|
||||
"ImpactSimpleDetectorSEGS": SimpleDetectorForEach,
|
||||
"ImpactSimpleDetectorSEGSPipe": SimpleDetectorForEachPipe,
|
||||
"ImpactControlNetApplySEGS": ControlNetApplySEGS,
|
||||
|
||||
"BboxDetectorCombined_v2": BboxDetectorCombined,
|
||||
"SegmDetectorCombined_v2": SegmDetectorCombined,
|
||||
@@ -240,6 +245,7 @@ NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
"ONNXDetectorSEGS": "ONNX Detector (SEGS)",
|
||||
"ImpactSimpleDetectorSEGS": "Simple Detector (SEGS)",
|
||||
"ImpactSimpleDetectorSEGSPipe": "Simple Detector (SEGS/pipe)",
|
||||
"ImpactControlNetApplySEGS": "ControlNetApply (SEGS)",
|
||||
|
||||
"BboxDetectorCombined_v2": "BBOX Detector (combined)",
|
||||
"SegmDetectorCombined_v2": "SEGM Detector (combined)",
|
||||
@@ -260,6 +266,10 @@ NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
"SAMDetectorSegmented": "SAMDetector (segmented)",
|
||||
"FaceDetailerPipe": "FaceDetailer (pipe)",
|
||||
|
||||
"FromDetailerPipeSDXL": "FaceDetailer (SDXL/pipe)",
|
||||
"BasicPipeToDetailerPipeSDXL": "BasicPipe -> DetailerPipe (SDXL)",
|
||||
"EditDetailerPipeSDXL": "Edit DetailerPipe (SDXL)",
|
||||
|
||||
"BasicPipeToDetailerPipe": "BasicPipe -> DetailerPipe",
|
||||
"DetailerPipeToBasicPipe": "DetailerPipe -> BasicPipe",
|
||||
"EditBasicPipe": "Edit BasicPipe",
|
||||
|
||||
+6
-1
@@ -312,7 +312,9 @@ app.registerExtension({
|
||||
|
||||
switch(node.comfyClass) {
|
||||
case "ToDetailerPipe":
|
||||
case "ToDetailerPipeSDXL":
|
||||
case "BasicPipeToDetailerPipe":
|
||||
case "BasicPipeToDetailerPipeSDXL":
|
||||
case "EditDetailerPipe":
|
||||
case "FaceDetailer":
|
||||
case "DetailerForEach":
|
||||
@@ -354,7 +356,8 @@ app.registerExtension({
|
||||
});
|
||||
}
|
||||
|
||||
if(node.comfyClass == "ImpactWildcardEncode" || node.comfyClass == "ToDetailerPipe" || node.comfyClass == "EditDetailerPipe" || node.comfyClass == "BasicPipeToDetailerPipe") {
|
||||
if(node.comfyClass == "ImpactWildcardEncode" || node.comfyClass == "ToDetailerPipe" || node.comfyClass == "ToDetailerPipeSDXL"
|
||||
|| node.comfyClass == "EditDetailerPipe" || node.comfyClass == "BasicPipeToDetailerPipe" || node.comfyClass == "BasicPipeToDetailerPipeSDXL") {
|
||||
node._value = "Select the LoRA to add to the text";
|
||||
|
||||
var tbox_id = 0;
|
||||
@@ -367,8 +370,10 @@ app.registerExtension({
|
||||
break;
|
||||
|
||||
case "ToDetailerPipe":
|
||||
case "ToDetailerPipeSDXL":
|
||||
case "EditDetailerPipe":
|
||||
case "BasicPipeToDetailerPipe":
|
||||
case "BasicPipeToDetailerPipeSDXL":
|
||||
tbox_id = 0;
|
||||
combo_id = 1;
|
||||
break;
|
||||
|
||||
@@ -2,7 +2,7 @@ import configparser
|
||||
import os
|
||||
|
||||
|
||||
version = "V3.25.3"
|
||||
version = "V3.26"
|
||||
|
||||
dependency_version = 9
|
||||
|
||||
|
||||
+187
-87
@@ -14,7 +14,9 @@ import comfy
|
||||
import impact.wildcards as wildcards
|
||||
import math
|
||||
|
||||
SEG = namedtuple("SEG", ['cropped_image', 'cropped_mask', 'confidence', 'crop_region', 'bbox', 'label'],
|
||||
|
||||
SEG = namedtuple("SEG",
|
||||
['cropped_image', 'cropped_mask', 'confidence', 'crop_region', 'bbox', 'label', 'control_net_wrapper'],
|
||||
defaults=[None])
|
||||
|
||||
|
||||
@@ -37,6 +39,44 @@ def erosion_mask(mask, grow_mask_by):
|
||||
return mask_erosion[:, :, :w, :h].round()
|
||||
|
||||
|
||||
def ksampler_wrapper(model, seed, steps, cfg, sampler_name, scheduler, positive, negative, latent_image, denoise,
|
||||
refiner_ratio=None, refiner_model=None, refiner_clip=None, refiner_positive=None,
|
||||
refiner_negative=None):
|
||||
if refiner_ratio is None or refiner_model is None or refiner_clip is None or refiner_positive is None or refiner_negative is None:
|
||||
refined_latent = \
|
||||
nodes.KSampler().sample(model, seed, steps, cfg, sampler_name, scheduler, positive, negative, latent_image,
|
||||
denoise)[0]
|
||||
else:
|
||||
advanced_steps = math.floor(steps / denoise)
|
||||
start_at_step = advanced_steps - steps
|
||||
end_at_step = start_at_step + math.floor(steps * (1.0 - refiner_ratio))
|
||||
|
||||
print(f"pre: {start_at_step} .. {end_at_step} / {advanced_steps}")
|
||||
temp_latent = \
|
||||
nodes.KSamplerAdvanced().sample(model, "enable", seed, advanced_steps, cfg, sampler_name, scheduler,
|
||||
positive, negative, latent_image, start_at_step, end_at_step,
|
||||
"enable")[0]
|
||||
|
||||
if 'noise_mask' in latent_image:
|
||||
# noise_latent = \
|
||||
# nodes.KSamplerAdvanced().sample(refiner_model, "enable", seed, advanced_steps, cfg, sampler_name,
|
||||
# scheduler, refiner_positive, refiner_negative, latent_image, end_at_step,
|
||||
# end_at_step, "enable")[0]
|
||||
|
||||
latent_compositor = nodes.NODE_CLASS_MAPPINGS['LatentCompositeMasked']()
|
||||
temp_latent = \
|
||||
latent_compositor.composite(latent_image, temp_latent, 0, 0, False, latent_image['noise_mask'])[0]
|
||||
|
||||
print(f"post: {end_at_step} .. {advanced_steps + 1} / {advanced_steps}")
|
||||
refined_latent = \
|
||||
nodes.KSamplerAdvanced().sample(refiner_model, "disable", seed, advanced_steps, cfg, sampler_name, scheduler,
|
||||
refiner_positive, refiner_negative, temp_latent, end_at_step,
|
||||
advanced_steps + 1,
|
||||
"disable")[0]
|
||||
|
||||
return refined_latent
|
||||
|
||||
|
||||
class REGIONAL_PROMPT:
|
||||
def __init__(self, mask, sampler):
|
||||
self.mask = mask
|
||||
@@ -76,18 +116,18 @@ def gen_detection_hints_from_mask_area(x, y, mask, threshold, use_negative):
|
||||
plabs = []
|
||||
|
||||
# minimum sampling step >= 3
|
||||
y_step = max(3, int(mask.shape[0]/20))
|
||||
x_step = max(3, int(mask.shape[1]/20))
|
||||
|
||||
y_step = max(3, int(mask.shape[0] / 20))
|
||||
x_step = max(3, int(mask.shape[1] / 20))
|
||||
|
||||
for i in range(0, len(mask), y_step):
|
||||
for j in range(0, len(mask[i]), x_step):
|
||||
if mask[i][j] > threshold:
|
||||
points.append((x+j, y+i))
|
||||
points.append((x + j, y + i))
|
||||
plabs.append(1)
|
||||
elif use_negative and mask[i][j] == 0:
|
||||
points.append((x+j, y+i))
|
||||
points.append((x + j, y + i))
|
||||
plabs.append(0)
|
||||
|
||||
|
||||
return points, plabs
|
||||
|
||||
|
||||
@@ -96,20 +136,24 @@ def gen_negative_hints(w, h, x1, y1, x2, y2):
|
||||
nplabs = []
|
||||
|
||||
# minimum sampling step >= 3
|
||||
y_step = max(3, int(w/20))
|
||||
x_step = max(3, int(h/20))
|
||||
|
||||
for i in range(10, h-10, y_step):
|
||||
for j in range(10, w-10, x_step):
|
||||
if not (x1-10 <= j and j <= x2+10 and y1-10 <= i and i <= y2+10):
|
||||
y_step = max(3, int(w / 20))
|
||||
x_step = max(3, int(h / 20))
|
||||
|
||||
for i in range(10, h - 10, y_step):
|
||||
for j in range(10, w - 10, x_step):
|
||||
if not (x1 - 10 <= j and j <= x2 + 10 and y1 - 10 <= i and i <= y2 + 10):
|
||||
npoints.append((j, i))
|
||||
nplabs.append(0)
|
||||
|
||||
return npoints, nplabs
|
||||
|
||||
|
||||
def enhance_detail(image, model, clip, vae, guide_size, guide_size_for_bbox, max_size, bbox, seed, steps, cfg, sampler_name,
|
||||
scheduler, positive, negative, denoise, noise_mask, force_inpaint, wildcard_opt=None, detailer_hook=None):
|
||||
def enhance_detail(image, model, clip, vae, guide_size, guide_size_for_bbox, max_size, bbox, seed, steps, cfg,
|
||||
sampler_name,
|
||||
scheduler, positive, negative, denoise, noise_mask, force_inpaint, wildcard_opt=None,
|
||||
detailer_hook=None,
|
||||
refiner_ratio=None, refiner_model=None, refiner_clip=None, refiner_positive=None,
|
||||
refiner_negative=None, control_net_wrapper=None):
|
||||
if wildcard_opt is not None and wildcard_opt != "":
|
||||
model, _, positive = wildcards.process_with_loras(wildcard_opt, model, clip)
|
||||
|
||||
@@ -179,7 +223,12 @@ def enhance_detail(image, model, clip, vae, guide_size, guide_size_for_bbox, max
|
||||
if detailer_hook is not None:
|
||||
latent_image = detailer_hook.post_encode(latent_image)
|
||||
|
||||
refined_latent = nodes.KSampler().sample(model, seed, steps, cfg, sampler_name, scheduler, positive, negative, latent_image, denoise)[0]
|
||||
if control_net_wrapper is not None:
|
||||
positive = control_net_wrapper.apply(positive, upscaled_image)
|
||||
|
||||
refined_latent = ksampler_wrapper(model, seed, steps, cfg, sampler_name, scheduler, positive, negative,
|
||||
latent_image, denoise,
|
||||
refiner_ratio, refiner_model, refiner_clip, refiner_positive, refiner_negative)
|
||||
|
||||
# non-latent downscale - latent downscale cause bad quality
|
||||
refined_image = vae.decode(refined_latent['samples'])
|
||||
@@ -239,8 +288,7 @@ def sam_predict(predictor, points, plabs, bbox, threshold):
|
||||
|
||||
|
||||
def make_sam_mask(sam_model, segs, image, detection_hint, dilation,
|
||||
threshold, bbox_expansion, mask_hint_threshold, mask_hint_use_negative):
|
||||
|
||||
threshold, bbox_expansion, mask_hint_threshold, mask_hint_use_negative):
|
||||
if sam_model.is_auto_mode:
|
||||
device = comfy.model_management.get_torch_device()
|
||||
sam_model.to(device=device)
|
||||
@@ -360,8 +408,9 @@ def make_sam_mask(sam_model, segs, image, detection_hint, dilation,
|
||||
|
||||
return mask
|
||||
|
||||
def generate_detection_hints(image,seg,center,detection_hint,dilated_bbox,mask_hint_threshold, use_small_negative, mask_hint_use_negative):
|
||||
|
||||
def generate_detection_hints(image, seg, center, detection_hint, dilated_bbox, mask_hint_threshold, use_small_negative,
|
||||
mask_hint_use_negative):
|
||||
[x1, y1, x2, y2] = dilated_bbox
|
||||
|
||||
points = []
|
||||
@@ -407,13 +456,13 @@ def generate_detection_hints(image,seg,center,detection_hint,dilated_bbox,mask_h
|
||||
|
||||
elif detection_hint == "mask-area":
|
||||
points, plabs = gen_detection_hints_from_mask_area(seg.crop_region[0], seg.crop_region[1],
|
||||
seg.cropped_mask,
|
||||
mask_hint_threshold, use_small_negative)
|
||||
seg.cropped_mask,
|
||||
mask_hint_threshold, use_small_negative)
|
||||
|
||||
if mask_hint_use_negative == "Outter":
|
||||
npoints, nplabs = gen_negative_hints(image.shape[0], image.shape[1],
|
||||
seg.crop_region[0], seg.crop_region[1],
|
||||
seg.crop_region[2], seg.crop_region[3])
|
||||
seg.crop_region[0], seg.crop_region[1],
|
||||
seg.crop_region[2], seg.crop_region[3])
|
||||
|
||||
points += npoints
|
||||
plabs += nplabs
|
||||
@@ -445,7 +494,7 @@ def merge_and_stack_masks(stacked_masks, group_size):
|
||||
merged_masks = []
|
||||
|
||||
for i in range(0, num_masks, group_size):
|
||||
subset_masks = stacked_masks[i:i+group_size]
|
||||
subset_masks = stacked_masks[i:i + group_size]
|
||||
merged_mask = torch.any(subset_masks, dim=0)
|
||||
merged_masks.append(merged_mask)
|
||||
|
||||
@@ -464,7 +513,6 @@ def every_three_pick_last(stacked_masks):
|
||||
|
||||
def make_sam_mask_segmented(sam_model, segs, image, detection_hint, dilation,
|
||||
threshold, bbox_expansion, mask_hint_threshold, mask_hint_use_negative):
|
||||
|
||||
if sam_model.is_auto_mode:
|
||||
device = comfy.model_management.get_torch_device()
|
||||
sam_model.to(device=device)
|
||||
@@ -509,7 +557,9 @@ def make_sam_mask_segmented(sam_model, segs, image, detection_hint, dilation,
|
||||
|
||||
dilated_bbox = [x1, y1, x2, y2]
|
||||
|
||||
points, plabs = generate_detection_hints(image, segs[i],center, detection_hint, dilated_bbox, mask_hint_threshold, use_small_negative, mask_hint_use_negative)
|
||||
points, plabs = generate_detection_hints(image, segs[i], center, detection_hint, dilated_bbox,
|
||||
mask_hint_threshold, use_small_negative,
|
||||
mask_hint_use_negative)
|
||||
|
||||
detected_masks = sam_predict(predictor, points, plabs, dilated_bbox, threshold)
|
||||
|
||||
@@ -539,7 +589,7 @@ def make_sam_mask_segmented(sam_model, segs, image, detection_hint, dilation,
|
||||
def segs_bitwise_and_mask(segs, mask):
|
||||
if mask is None:
|
||||
print("[SegsBitwiseAndMask] Cannot operate: MASK is empty.")
|
||||
return ([], )
|
||||
return ([],)
|
||||
|
||||
items = []
|
||||
|
||||
@@ -563,7 +613,7 @@ def segs_bitwise_and_mask(segs, mask):
|
||||
def apply_mask_to_each_seg(segs, masks):
|
||||
if masks is None:
|
||||
print("[SegsBitwiseAndMask] Cannot operate: MASK is empty.")
|
||||
return (segs[0], [], )
|
||||
return (segs[0], [],)
|
||||
|
||||
items = []
|
||||
|
||||
@@ -614,9 +664,9 @@ class ONNXDetector:
|
||||
crop_x1, crop_y1, crop_x2, crop_y2, = crop_region
|
||||
|
||||
# prepare cropped mask
|
||||
cropped_mask = np.zeros((crop_y2-crop_y1,crop_x2-crop_x1))
|
||||
inner_mask = np.ones((y2-y1, x2-x1))
|
||||
cropped_mask[y1-crop_y1:y2-crop_y1, x1-crop_x1:x2-crop_x1] = inner_mask
|
||||
cropped_mask = np.zeros((crop_y2 - crop_y1, crop_x2 - crop_x1))
|
||||
inner_mask = np.ones((y2 - y1, x2 - x1))
|
||||
cropped_mask[y1 - crop_y1:y2 - crop_y1, x1 - crop_x1:x2 - crop_x1] = inner_mask
|
||||
|
||||
# make items
|
||||
item = SEG(None, cropped_mask, scores[i], crop_region, item_bbox)
|
||||
@@ -690,10 +740,10 @@ def mask_to_segs(mask, combined, crop_factor, bbox_fill, drop_size=1):
|
||||
for contour in contours:
|
||||
separated_mask = np.zeros_like(mask_i_uint8)
|
||||
cv2.drawContours(separated_mask, [contour], 0, 255, -1)
|
||||
separated_mask = np.array(separated_mask/255.0).astype(np.float32)
|
||||
separated_mask = np.array(separated_mask / 255.0).astype(np.float32)
|
||||
|
||||
x, y, w, h = cv2.boundingRect(contour)
|
||||
bbox = x, y, x+w, y+h
|
||||
bbox = x, y, x + w, y + h
|
||||
crop_region = make_crop_region(
|
||||
mask_i.shape[1], mask_i.shape[0], bbox, crop_factor
|
||||
)
|
||||
@@ -701,8 +751,8 @@ def mask_to_segs(mask, combined, crop_factor, bbox_fill, drop_size=1):
|
||||
if w > drop_size and h > drop_size:
|
||||
cropped_mask = np.array(
|
||||
separated_mask[
|
||||
crop_region[1]: crop_region[3],
|
||||
crop_region[0]: crop_region[2],
|
||||
crop_region[1]: crop_region[3],
|
||||
crop_region[0]: crop_region[2],
|
||||
]
|
||||
)
|
||||
|
||||
@@ -791,9 +841,11 @@ class KSamplerWrapper:
|
||||
|
||||
if hook is not None:
|
||||
model, seed, steps, cfg, sampler_name, scheduler, positive, negative, upscaled_latent, denoise = \
|
||||
hook.pre_ksample(model, seed, steps, cfg, sampler_name, scheduler, positive, negative, latent_image, denoise)
|
||||
hook.pre_ksample(model, seed, steps, cfg, sampler_name, scheduler, positive, negative, latent_image,
|
||||
denoise)
|
||||
|
||||
return nodes.common_ksampler(model, seed, steps, cfg, sampler_name, scheduler, positive, negative, latent_image, denoise=denoise)[0]
|
||||
return nodes.common_ksampler(model, seed, steps, cfg, sampler_name, scheduler, positive, negative, latent_image,
|
||||
denoise=denoise)[0]
|
||||
|
||||
|
||||
class KSamplerAdvancedWrapper:
|
||||
@@ -802,7 +854,8 @@ class KSamplerAdvancedWrapper:
|
||||
def __init__(self, model, cfg, sampler_name, scheduler, positive, negative):
|
||||
self.params = model, cfg, sampler_name, scheduler, positive, negative
|
||||
|
||||
def sample_advanced(self, add_noise, seed, steps, latent_image, start_at_step, end_at_step, return_with_leftover_noise, hook=None):
|
||||
def sample_advanced(self, add_noise, seed, steps, latent_image, start_at_step, end_at_step,
|
||||
return_with_leftover_noise, hook=None):
|
||||
model, cfg, sampler_name, scheduler, positive, negative = self.params
|
||||
|
||||
if hook is not None:
|
||||
@@ -822,7 +875,7 @@ class PixelKSampleHook:
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
|
||||
def set_steps(self, info):
|
||||
self.cur_step, self.total_step = info
|
||||
|
||||
@@ -835,14 +888,15 @@ class PixelKSampleHook:
|
||||
def post_encode(self, samples):
|
||||
return samples
|
||||
|
||||
def pre_ksample(self, model, seed, steps, cfg, sampler_name, scheduler, positive, negative, upscaled_latent, denoise):
|
||||
return model, seed, steps, cfg, sampler_name, scheduler, positive, negative, upscaled_latent, denoise
|
||||
def pre_ksample(self, model, seed, steps, cfg, sampler_name, scheduler, positive, negative, upscaled_latent,
|
||||
denoise):
|
||||
return model, seed, steps, cfg, sampler_name, scheduler, positive, negative, upscaled_latent, denoise
|
||||
|
||||
|
||||
class PixelKSampleHookCombine(PixelKSampleHook):
|
||||
hook1 = None
|
||||
hook2 = None
|
||||
|
||||
|
||||
def __init__(self, hook1, hook2):
|
||||
super().__init__()
|
||||
self.hook1 = hook1
|
||||
@@ -864,9 +918,11 @@ class PixelKSampleHookCombine(PixelKSampleHook):
|
||||
def pre_ksample(self, model, seed, steps, cfg, sampler_name, scheduler, positive, negative, upscaled_latent,
|
||||
denoise):
|
||||
model, seed, steps, cfg, sampler_name, scheduler, positive, negative, upscaled_latent, denoise = \
|
||||
self.hook1.pre_ksample(model, seed, steps, cfg, sampler_name, scheduler, positive, negative, upscaled_latent, denoise)
|
||||
self.hook1.pre_ksample(model, seed, steps, cfg, sampler_name, scheduler, positive, negative,
|
||||
upscaled_latent, denoise)
|
||||
|
||||
return self.hook2.pre_ksample(model, seed, steps, cfg, sampler_name, scheduler, positive, negative, upscaled_latent, denoise)
|
||||
return self.hook2.pre_ksample(model, seed, steps, cfg, sampler_name, scheduler, positive, negative,
|
||||
upscaled_latent, denoise)
|
||||
|
||||
|
||||
class SimpleCfgScheduleHook(PixelKSampleHook):
|
||||
@@ -875,11 +931,12 @@ class SimpleCfgScheduleHook(PixelKSampleHook):
|
||||
def __init__(self, target_cfg):
|
||||
super().__init__()
|
||||
self.target_cfg = target_cfg
|
||||
|
||||
def pre_ksample(self, model, seed, steps, cfg, sampler_name, scheduler, positive, negative, upscaled_latent, denoise):
|
||||
progress = self.cur_step/self.total_step
|
||||
|
||||
def pre_ksample(self, model, seed, steps, cfg, sampler_name, scheduler, positive, negative, upscaled_latent,
|
||||
denoise):
|
||||
progress = self.cur_step / self.total_step
|
||||
gap = self.target_cfg - cfg
|
||||
current_cfg = cfg + gap*progress
|
||||
current_cfg = cfg + gap * progress
|
||||
return model, seed, steps, current_cfg, sampler_name, scheduler, positive, negative, upscaled_latent, denoise
|
||||
|
||||
|
||||
@@ -890,14 +947,16 @@ class SimpleDenoiseScheduleHook(PixelKSampleHook):
|
||||
super().__init__()
|
||||
self.target_denoise = target_denoise
|
||||
|
||||
def pre_ksample(self, model, seed, steps, cfg, sampler_name, scheduler, positive, negative, upscaled_latent, denoise):
|
||||
def pre_ksample(self, model, seed, steps, cfg, sampler_name, scheduler, positive, negative, upscaled_latent,
|
||||
denoise):
|
||||
progress = self.cur_step / self.total_step
|
||||
gap = self.target_denoise - denoise
|
||||
current_denoise = denoise + gap * progress
|
||||
return model, seed, steps, cfg, sampler_name, scheduler, positive, negative, upscaled_latent, current_denoise
|
||||
|
||||
|
||||
def latent_upscale_on_pixel_space_shape(samples, scale_method, w, h, vae, use_tile=False, tile_size=512, save_temp_prefix=None, hook=None):
|
||||
def latent_upscale_on_pixel_space_shape(samples, scale_method, w, h, vae, use_tile=False, tile_size=512,
|
||||
save_temp_prefix=None, hook=None):
|
||||
pixels = vae_decode(vae, samples, use_tile, hook, tile_size=tile_size)
|
||||
|
||||
if save_temp_prefix is not None:
|
||||
@@ -911,7 +970,8 @@ def latent_upscale_on_pixel_space_shape(samples, scale_method, w, h, vae, use_ti
|
||||
return vae_encode(vae, pixels, use_tile, hook, tile_size=tile_size)
|
||||
|
||||
|
||||
def latent_upscale_on_pixel_space(samples, scale_method, scale_factor, vae, use_tile=False, tile_size=512, save_temp_prefix=None, hook=None):
|
||||
def latent_upscale_on_pixel_space(samples, scale_method, scale_factor, vae, use_tile=False, tile_size=512,
|
||||
save_temp_prefix=None, hook=None):
|
||||
pixels = vae_decode(vae, samples, use_tile, hook, tile_size=tile_size)
|
||||
|
||||
if save_temp_prefix is not None:
|
||||
@@ -927,7 +987,8 @@ def latent_upscale_on_pixel_space(samples, scale_method, scale_factor, vae, use_
|
||||
return vae_encode(vae, pixels, use_tile, hook, tile_size=tile_size)
|
||||
|
||||
|
||||
def latent_upscale_on_pixel_space_with_model_shape(samples, scale_method, upscale_model, new_w, new_h, vae, use_tile=False, tile_size=512, save_temp_prefix=None, hook=None):
|
||||
def latent_upscale_on_pixel_space_with_model_shape(samples, scale_method, upscale_model, new_w, new_h, vae,
|
||||
use_tile=False, tile_size=512, save_temp_prefix=None, hook=None):
|
||||
pixels = vae_decode(vae, samples, use_tile, hook, tile_size=tile_size)
|
||||
|
||||
if save_temp_prefix is not None:
|
||||
@@ -950,7 +1011,8 @@ def latent_upscale_on_pixel_space_with_model_shape(samples, scale_method, upscal
|
||||
return vae_encode(vae, pixels, use_tile, hook, tile_size=tile_size)
|
||||
|
||||
|
||||
def latent_upscale_on_pixel_space_with_model(samples, scale_method, upscale_model, scale_factor, vae, use_tile=False, tile_size=512, save_temp_prefix=None, hook=None):
|
||||
def latent_upscale_on_pixel_space_with_model(samples, scale_method, upscale_model, scale_factor, vae, use_tile=False,
|
||||
tile_size=512, save_temp_prefix=None, hook=None):
|
||||
pixels = vae_decode(vae, samples, use_tile, hook, tile_size=tile_size)
|
||||
|
||||
if save_temp_prefix is not None:
|
||||
@@ -988,7 +1050,8 @@ class TwoSamplersForMaskUpscaler:
|
||||
tile_size = 512
|
||||
|
||||
def __init__(self, scale_method, sample_schedule, use_tiled_vae, base_sampler, mask_sampler, mask, vae,
|
||||
full_sampler_opt=None, upscale_model_opt=None, hook_base_opt=None, hook_mask_opt=None, hook_full_opt=None,
|
||||
full_sampler_opt=None, upscale_model_opt=None, hook_base_opt=None, hook_mask_opt=None,
|
||||
hook_full_opt=None,
|
||||
tile_size=512):
|
||||
mask = mask.reshape((-1, 1, mask.shape[-2], mask.shape[-1]))
|
||||
|
||||
@@ -1013,7 +1076,8 @@ class TwoSamplersForMaskUpscaler:
|
||||
save_temp_prefix=save_temp_prefix,
|
||||
hook=self.hook_base, tile_size=self.tile_size)
|
||||
else:
|
||||
upscaled_latent = latent_upscale_on_pixel_space_with_model(samples, scale_method, self.upscale_model, upscale_factor, vae,
|
||||
upscaled_latent = latent_upscale_on_pixel_space_with_model(samples, scale_method, self.upscale_model,
|
||||
upscale_factor, vae,
|
||||
use_tile=self.use_tiled_vae,
|
||||
save_temp_prefix=save_temp_prefix,
|
||||
hook=self.hook_mask, tile_size=self.tile_size)
|
||||
@@ -1037,12 +1101,15 @@ class TwoSamplersForMaskUpscaler:
|
||||
if self.upscale_model is None:
|
||||
upscaled_latent = latent_upscale_on_pixel_space_shape(samples, scale_method, w, h, vae,
|
||||
use_tile=self.use_tiled_vae,
|
||||
save_temp_prefix=save_temp_prefix, hook=self.hook_base,
|
||||
save_temp_prefix=save_temp_prefix,
|
||||
hook=self.hook_base,
|
||||
tile_size=self.tile_size)
|
||||
else:
|
||||
upscaled_latent = latent_upscale_on_pixel_space_with_model_shape(samples, scale_method, self.upscale_model, w, h, vae,
|
||||
upscaled_latent = latent_upscale_on_pixel_space_with_model_shape(samples, scale_method, self.upscale_model,
|
||||
w, h, vae,
|
||||
use_tile=self.use_tiled_vae,
|
||||
save_temp_prefix=save_temp_prefix, hook=self.hook_mask,
|
||||
save_temp_prefix=save_temp_prefix,
|
||||
hook=self.hook_mask,
|
||||
tile_size=self.tile_size)
|
||||
|
||||
return self.do_samples(step_info, base_sampler, mask_sampler, sample_schedule, mask, upscaled_latent)
|
||||
@@ -1070,16 +1137,16 @@ class TwoSamplersForMaskUpscaler:
|
||||
return cur_step == total_step
|
||||
|
||||
elif sample_schedule == "last2":
|
||||
return cur_step >= total_step-1
|
||||
return cur_step >= total_step - 1
|
||||
|
||||
elif sample_schedule == "interleave1+last1":
|
||||
return cur_step % 2 == 0 or cur_step >= total_step-1
|
||||
return cur_step % 2 == 0 or cur_step >= total_step - 1
|
||||
|
||||
elif sample_schedule == "interleave2+last1":
|
||||
return cur_step % 2 == 0 or cur_step >= total_step-1
|
||||
return cur_step % 2 == 0 or cur_step >= total_step - 1
|
||||
|
||||
elif sample_schedule == "interleave3+last1":
|
||||
return cur_step % 2 == 0 or cur_step >= total_step-1
|
||||
return cur_step % 2 == 0 or cur_step >= total_step - 1
|
||||
|
||||
def do_samples(self, step_info, base_sampler, mask_sampler, sample_schedule, mask, upscaled_latent):
|
||||
if self.is_full_sample_time(step_info, sample_schedule):
|
||||
@@ -1092,9 +1159,11 @@ class TwoSamplersForMaskUpscaler:
|
||||
else:
|
||||
print(f"step_info={step_info} / non-full time")
|
||||
# upscale mask
|
||||
upscaled_mask = F.interpolate(mask, size=(upscaled_latent['samples'].shape[2], upscaled_latent['samples'].shape[3]),
|
||||
upscaled_mask = F.interpolate(mask, size=(
|
||||
upscaled_latent['samples'].shape[2], upscaled_latent['samples'].shape[3]),
|
||||
mode='bilinear', align_corners=True)
|
||||
upscaled_mask = upscaled_mask[:, :, :upscaled_latent['samples'].shape[2], :upscaled_latent['samples'].shape[3]]
|
||||
upscaled_mask = upscaled_mask[:, :, :upscaled_latent['samples'].shape[2],
|
||||
:upscaled_latent['samples'].shape[3]]
|
||||
|
||||
# base sampler
|
||||
upscaled_inv_mask = torch.where(upscaled_mask != 1.0, torch.tensor(1.0), torch.tensor(0.0))
|
||||
@@ -1140,12 +1209,14 @@ class PixelKSampleUpscaler:
|
||||
upscaled_latent = latent_upscale_on_pixel_space_with_model(samples, scale_method, self.upscale_model,
|
||||
upscale_factor, vae,
|
||||
use_tile=self.use_tiled_vae,
|
||||
save_temp_prefix=save_temp_prefix, hook=self.hook,
|
||||
save_temp_prefix=save_temp_prefix,
|
||||
hook=self.hook,
|
||||
tile_size=self.tile_size)
|
||||
|
||||
if self.hook is not None:
|
||||
model, seed, steps, cfg, sampler_name, scheduler, positive, negative, upscaled_latent, denoise = \
|
||||
self.hook.pre_ksample(model, seed, steps, cfg, sampler_name, scheduler, positive, negative, upscaled_latent, denoise)
|
||||
self.hook.pre_ksample(model, seed, steps, cfg, sampler_name, scheduler, positive, negative,
|
||||
upscaled_latent, denoise)
|
||||
|
||||
refined_latent = nodes.KSampler().sample(model, seed, steps, cfg, sampler_name, scheduler,
|
||||
positive, negative, upscaled_latent, denoise)[0]
|
||||
@@ -1163,20 +1234,36 @@ class PixelKSampleUpscaler:
|
||||
save_temp_prefix=save_temp_prefix, hook=self.hook,
|
||||
tile_size=self.tile_size)
|
||||
else:
|
||||
upscaled_latent = latent_upscale_on_pixel_space_with_model_shape(samples, scale_method, self.upscale_model, w, h, vae,
|
||||
upscaled_latent = latent_upscale_on_pixel_space_with_model_shape(samples, scale_method, self.upscale_model,
|
||||
w, h, vae,
|
||||
use_tile=self.use_tiled_vae,
|
||||
save_temp_prefix=save_temp_prefix, hook=self.hook,
|
||||
save_temp_prefix=save_temp_prefix,
|
||||
hook=self.hook,
|
||||
tile_size=self.tile_size)
|
||||
|
||||
if self.hook is not None:
|
||||
model, seed, steps, cfg, sampler_name, scheduler, positive, negative, upscaled_latent, denoise = \
|
||||
self.hook.pre_ksample(model, seed, steps, cfg, sampler_name, scheduler, positive, negative, upscaled_latent, denoise)
|
||||
self.hook.pre_ksample(model, seed, steps, cfg, sampler_name, scheduler, positive, negative,
|
||||
upscaled_latent, denoise)
|
||||
|
||||
refined_latent = nodes.KSampler().sample(model, seed, steps, cfg, sampler_name, scheduler,
|
||||
positive, negative, upscaled_latent, denoise)[0]
|
||||
return refined_latent
|
||||
|
||||
|
||||
class ControlNetWrapper:
|
||||
def __init__(self, control_net, strength, preprocessor):
|
||||
self.control_net = control_net
|
||||
self.strength = strength
|
||||
self.preprocessor = preprocessor
|
||||
|
||||
def apply(self, conditioning, image):
|
||||
if self.preprocessor is not None:
|
||||
image = self.preprocessor.apply(image)
|
||||
|
||||
return nodes.ControlNetApply().apply_controlnet(conditioning, self.control_net, image, self.strength)[0]
|
||||
|
||||
|
||||
# REQUIREMENTS: BlenderNeko/ComfyUI Noise
|
||||
try:
|
||||
class InjectNoiseHook(PixelKSampleHook):
|
||||
@@ -1192,14 +1279,14 @@ try:
|
||||
size = samples['samples'].shape
|
||||
seed = self.cur_step + self.seed
|
||||
from custom_nodes.ComfyUI_Noise.nodes import NoisyLatentImage, InjectNoise
|
||||
noise = NoisyLatentImage().create_noisy_latents(self.source, seed, size[3]*8, size[2]*8, size[0])[0]
|
||||
noise = NoisyLatentImage().create_noisy_latents(self.source, seed, size[3] * 8, size[2] * 8, size[0])[0]
|
||||
|
||||
# inj noise
|
||||
mask = None
|
||||
if 'noise_mask' in samples:
|
||||
mask = samples['noise_mask']
|
||||
|
||||
strength = self.start_strength + (self.end_strength-self.start_strength)*self.cur_step/self.total_step
|
||||
strength = self.start_strength + (self.end_strength - self.start_strength) * self.cur_step / self.total_step
|
||||
samples = InjectNoise().inject_noise(samples, strength, noise, mask)[0]
|
||||
|
||||
if mask is not None:
|
||||
@@ -1209,7 +1296,6 @@ try:
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
# REQUIREMENTS: BlenderNeko/ComfyUI_TiledKSampler
|
||||
try:
|
||||
class TiledKSamplerWrapper:
|
||||
@@ -1226,10 +1312,14 @@ try:
|
||||
|
||||
if hook is not None:
|
||||
model, seed, steps, cfg, sampler_name, scheduler, positive, negative, upscaled_latent, denoise = \
|
||||
hook.pre_ksample(model, seed, steps, cfg, sampler_name, scheduler, positive, negative, latent_image, denoise)
|
||||
hook.pre_ksample(model, seed, steps, cfg, sampler_name, scheduler, positive, negative, latent_image,
|
||||
denoise)
|
||||
|
||||
return \
|
||||
TiledKSampler().sample(model, seed, tile_width, tile_height, tiling_strategy, steps, cfg, sampler_name,
|
||||
scheduler,
|
||||
positive, negative, latent_image, denoise)[0]
|
||||
|
||||
return TiledKSampler().sample(model, seed, tile_width, tile_height, tiling_strategy, steps, cfg, sampler_name, scheduler,
|
||||
positive, negative, latent_image, denoise)[0]
|
||||
|
||||
class PixelTiledKSampleUpscaler:
|
||||
params = None
|
||||
@@ -1239,7 +1329,8 @@ try:
|
||||
is_tiled = True
|
||||
tile_size = 512
|
||||
|
||||
def __init__(self, scale_method, model, vae, seed, steps, cfg, sampler_name, scheduler, positive, negative, denoise,
|
||||
def __init__(self, scale_method, model, vae, seed, steps, cfg, sampler_name, scheduler, positive, negative,
|
||||
denoise,
|
||||
tile_width, tile_height, tiling_strategy,
|
||||
upscale_model_opt=None, hook_opt=None, tile_size=512):
|
||||
self.params = scale_method, model, vae, seed, steps, cfg, sampler_name, scheduler, positive, negative, denoise
|
||||
@@ -1254,8 +1345,10 @@ try:
|
||||
scale_method, model, vae, seed, steps, cfg, sampler_name, scheduler, positive, negative, denoise = self.params
|
||||
tile_width, tile_height, tiling_strategy = self.tile_params
|
||||
|
||||
return TiledKSampler().sample(model, seed, tile_width, tile_height, tiling_strategy, steps, cfg, sampler_name, scheduler,
|
||||
positive, negative, latent, denoise)[0]
|
||||
return \
|
||||
TiledKSampler().sample(model, seed, tile_width, tile_height, tiling_strategy, steps, cfg, sampler_name,
|
||||
scheduler,
|
||||
positive, negative, latent, denoise)[0]
|
||||
|
||||
def upscale(self, step_info, samples, upscale_factor, save_temp_prefix=None):
|
||||
scale_method, model, vae, seed, steps, cfg, sampler_name, scheduler, positive, negative, denoise = self.params
|
||||
@@ -1265,11 +1358,15 @@ try:
|
||||
|
||||
if self.upscale_model is None:
|
||||
upscaled_latent = latent_upscale_on_pixel_space(samples, scale_method, upscale_factor, vae,
|
||||
use_tile=True, save_temp_prefix=save_temp_prefix, hook=self.hook,
|
||||
use_tile=True, save_temp_prefix=save_temp_prefix,
|
||||
hook=self.hook,
|
||||
tile_size=self.tile_size)
|
||||
else:
|
||||
upscaled_latent = latent_upscale_on_pixel_space_with_model(samples, scale_method, self.upscale_model, upscale_factor, vae,
|
||||
use_tile=True, save_temp_prefix=save_temp_prefix, hook=self.hook,
|
||||
upscaled_latent = latent_upscale_on_pixel_space_with_model(samples, scale_method, self.upscale_model,
|
||||
upscale_factor, vae,
|
||||
use_tile=True,
|
||||
save_temp_prefix=save_temp_prefix,
|
||||
hook=self.hook,
|
||||
tile_size=self.tile_size)
|
||||
|
||||
refined_latent = self.tiled_ksample(upscaled_latent)
|
||||
@@ -1287,9 +1384,12 @@ try:
|
||||
use_tile=True, save_temp_prefix=save_temp_prefix,
|
||||
hook=self.hook, tile_size=self.tile_size)
|
||||
else:
|
||||
upscaled_latent = latent_upscale_on_pixel_space_with_model_shape(samples, scale_method, self.upscale_model, w, h, vae,
|
||||
use_tile=True, save_temp_prefix=save_temp_prefix,
|
||||
hook=self.hook, tile_size=self.tile_size)
|
||||
upscaled_latent = latent_upscale_on_pixel_space_with_model_shape(samples, scale_method,
|
||||
self.upscale_model, w, h, vae,
|
||||
use_tile=True,
|
||||
save_temp_prefix=save_temp_prefix,
|
||||
hook=self.hook,
|
||||
tile_size=self.tile_size)
|
||||
|
||||
refined_latent = self.tiled_ksample(upscaled_latent)
|
||||
|
||||
@@ -1297,7 +1397,6 @@ try:
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
# REQUIREMENTS: biegert/ComfyUI-CLIPSeg
|
||||
try:
|
||||
class BBoxDetectorBasedOnCLIPSeg:
|
||||
@@ -1361,6 +1460,7 @@ from latent_preview import TAESD, TAESDPreviewerImpl, Latent2RGBPreviewer
|
||||
try:
|
||||
import comfy.latent_formats as latent_formats
|
||||
|
||||
|
||||
def get_previewer(device, latent_format=latent_formats.SD15(), force=False, method=None):
|
||||
previewer = None
|
||||
|
||||
@@ -1381,7 +1481,8 @@ try:
|
||||
taesd = TAESD(None, taesd_decoder_path).to(device)
|
||||
previewer = TAESDPreviewerImpl(taesd)
|
||||
else:
|
||||
print("Warning: TAESD previews enabled, but could not find models/vae_approx/{}".format(latent_format.taesd_decoder_name))
|
||||
print("Warning: TAESD previews enabled, but could not find models/vae_approx/{}".format(
|
||||
latent_format.taesd_decoder_name))
|
||||
|
||||
if previewer is None:
|
||||
previewer = Latent2RGBPreviewer(latent_format.latent_rgb_factors)
|
||||
@@ -1391,4 +1492,3 @@ except:
|
||||
print(f"#########################################################################")
|
||||
print(f"[ERROR] ComfyUI-Impact-Pack: Please update ComfyUI to the latest version.")
|
||||
print(f"#########################################################################")
|
||||
|
||||
|
||||
@@ -230,7 +230,7 @@ class SimpleDetectorForEachPipe:
|
||||
def doit(self, detailer_pipe, image, bbox_threshold, bbox_dilation, crop_factor, drop_size,
|
||||
sub_threshold, sub_dilation, sub_bbox_expansion, sam_mask_hint_threshold):
|
||||
|
||||
model, clip, vae, positive, negative, wildcard, bbox_detector, segm_detector_opt, sam_model_opt, detailer_hook = detailer_pipe
|
||||
model, clip, vae, positive, negative, wildcard, bbox_detector, segm_detector_opt, sam_model_opt, detailer_hook, refiner_model, refiner_clip, refiner_positive, refiner_negative = detailer_pipe
|
||||
|
||||
return SimpleDetectorForEach.detect(bbox_detector, image, bbox_threshold, bbox_dilation, crop_factor, drop_size,
|
||||
sub_threshold, sub_dilation, sub_bbox_expansion,
|
||||
|
||||
+108
-30
@@ -167,7 +167,11 @@ class SEGSDetailer:
|
||||
"noise_mask": ("BOOLEAN", {"default": True, "label_on": "enabled", "label_off": "disabled"}),
|
||||
"force_inpaint": ("BOOLEAN", {"default": False, "label_on": "enabled", "label_off": "disabled"}),
|
||||
"basic_pipe": ("BASIC_PIPE",),
|
||||
"refiner_ratio": ("FLOAT", {"default": 0.2, "min": 0.0, "max": 1.0}),
|
||||
},
|
||||
"optional": {
|
||||
"refiner_basic_pipe_opt": ("BASIC_PIPE",),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("SEGS", )
|
||||
@@ -177,9 +181,13 @@ class SEGSDetailer:
|
||||
|
||||
@staticmethod
|
||||
def do_detail(image, segs, guide_size, guide_size_for, max_size, seed, steps, cfg, sampler_name, scheduler,
|
||||
denoise, noise_mask, force_inpaint, basic_pipe):
|
||||
denoise, noise_mask, force_inpaint, basic_pipe, refiner_ratio=None, refiner_basic_pipe_opt=None):
|
||||
|
||||
model, clip, vae, positive, negative = basic_pipe
|
||||
if refiner_basic_pipe_opt is None:
|
||||
refiner_model, refiner_clip, refiner_positive, refiner_negative = None, None, None, None
|
||||
else:
|
||||
refiner_model, refiner_clip, _, refiner_positive, refiner_negative = refiner_basic_pipe_opt
|
||||
|
||||
new_segs = []
|
||||
|
||||
@@ -200,19 +208,26 @@ class SEGSDetailer:
|
||||
|
||||
enhanced_pil = core.enhance_detail(cropped_image, model, clip, vae, guide_size, guide_size_for, max_size,
|
||||
seg.bbox, seed, steps, cfg, sampler_name, scheduler,
|
||||
positive, negative, denoise, cropped_mask, force_inpaint)
|
||||
positive, negative, denoise, cropped_mask, force_inpaint,
|
||||
refiner_ratio=refiner_ratio, refiner_model=refiner_model,
|
||||
refiner_clip=refiner_clip, refiner_positive=refiner_positive, refiner_negative=refiner_negative,
|
||||
control_net_wrapper=seg.control_net_wrapper)
|
||||
|
||||
if enhanced_pil is None:
|
||||
new_cropped_image = cropped_image
|
||||
else:
|
||||
new_cropped_image = pil2numpy(enhanced_pil)
|
||||
|
||||
new_cropped_image = pil2numpy(enhanced_pil)
|
||||
new_seg = SEG(new_cropped_image, seg.cropped_mask, seg.confidence, seg.crop_region, seg.bbox, seg.label)
|
||||
new_segs.append(new_seg)
|
||||
|
||||
return segs[0], new_segs
|
||||
|
||||
def doit(self, image, segs, guide_size, guide_size_for, max_size, seed, steps, cfg, sampler_name, scheduler,
|
||||
denoise, noise_mask, force_inpaint, basic_pipe):
|
||||
denoise, noise_mask, force_inpaint, basic_pipe, refiner_ratio=None, refiner_basic_pipe_opt=None):
|
||||
|
||||
segs = SEGSDetailer.do_detail(image, segs, guide_size, guide_size_for, max_size, seed, steps, cfg, sampler_name, scheduler,
|
||||
denoise, noise_mask, force_inpaint, basic_pipe)
|
||||
segs = SEGSDetailer.do_detail(image, segs, guide_size, guide_size_for, max_size, seed, steps, cfg, sampler_name,
|
||||
scheduler, denoise, noise_mask, force_inpaint, basic_pipe, refiner_ratio, refiner_basic_pipe_opt)
|
||||
|
||||
return (segs, )
|
||||
|
||||
@@ -573,7 +588,8 @@ class DetailerForEach:
|
||||
|
||||
@staticmethod
|
||||
def do_detail(image, segs, model, clip, vae, guide_size, guide_size_for_bbox, max_size, seed, steps, cfg, sampler_name, scheduler,
|
||||
positive, negative, denoise, feather, noise_mask, force_inpaint, wildcard_opt=None, detailer_hook=None):
|
||||
positive, negative, denoise, feather, noise_mask, force_inpaint, wildcard_opt=None, detailer_hook=None,
|
||||
refiner_ratio=None, refiner_model=None, refiner_clip=None, refiner_positive=None, refiner_negative=None):
|
||||
|
||||
image_pil = tensor2pil(image).convert('RGBA')
|
||||
|
||||
@@ -599,7 +615,10 @@ class DetailerForEach:
|
||||
|
||||
enhanced_pil = core.enhance_detail(cropped_image, model, clip, vae, guide_size, guide_size_for_bbox, max_size,
|
||||
seg.bbox, seed, steps, cfg, sampler_name, scheduler,
|
||||
positive, negative, denoise, cropped_mask, force_inpaint, wildcard_opt, detailer_hook)
|
||||
positive, negative, denoise, cropped_mask, force_inpaint, wildcard_opt, detailer_hook,
|
||||
refiner_ratio=refiner_ratio, refiner_model=refiner_model,
|
||||
refiner_clip=refiner_clip, refiner_positive=refiner_positive,
|
||||
refiner_negative=refiner_negative, control_net_wrapper=seg.control_net_wrapper)
|
||||
|
||||
if not (enhanced_pil is None):
|
||||
# don't latent composite-> converting to latent caused poor quality
|
||||
@@ -658,8 +677,12 @@ class DetailerForEachPipe:
|
||||
"force_inpaint": ("BOOLEAN", {"default": True, "label_on": "enabled", "label_off": "disabled"}),
|
||||
"basic_pipe": ("BASIC_PIPE", ),
|
||||
"wildcard": ("STRING", {"multiline": True, "dynamicPrompts": False}),
|
||||
"refiner_ratio": ("FLOAT", {"default": 0.2, "min": 0.0, "max": 1.0}),
|
||||
},
|
||||
"optional": {"detailer_hook": ("DETAILER_HOOK",), }
|
||||
"optional": {
|
||||
"detailer_hook": ("DETAILER_HOOK",),
|
||||
"refiner_basic_pipe_opt": ("BASIC_PIPE",),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("IMAGE", )
|
||||
@@ -668,13 +691,21 @@ class DetailerForEachPipe:
|
||||
CATEGORY = "ImpactPack/Detailer"
|
||||
|
||||
def doit(self, image, segs, guide_size, guide_size_for, max_size, seed, steps, cfg, sampler_name, scheduler,
|
||||
denoise, feather, noise_mask, force_inpaint, basic_pipe, wildcard, detailer_hook=None):
|
||||
denoise, feather, noise_mask, force_inpaint, basic_pipe, wildcard, refiner_ratio=None, detailer_hook=None, refiner_basic_pipe_opt=None):
|
||||
|
||||
model, clip, vae, positive, negative = basic_pipe
|
||||
|
||||
if refiner_basic_pipe_opt is None:
|
||||
refiner_model, refiner_clip, refiner_positive, refiner_negative = None, None, None, None
|
||||
else:
|
||||
refiner_model, refiner_clip, _, refiner_positive, refiner_negative = refiner_basic_pipe_opt
|
||||
|
||||
enhanced_img, cropped, cropped_enhanced, cropped_enhanced_alpha = \
|
||||
DetailerForEach.do_detail(image, segs, model, clip, vae, guide_size, guide_size_for, max_size, seed, steps, cfg,
|
||||
sampler_name, scheduler, positive, negative, denoise, feather, noise_mask,
|
||||
force_inpaint, wildcard, detailer_hook)
|
||||
force_inpaint, wildcard, detailer_hook,
|
||||
refiner_ratio=refiner_ratio, refiner_model=refiner_model,
|
||||
refiner_clip=refiner_clip, refiner_positive=refiner_positive, refiner_negative=refiner_negative)
|
||||
|
||||
return (enhanced_img, )
|
||||
|
||||
@@ -982,7 +1013,9 @@ class FaceDetailer:
|
||||
bbox_threshold, bbox_dilation, bbox_crop_factor,
|
||||
sam_detection_hint, sam_dilation, sam_threshold, sam_bbox_expansion, sam_mask_hint_threshold,
|
||||
sam_mask_hint_use_negative, drop_size,
|
||||
bbox_detector, segm_detector=None, sam_model_opt=None, wildcard_opt=None, detailer_hook=None):
|
||||
bbox_detector, segm_detector=None, sam_model_opt=None, wildcard_opt=None, detailer_hook=None,
|
||||
refiner_ratio=None, refiner_model=None, refiner_clip=None, refiner_positive=None, refiner_negative=None):
|
||||
|
||||
# make default prompt as 'face' if empty prompt for CLIPSeg
|
||||
bbox_detector.setAux('face')
|
||||
segs = bbox_detector.detect(image, bbox_threshold, bbox_dilation, bbox_crop_factor, drop_size)
|
||||
@@ -1003,7 +1036,10 @@ class FaceDetailer:
|
||||
enhanced_img, _, cropped_enhanced, cropped_enhanced_alpha = \
|
||||
DetailerForEach.do_detail(image, segs, model, clip, vae, guide_size, guide_size_for_bbox, max_size, seed, steps, cfg,
|
||||
sampler_name, scheduler, positive, negative, denoise, feather, noise_mask,
|
||||
force_inpaint, wildcard_opt, detailer_hook)
|
||||
force_inpaint, wildcard_opt, detailer_hook,
|
||||
refiner_ratio=refiner_ratio, refiner_model=refiner_model,
|
||||
refiner_clip=refiner_clip, refiner_positive=refiner_positive,
|
||||
refiner_negative=refiner_negative)
|
||||
|
||||
# Mask Generator
|
||||
mask = core.segs_to_combined_mask(segs)
|
||||
@@ -1029,7 +1065,7 @@ class FaceDetailer:
|
||||
sam_detection_hint, sam_dilation, sam_threshold, sam_bbox_expansion, sam_mask_hint_threshold,
|
||||
sam_mask_hint_use_negative, drop_size, bbox_detector, segm_detector_opt, sam_model_opt, wildcard, detailer_hook)
|
||||
|
||||
pipe = (model, clip, vae, positive, negative, wildcard, bbox_detector, segm_detector_opt, sam_model_opt, detailer_hook)
|
||||
pipe = (model, clip, vae, positive, negative, wildcard, bbox_detector, segm_detector_opt, sam_model_opt, detailer_hook, None, None, None, None)
|
||||
return enhanced_img, cropped_enhanced, cropped_enhanced_alpha, mask, pipe
|
||||
|
||||
|
||||
@@ -1200,8 +1236,8 @@ class TiledKSamplerProvider:
|
||||
"sampler_name": (comfy.samplers.KSampler.SAMPLERS, ),
|
||||
"scheduler": (comfy.samplers.KSampler.SCHEDULERS, ),
|
||||
"denoise": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01}),
|
||||
"tile_width": ("INT", {"default": 512, "min": 256, "max": MAX_RESOLUTION, "step": 64}),
|
||||
"tile_height": ("INT", {"default": 512, "min": 256, "max": MAX_RESOLUTION, "step": 64}),
|
||||
"tile_width": ("INT", {"default": 512, "min": 320, "max": MAX_RESOLUTION, "step": 64}),
|
||||
"tile_height": ("INT", {"default": 512, "min": 320, "max": MAX_RESOLUTION, "step": 64}),
|
||||
"tiling_strategy": (["random", "padded", 'simple'], ),
|
||||
"basic_pipe": ("BASIC_PIPE", )
|
||||
}}
|
||||
@@ -1236,8 +1272,8 @@ class PixelTiledKSampleUpscalerProvider:
|
||||
"positive": ("CONDITIONING", ),
|
||||
"negative": ("CONDITIONING", ),
|
||||
"denoise": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01}),
|
||||
"tile_width": ("INT", {"default": 512, "min": 256, "max": MAX_RESOLUTION, "step": 64}),
|
||||
"tile_height": ("INT", {"default": 512, "min": 256, "max": MAX_RESOLUTION, "step": 64}),
|
||||
"tile_width": ("INT", {"default": 512, "min": 320, "max": MAX_RESOLUTION, "step": 64}),
|
||||
"tile_height": ("INT", {"default": 512, "min": 320, "max": MAX_RESOLUTION, "step": 64}),
|
||||
"tiling_strategy": (["random", "padded", 'simple'], ),
|
||||
},
|
||||
"optional": {
|
||||
@@ -1275,8 +1311,8 @@ class PixelTiledKSampleUpscalerProviderPipe:
|
||||
"sampler_name": (comfy.samplers.KSampler.SAMPLERS, ),
|
||||
"scheduler": (comfy.samplers.KSampler.SCHEDULERS, ),
|
||||
"denoise": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01}),
|
||||
"tile_width": ("INT", {"default": 512, "min": 256, "max": MAX_RESOLUTION, "step": 64}),
|
||||
"tile_height": ("INT", {"default": 512, "min": 256, "max": MAX_RESOLUTION, "step": 64}),
|
||||
"tile_width": ("INT", {"default": 512, "min": 320, "max": MAX_RESOLUTION, "step": 64}),
|
||||
"tile_height": ("INT", {"default": 512, "min": 320, "max": MAX_RESOLUTION, "step": 64}),
|
||||
"tiling_strategy": (["random", "padded", 'simple'], ),
|
||||
"basic_pipe": ("BASIC_PIPE",)
|
||||
},
|
||||
@@ -1321,7 +1357,7 @@ class PixelKSampleUpscalerProvider:
|
||||
"negative": ("CONDITIONING", ),
|
||||
"denoise": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01}),
|
||||
"use_tiled_vae": ("BOOLEAN", {"default": False, "label_on": "enabled", "label_off": "disabled"}),
|
||||
"tile_size": ("INT", {"default": 512, "min": 192, "max": 4096, "step": 64}),
|
||||
"tile_size": ("INT", {"default": 512, "min": 320, "max": 4096, "step": 64}),
|
||||
},
|
||||
"optional": {
|
||||
"upscale_model_opt": ("UPSCALE_MODEL", ),
|
||||
@@ -1357,7 +1393,7 @@ class PixelKSampleUpscalerProviderPipe(PixelKSampleUpscalerProvider):
|
||||
"denoise": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01}),
|
||||
"use_tiled_vae": ("BOOLEAN", {"default": False, "label_on": "enabled", "label_off": "disabled"}),
|
||||
"basic_pipe": ("BASIC_PIPE",),
|
||||
"tile_size": ("INT", {"default": 512, "min": 192, "max": 4096, "step": 64}),
|
||||
"tile_size": ("INT", {"default": 512, "min": 320, "max": 4096, "step": 64}),
|
||||
},
|
||||
"optional": {
|
||||
"upscale_model_opt": ("UPSCALE_MODEL", ),
|
||||
@@ -1396,7 +1432,7 @@ class TwoSamplersForMaskUpscalerProvider:
|
||||
"mask_sampler": ("KSAMPLER", ),
|
||||
"mask": ("MASK", ),
|
||||
"vae": ("VAE",),
|
||||
"tile_size": ("INT", {"default": 512, "min": 192, "max": 4096, "step": 64}),
|
||||
"tile_size": ("INT", {"default": 512, "min": 320, "max": 4096, "step": 64}),
|
||||
},
|
||||
"optional": {
|
||||
"full_sampler_opt": ("KSAMPLER",),
|
||||
@@ -1438,7 +1474,7 @@ class TwoSamplersForMaskUpscalerProviderPipe:
|
||||
"mask_sampler": ("KSAMPLER", ),
|
||||
"mask": ("MASK", ),
|
||||
"basic_pipe": ("BASIC_PIPE",),
|
||||
"tile_size": ("INT", {"default": 512, "min": 192, "max": 4096, "step": 64}),
|
||||
"tile_size": ("INT", {"default": 512, "min": 320, "max": 4096, "step": 64}),
|
||||
},
|
||||
"optional": {
|
||||
"full_sampler_opt": ("KSAMPLER",),
|
||||
@@ -1590,6 +1626,7 @@ class FaceDetailerPipe:
|
||||
"sam_mask_hint_use_negative": (["False", "Small", "Outter"],),
|
||||
|
||||
"drop_size": ("INT", {"min": 1, "max": MAX_RESOLUTION, "step": 1, "default": 10}),
|
||||
"refiner_ratio": ("FLOAT", {"default": 0.2, "min": 0.0, "max": 1.0}),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1603,16 +1640,19 @@ class FaceDetailerPipe:
|
||||
def doit(self, image, detailer_pipe, guide_size, guide_size_for, max_size, seed, steps, cfg, sampler_name, scheduler,
|
||||
denoise, feather, noise_mask, force_inpaint, bbox_threshold, bbox_dilation, bbox_crop_factor,
|
||||
sam_detection_hint, sam_dilation, sam_threshold, sam_bbox_expansion,
|
||||
sam_mask_hint_threshold, sam_mask_hint_use_negative, drop_size):
|
||||
sam_mask_hint_threshold, sam_mask_hint_use_negative, drop_size, refiner_ratio=None):
|
||||
|
||||
model, clip, vae, positive, negative, wildcard, bbox_detector, segm_detector, sam_model_opt, detailer_hook = detailer_pipe
|
||||
model, clip, vae, positive, negative, wildcard, bbox_detector, segm_detector, sam_model_opt, detailer_hook, \
|
||||
refiner_model, refiner_clip, refiner_positive, refiner_negative = detailer_pipe
|
||||
|
||||
enhanced_img, cropped_enhanced, cropped_enhanced_alpha, mask = FaceDetailer.enhance_face(
|
||||
image, model, clip, vae, guide_size, guide_size_for, max_size, seed, steps, cfg, sampler_name, scheduler,
|
||||
positive, negative, denoise, feather, noise_mask, force_inpaint,
|
||||
bbox_threshold, bbox_dilation, bbox_crop_factor,
|
||||
sam_detection_hint, sam_dilation, sam_threshold, sam_bbox_expansion, sam_mask_hint_threshold,
|
||||
sam_mask_hint_use_negative, drop_size, bbox_detector, segm_detector, sam_model_opt, wildcard, detailer_hook)
|
||||
sam_mask_hint_use_negative, drop_size, bbox_detector, segm_detector, sam_model_opt, wildcard, detailer_hook,
|
||||
refiner_ratio=refiner_ratio, refiner_model=refiner_model,
|
||||
refiner_clip=refiner_clip, refiner_positive=refiner_positive, refiner_negative=refiner_negative)
|
||||
|
||||
if len(cropped_enhanced) == 0:
|
||||
cropped_enhanced = [empty_pil_tensor()]
|
||||
@@ -1663,13 +1703,22 @@ class DetailerForEachTestPipe(DetailerForEachPipe):
|
||||
CATEGORY = "ImpactPack/Detailer"
|
||||
|
||||
def doit(self, image, segs, guide_size, guide_size_for, max_size, seed, steps, cfg, sampler_name, scheduler,
|
||||
denoise, feather, noise_mask, force_inpaint, basic_pipe, wildcard, detailer_hook=None):
|
||||
denoise, feather, noise_mask, force_inpaint, basic_pipe, wildcard, refiner_ratio=None, detailer_hook=None, refiner_basic_pipe_opt=None):
|
||||
|
||||
model, clip, vae, positive, negative = basic_pipe
|
||||
|
||||
if refiner_basic_pipe_opt is None:
|
||||
refiner_model, refiner_clip, refiner_positive, refiner_negative = None, None, None, None
|
||||
else:
|
||||
refiner_model, refiner_clip, _, refiner_positive, refiner_negative = refiner_basic_pipe_opt
|
||||
|
||||
enhanced_img, cropped, cropped_enhanced, cropped_enhanced_alpha = \
|
||||
DetailerForEach.do_detail(image, segs, model, clip, vae, guide_size, guide_size_for, max_size, seed, steps, cfg,
|
||||
sampler_name, scheduler, positive, negative, denoise, feather, noise_mask,
|
||||
force_inpaint, wildcard, detailer_hook)
|
||||
force_inpaint, wildcard, detailer_hook,
|
||||
refiner_ratio=refiner_ratio, refiner_model=refiner_model,
|
||||
refiner_clip=refiner_clip, refiner_positive=refiner_positive,
|
||||
refiner_negative=refiner_negative)
|
||||
|
||||
# set fallback image
|
||||
if len(cropped) == 0:
|
||||
@@ -2571,7 +2620,7 @@ class ReencodeLatent:
|
||||
"tile_mode": (["None", "Both", "Decode(input) only", "Encode(output) only"],),
|
||||
"input_vae": ("VAE", ),
|
||||
"output_vae": ("VAE", ),
|
||||
"tile_size": ("INT", {"default": 512, "min": 192, "max": 4096, "step": 64}),
|
||||
"tile_size": ("INT", {"default": 512, "min": 320, "max": 4096, "step": 64}),
|
||||
},
|
||||
}
|
||||
|
||||
@@ -2716,6 +2765,35 @@ class MakeImageList:
|
||||
return (images, )
|
||||
|
||||
|
||||
class ControlNetApplySEGS:
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
return {"required": {
|
||||
"segs": ("SEGS",),
|
||||
"control_net": ("CONTROL_NET",),
|
||||
"strength": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.01}),
|
||||
},
|
||||
"optional": {
|
||||
"segs_preprocessor": ("SEGS_PREPROCESSOR",),
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("SEGS",)
|
||||
FUNCTION = "doit"
|
||||
|
||||
CATEGORY = "ImpactPack/Util"
|
||||
|
||||
def doit(self, segs, control_net, strength, segs_preprocessor=None):
|
||||
new_segs = []
|
||||
|
||||
for seg in segs[1]:
|
||||
control_net_wrapper = impact.core.ControlNetWrapper(control_net, strength, segs_preprocessor)
|
||||
new_seg = SEG(seg.cropped_image, seg.cropped_mask, seg.confidence, seg.crop_region, seg.bbox, seg.label, control_net_wrapper)
|
||||
new_segs.append(new_seg)
|
||||
|
||||
return ((segs[0], new_segs), )
|
||||
|
||||
|
||||
class StringSelector:
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
|
||||
+135
-10
@@ -27,10 +27,36 @@ class ToDetailerPipe:
|
||||
|
||||
def doit(self, *args, **kwargs):
|
||||
pipe = (kwargs['model'], kwargs['clip'], kwargs['vae'], kwargs['positive'], kwargs['negative'], kwargs['wildcard'], kwargs['bbox_detector'],
|
||||
kwargs.get('segm_detector_opt', None), kwargs.get('sam_model_opt', None), kwargs.get('detailer_hook', None))
|
||||
kwargs.get('segm_detector_opt', None), kwargs.get('sam_model_opt', None), kwargs.get('detailer_hook', None),
|
||||
kwargs.get('refiner_model', None), kwargs.get('refiner_clip', None),
|
||||
kwargs.get('refiner_positive', None), kwargs.get('refiner_negative', None))
|
||||
return (pipe, )
|
||||
|
||||
|
||||
class ToDetailerPipeSDXL(ToDetailerPipe):
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
return {"required": {
|
||||
"model": ("MODEL",),
|
||||
"clip": ("CLIP",),
|
||||
"vae": ("VAE",),
|
||||
"positive": ("CONDITIONING",),
|
||||
"negative": ("CONDITIONING",),
|
||||
"refiner_model": ("MODEL",),
|
||||
"refiner_clip": ("CLIP",),
|
||||
"refiner_positive": ("CONDITIONING",),
|
||||
"refiner_negative": ("CONDITIONING",),
|
||||
"bbox_detector": ("BBOX_DETECTOR", ),
|
||||
"wildcard": ("STRING", {"multiline": True, "dynamicPrompts": False}),
|
||||
"Select to add LoRA": (["Select the LoRA to add to the text"] + folder_paths.get_filename_list("loras"),),
|
||||
},
|
||||
"optional": {
|
||||
"sam_model_opt": ("SAM_MODEL",),
|
||||
"segm_detector_opt": ("SEGM_DETECTOR",),
|
||||
"detailer_hook": ("DETAILER_HOOK",),
|
||||
}}
|
||||
|
||||
|
||||
class FromDetailerPipe:
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
@@ -43,7 +69,7 @@ class FromDetailerPipe:
|
||||
CATEGORY = "ImpactPack/Pipe"
|
||||
|
||||
def doit(self, detailer_pipe):
|
||||
model, clip, vae, positive, negative, wildcard, bbox_detector, segm_detector_opt, sam_model_opt, detailer_hook = detailer_pipe
|
||||
model, clip, vae, positive, negative, wildcard, bbox_detector, segm_detector_opt, sam_model_opt, detailer_hook, _, _, _, _ = detailer_pipe
|
||||
return model, clip, vae, positive, negative, bbox_detector, sam_model_opt, segm_detector_opt, detailer_hook
|
||||
|
||||
|
||||
@@ -59,10 +85,26 @@ class FromDetailerPipe_v2:
|
||||
CATEGORY = "ImpactPack/Pipe"
|
||||
|
||||
def doit(self, detailer_pipe):
|
||||
model, clip, vae, positive, negative, wildcard, bbox_detector, segm_detector_opt, sam_model_opt, detailer_hook = detailer_pipe
|
||||
model, clip, vae, positive, negative, wildcard, bbox_detector, segm_detector_opt, sam_model_opt, detailer_hook, _, _, _, _ = detailer_pipe
|
||||
return detailer_pipe, model, clip, vae, positive, negative, bbox_detector, sam_model_opt, segm_detector_opt, detailer_hook
|
||||
|
||||
|
||||
class FromDetailerPipe_SDXL:
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
return {"required": {"detailer_pipe": ("DETAILER_PIPE",), }, }
|
||||
|
||||
RETURN_TYPES = ("DETAILER_PIPE", "MODEL", "CLIP", "VAE", "CONDITIONING", "CONDITIONING", "BBOX_DETECTOR", "SAM_MODEL", "SEGM_DETECTOR", "DETAILER_HOOK", "MODEL", "CLIP", "CONDITIONING", "CONDITIONING")
|
||||
RETURN_NAMES = ("detailer_pipe", "model", "clip", "vae", "positive", "negative", "bbox_detector", "sam_model_opt", "segm_detector_opt", "detailer_hook", "refiner_model", "refiner_clip", "refiner_positive", "refiner_negative")
|
||||
FUNCTION = "doit"
|
||||
|
||||
CATEGORY = "ImpactPack/Pipe"
|
||||
|
||||
def doit(self, detailer_pipe):
|
||||
model, clip, vae, positive, negative, wildcard, bbox_detector, segm_detector_opt, sam_model_opt, detailer_hook, refiner_model, refiner_clip, refiner_positive, refiner_negative = detailer_pipe
|
||||
return detailer_pipe, model, clip, vae, positive, negative, bbox_detector, sam_model_opt, segm_detector_opt, detailer_hook, refiner_model, refiner_clip, refiner_positive, refiner_negative
|
||||
|
||||
|
||||
class ToBasicPipe:
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
@@ -148,7 +190,44 @@ class BasicPipeToDetailerPipe:
|
||||
detailer_hook = kwargs.get('detailer_hook', None)
|
||||
|
||||
model, clip, vae, positive, negative = basic_pipe
|
||||
pipe = model, clip, vae, positive, negative, wildcard, bbox_detector, segm_detector_opt, sam_model_opt, detailer_hook
|
||||
pipe = model, clip, vae, positive, negative, wildcard, bbox_detector, segm_detector_opt, sam_model_opt, detailer_hook, None, None, None, None
|
||||
return (pipe, )
|
||||
|
||||
|
||||
class BasicPipeToDetailerPipeSDXL:
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
return {"required": {"base_basic_pipe": ("BASIC_PIPE",),
|
||||
"refiner_basic_pipe": ("BASIC_PIPE",),
|
||||
"bbox_detector": ("BBOX_DETECTOR", ),
|
||||
"wildcard": ("STRING", {"multiline": True, "dynamicPrompts": False}),
|
||||
"Select to add LoRA": (["Select the LoRA to add to the text"] + folder_paths.get_filename_list("loras"),),
|
||||
},
|
||||
"optional": {
|
||||
"sam_model_opt": ("SAM_MODEL", ),
|
||||
"segm_detector_opt": ("SEGM_DETECTOR",),
|
||||
"detailer_hook": ("DETAILER_HOOK",),
|
||||
},
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("DETAILER_PIPE", )
|
||||
RETURN_NAMES = ("detailer_pipe", )
|
||||
FUNCTION = "doit"
|
||||
|
||||
CATEGORY = "ImpactPack/Pipe"
|
||||
|
||||
def doit(self, *args, **kwargs):
|
||||
base_basic_pipe = kwargs['base_basic_pipe']
|
||||
refiner_basic_pipe = kwargs['refiner_basic_pipe']
|
||||
bbox_detector = kwargs['bbox_detector']
|
||||
wildcard = kwargs['wildcard']
|
||||
sam_model_opt = kwargs.get('sam_model_opt', None)
|
||||
segm_detector_opt = kwargs.get('segm_detector_opt', None)
|
||||
detailer_hook = kwargs.get('detailer_hook', None)
|
||||
|
||||
model, clip, vae, positive, negative = base_basic_pipe
|
||||
refiner_model, refiner_clip, refiner_vae, refiner_positive, refiner_negative = refiner_basic_pipe
|
||||
pipe = model, clip, vae, positive, negative, wildcard, bbox_detector, segm_detector_opt, sam_model_opt, detailer_hook, refiner_model, refiner_clip, refiner_positive, refiner_negative
|
||||
return (pipe, )
|
||||
|
||||
|
||||
@@ -157,16 +236,17 @@ class DetailerPipeToBasicPipe:
|
||||
def INPUT_TYPES(s):
|
||||
return {"required": {"detailer_pipe": ("DETAILER_PIPE",), }}
|
||||
|
||||
RETURN_TYPES = ("BASIC_PIPE", )
|
||||
RETURN_NAMES = ("basic_pipe", )
|
||||
RETURN_TYPES = ("BASIC_PIPE", "BASIC_PIPE")
|
||||
RETURN_NAMES = ("base_basic_pipe", "refiner_basic_pipe")
|
||||
FUNCTION = "doit"
|
||||
|
||||
CATEGORY = "ImpactPack/Pipe"
|
||||
|
||||
def doit(self, detailer_pipe):
|
||||
model, clip, vae, positive, negative, _, _, _, _, _ = detailer_pipe
|
||||
model, clip, vae, positive, negative, _, _, _, _, _, refiner_model, refiner_clip, refiner_positive, refiner_negative = detailer_pipe
|
||||
pipe = model, clip, vae, positive, negative
|
||||
return (pipe, )
|
||||
refiner_pipe = refiner_model, refiner_clip, vae, refiner_positive, refiner_negative
|
||||
return (pipe, refiner_pipe)
|
||||
|
||||
|
||||
class EditBasicPipe:
|
||||
@@ -252,8 +332,12 @@ class EditDetailerPipe:
|
||||
sam_model = kwargs.get('sam_model', None)
|
||||
segm_detector = kwargs.get('segm_detector', None)
|
||||
detailer_hook = kwargs.get('detailer_hook', None)
|
||||
refiner_model = kwargs.get('refiner_model', None)
|
||||
refiner_clip = kwargs.get('refiner_clip', None)
|
||||
refiner_positive = kwargs.get('refiner_positive', None)
|
||||
refiner_negative = kwargs.get('refiner_negative', None)
|
||||
|
||||
res_model, res_clip, res_vae, res_positive, res_negative, res_wildcard, res_bbox_detector, res_segm_detector, res_sam_model, res_detailer_hook = detailer_pipe
|
||||
res_model, res_clip, res_vae, res_positive, res_negative, res_wildcard, res_bbox_detector, res_segm_detector, res_sam_model, res_detailer_hook, res_refiner_model, res_refiner_clip, res_refiner_positive, res_refiner_negative = detailer_pipe
|
||||
|
||||
if model is not None:
|
||||
res_model = model
|
||||
@@ -285,6 +369,47 @@ class EditDetailerPipe:
|
||||
if detailer_hook is not None:
|
||||
res_detailer_hook = detailer_hook
|
||||
|
||||
pipe = res_model, res_clip, res_vae, res_positive, res_negative, res_wildcard, res_bbox_detector, res_segm_detector, res_sam_model, res_detailer_hook
|
||||
if refiner_model is not None:
|
||||
res_refiner_model = refiner_model
|
||||
|
||||
if refiner_clip is not None:
|
||||
res_refiner_clip = refiner_clip
|
||||
|
||||
if refiner_positive is not None:
|
||||
res_refiner_positive = refiner_positive
|
||||
|
||||
if refiner_negative is not None:
|
||||
res_refiner_negative = refiner_negative
|
||||
|
||||
pipe = (res_model, res_clip, res_vae, res_positive, res_negative, res_wildcard,
|
||||
res_bbox_detector, res_segm_detector, res_sam_model, res_detailer_hook,
|
||||
res_refiner_model, res_refiner_clip, res_refiner_positive, res_refiner_negative)
|
||||
|
||||
return (pipe, )
|
||||
|
||||
|
||||
class EditDetailerPipeSDXL(EditDetailerPipe):
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
return {
|
||||
"required": {
|
||||
"detailer_pipe": ("DETAILER_PIPE",),
|
||||
"wildcard": ("STRING", {"multiline": True, "dynamicPrompts": False}),
|
||||
"Select to add LoRA": (["Select the LoRA to add to the text"] + folder_paths.get_filename_list("loras"),),
|
||||
},
|
||||
"optional": {
|
||||
"model": ("MODEL",),
|
||||
"clip": ("CLIP",),
|
||||
"vae": ("VAE",),
|
||||
"positive": ("CONDITIONING",),
|
||||
"negative": ("CONDITIONING",),
|
||||
"refiner_model": ("MODEL",),
|
||||
"refiner_clip": ("CLIP",),
|
||||
"refiner_positive": ("CONDITIONING",),
|
||||
"refiner_negative": ("CONDITIONING",),
|
||||
"bbox_detector": ("BBOX_DETECTOR",),
|
||||
"sam_model": ("SAM_MODEL",),
|
||||
"segm_detector_opt": ("SEGM_DETECTOR",),
|
||||
"detailer_hook": ("DETAILER_HOOK",),
|
||||
},
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user