more extensions

This commit is contained in:
salt
2024-02-20 08:30:59 -08:00
parent 8048a05d12
commit 7053eec79c
145 changed files with 7747 additions and 2775 deletions
@@ -7,6 +7,8 @@ This custom node helps to conveniently enhance images through Detector, Detailer
## NOTICE
* V4.77: Compatibility patch applied. Requires ComfyUI version (Oct. 8th) or later.
* V4.73.3: ControlNetApply (SEGS) supports AnimateDiff
* V4.20.1: Due to the feature update in `RegionalSampler`, the parameter order has changed, causing malfunctions in previously created `RegionalSamplers`. Please adjust the parameters accordingly.
* V4.12: `MASKS` is changed to `MASK`.
* V4.7.2 isn't compatible with old version of `ControlNet Auxiliary Preprocessor`. If you will use `MediaPipe FaceMesh to SEGS` update to latest version(Sep. 17th).
@@ -41,8 +43,9 @@ This custom node helps to conveniently enhance images through Detector, Detailer
* ControlNet
* ControlNetApply (SEGS) - To apply ControlNet in SEGS, you need to use the Preprocessor Provider node from the Inspire Pack to utilize this node.
* `SEGSPreprocessor` and `Image` can be selectively applied. If an `Image` is given, `SEGSPreprocessor` will be ignored.
* If set to `Image`, you can preview the cropped cnet image through `SEGSPreview (CNET Image)`. Images generated by `SEGSPreprocessor` should be verified through the `cnet_pil` output of each Detailer.
* `segs_preprocessor` and `control_image` can be selectively applied. If an `control_image` is given, `segs_preprocessor` will be ignored.
* If set to `control_image`, you can preview the cropped cnet image through `SEGSPreview (CNET Image)`. Images generated by `segs_preprocessor` should be verified through the `cnet_images` output of each Detailer.
* The `segs_preprocessor` operates by applying preprocessing on-the-fly based on the cropped image during the detailing process, while `control_image` will be cropped and used as input to `ControlNetApply (SEGS)`.
* ControlNetClear (SEGS) - Clear applied ControlNet in SEGS
* Bitwise(SEGS & SEGS) - Performs a 'bitwise and' operation between two SEGS.
@@ -89,6 +92,7 @@ This custom node helps to conveniently enhance images through Detector, Detailer
* SEGS Filter (label) - This node filters SEGS based on the label of the detected areas.
* SEGS Filter (ordered) - This node sorts SEGS based on size and position and retrieves SEGs within a certain range.
* SEGS Filter (range) - This node retrieves only SEGs from SEGS that have a size and position within a certain range.
* SEGS Assign (label) - Assign labels sequentially to SEGS. This node is useful when used with `[LAB]` of FaceDetailer.
* SEGSConcat - Concatenate segs1 and segs2. If source shape of segs1 and segs2 are different from segs2 will be ignored.
* Picker (SEGS) - Among the input SEGS, you can select a specific SEG through a dialog. If no SEG is selected, it outputs an empty SEGS. Increasing the batch_size of SEGSDetailer can be used for the purpose of selecting from the candidates.
* Set Default Image For SEGS - Set a default image for SEGS. SEGS with images set this way do not need to have a fallback image set. When override is set to false, the original image is preserved.
@@ -122,8 +126,9 @@ This custom node helps to conveniently enhance images through Detector, Detailer
* You need to install the [BlenderNeko/ComfyUI_TiledKSampler](https://github.com/BlenderNeko/ComfyUI_TiledKSampler) node extension.
* PK_HOOK
* DenoiseScheduleHookProvider - IterativeUpscale provides a hook that gradually changes the denoise to target_denoise as the step progresses.
* CfgScheduleHookProvider - IterativeUpscale provides a hook that gradually changes the cfg to target_cfg as the step progresses.
* DenoiseScheduleHookProvider - IterativeUpscale provides a hook that gradually changes the denoise to target_denoise as the iterative-step progresses.
* CfgScheduleHookProvider - IterativeUpscale provides a hook that gradually changes the cfg to target_cfg as the iterative-step progresses.
* StepsScheduleHookProvider - IterativeUpscale provides a hook that gradually changes the sampling-steps to target_steps as the iterative-step progresses.
* NoiseInjectionHookProvider - During each iteration of IterativeUpscale, noise is injected into the latent space while varying the strength according to a schedule.
* You need to install the [BlenderNeko/ComfyUI_Noise](https://github.com/BlenderNeko/ComfyUI_Noise) node extension.
* The seed serves as the initial value required for generating noise, and it increments by 1 with each iteration as the process unfolds.
@@ -155,7 +160,8 @@ This takes latent as input and outputs latent as the result.
* You need to install the [BlenderNeko/ComfyUI_TiledKSampler](https://github.com/BlenderNeko/ComfyUI_TiledKSampler) node extension.
* TwoAdvancedSamplersForMask - TwoSamplersForMask is similar to TwoAdvancedSamplersForMask, but they differ in their operation. TwoSamplersForMask performs sampling in the mask area only after all the samples in the base area are finished. On the other hand, TwoAdvancedSamplersForMask performs sampling in both the base area and the mask area sequentially at each step.
* KSamplerAdvancedProvider - This is a wrapper that enables KSampler to be used in TwoAdvancedSamplersForMask.
* KSamplerAdvancedProvider - This is a wrapper that enables KSampler to be used in TwoAdvancedSamplersForMask, RegionalSampler.
* sigma_factor: By multiplying the denoise schedule by the sigma_factor, you can adjust the amount of denoising based on the configured denoise.
* TwoSamplersForMaskUpscalerProvider - This is an Upscaler that extends TwoSamplersForMask to be used in Iterative Upscale.
* TwoSamplersForMaskUpscalerProviderPipe - pipe version of TwoSamplersForMaskUpscalerProvider.
@@ -176,6 +176,7 @@ NODE_CLASS_MAPPINGS = {
"PixelKSampleHookCombine": PixelKSampleHookCombine,
"DenoiseScheduleHookProvider": DenoiseScheduleHookProvider,
"StepsScheduleHookProvider": StepsScheduleHookProvider,
"CfgScheduleHookProvider": CfgScheduleHookProvider,
"NoiseInjectionHookProvider": NoiseInjectionHookProvider,
"UnsamplerHookProvider": UnsamplerHookProvider,
@@ -285,6 +286,7 @@ NODE_CLASS_MAPPINGS = {
"ImpactCombineConditionings": CombineConditionings,
"ImpactConcatConditionings": ConcatConditionings,
"ImpactSEGSLabelAssign": SEGSLabelAssign,
"ImpactSEGSLabelFilter": SEGSLabelFilter,
"ImpactSEGSRangeFilter": SEGSRangeFilter,
"ImpactSEGSOrderedFilter": SEGSOrderedFilter,
@@ -384,6 +386,7 @@ NODE_DISPLAY_NAME_MAPPINGS = {
"ImpactKSamplerBasicPipe": "KSampler (pipe)",
"ImpactKSamplerAdvancedBasicPipe": "KSampler (Advanced/pipe)",
"ImpactSEGSLabelAssign": "SEGS Assign (label)",
"ImpactSEGSLabelFilter": "SEGS Filter (label)",
"ImpactSEGSRangeFilter": "SEGS Filter (range)",
"ImpactSEGSOrderedFilter": "SEGS Filter (ordered)",
@@ -65,7 +65,7 @@ class SEGSDetailerForAnimateDiff:
else:
cropped_image_frames = torch.concat((cropped_image_frames, cropped_image), dim=0)
cropped_image_frames = cropped_image_frames.numpy()
cropped_image_frames = cropped_image_frames.cpu().numpy()
enhanced_image_tensor, cnet_images = core.enhance_detail_for_animatediff(cropped_image_frames, model, clip, vae, guide_size, guide_size_for, max_size,
seg.bbox, seed, steps, cfg, sampler_name, scheduler,
positive, negative, denoise, seg.cropped_mask,
@@ -79,7 +79,7 @@ class SEGSDetailerForAnimateDiff:
if enhanced_image_tensor is None:
new_cropped_image = cropped_image_frames
else:
new_cropped_image = enhanced_image_tensor.numpy()
new_cropped_image = enhanced_image_tensor.cpu().numpy()
new_seg = SEG(new_cropped_image, seg.cropped_mask, seg.confidence, seg.crop_region, seg.bbox, seg.label, None)
new_segs.append(new_seg)
@@ -2,7 +2,7 @@ import configparser
import os
version_code = [4, 73, 3]
version_code = [4, 78]
version = f"V{version_code[0]}.{version_code[1]}" + (f'.{version_code[2]}' if len(version_code) > 2 else '')
dependency_version = 20
@@ -370,7 +370,7 @@ def enhance_detail_for_animatediff(image_frames, model, clip, vae, guide_size, g
cnet_images = None
if control_net_wrapper is not None:
positive, negative, cnet_images = control_net_wrapper.apply(positive, negative, torch.from_numpy(image_frames), noise_mask)
positive, negative, cnet_images = control_net_wrapper.apply(positive, negative, torch.from_numpy(image_frames), noise_mask, use_acn=True)
if len(upscaled_mask) != len(image_frames) and len(upscaled_mask) > 1:
print(f"[Impact Pack] WARN: DetailerForAnimateDiff - The number of the mask frames({len(upscaled_mask)}) and the image frames({len(image_frames)}) are different. Combine the mask frames and apply.")
@@ -1505,26 +1505,36 @@ class ControlNetWrapper:
else:
self.control_image = None
def apply(self, positive, negative, image, mask=None):
cnet_tensors = []
prev_cnet_tensors = []
def apply(self, positive, negative, image, mask=None, use_acn=False):
cnet_image_list = []
prev_cnet_images = []
if self.prev_control_net is not None:
positive, negative, prev_cnet_tensors = self.prev_control_net.apply(positive, negative, image, mask)
positive, negative, prev_cnet_images = self.prev_control_net.apply(positive, negative, image, mask, use_acn=use_acn)
if self.control_image is not None:
cnet_tensor = self.control_image
cnet_image = self.control_image
elif self.preprocessor is not None:
cnet_tensor = self.preprocessor.apply(image, mask)
cnet_image = self.preprocessor.apply(image, mask)
else:
cnet_tensor = image
cnet_image = image
cnet_tensors.extend(prev_cnet_tensors)
cnet_tensors.append(cnet_tensor)
cnet_image_list.extend(prev_cnet_images)
cnet_image_list.append(cnet_image)
positive = nodes.ControlNetApply().apply_controlnet(positive, self.control_net, cnet_tensor, self.strength)[0]
if use_acn:
if "ACN_AdvancedControlNetApply" in nodes.NODE_CLASS_MAPPINGS:
acn = nodes.NODE_CLASS_MAPPINGS['ACN_AdvancedControlNetApply']()
positive, negative, _ = acn.apply_controlnet(positive=positive, negative=negative, control_net=self.control_net, image=cnet_image,
strength=self.strength, start_percent=0.0, end_percent=1.0)
else:
utils.try_install_custom_node('https://github.com/BlenderNeko/ComfyUI_TiledKSampler',
"To use 'ControlNetWrapper' for AnimateDiff, 'ComfyUI-Advanced-ControlNet' extension is required.")
raise Exception("'ACN_AdvancedControlNetApply' node isn't installed.")
else:
positive = nodes.ControlNetApply().apply_controlnet(positive, self.control_net, cnet_image, self.strength)[0]
return positive, negative, cnet_tensors
return positive, negative, cnet_image_list
class ControlNetAdvancedWrapper:
@@ -1543,26 +1553,36 @@ class ControlNetAdvancedWrapper:
else:
self.control_image = None
def apply(self, positive, negative, image, mask=None):
cnet_tensors = []
prev_cnet_tensors = []
def apply(self, positive, negative, image, mask=None, use_acn=False):
cnet_image_list = []
prev_cnet_images = []
if self.prev_control_net is not None:
positive, negative, prev_cnet_tensors = self.prev_control_net.apply(positive, negative, image, mask)
positive, negative, prev_cnet_images = self.prev_control_net.apply(positive, negative, image, mask)
if self.control_image is not None:
cnet_tensor = self.control_image
cnet_image = self.control_image
elif self.preprocessor is not None:
cnet_tensor = self.preprocessor.apply(image, mask)
cnet_image = self.preprocessor.apply(image, mask)
else:
cnet_tensor = image
cnet_image = image
cnet_tensors.extend(prev_cnet_tensors)
cnet_tensors.append(cnet_tensor)
cnet_image_list.extend(prev_cnet_images)
cnet_image_list.append(cnet_image)
conditioning = nodes.ControlNetApplyAdvanced().apply_controlnet(positive, negative, self.control_net, cnet_tensor, self.strength, self.start_percent, self.end_percent)
if use_acn:
if "ACN_AdvancedControlNetApply" in nodes.NODE_CLASS_MAPPINGS:
acn = nodes.NODE_CLASS_MAPPINGS['ACN_AdvancedControlNetApply']()
positive, negative, _ = acn.apply_controlnet(positive=positive, negative=negative, control_net=self.control_net, image=cnet_image,
strength=self.strength, start_percent=self.start_percent, end_percent=self.end_percent)
else:
utils.try_install_custom_node('https://github.com/BlenderNeko/ComfyUI_TiledKSampler',
"To use 'ControlNetAdvancedWrapper' for AnimateDiff, 'ComfyUI-Advanced-ControlNet' extension is required.")
raise Exception("'ACN_AdvancedControlNetApply' node isn't installed.")
else:
positive, negative = nodes.ControlNetApplyAdvanced().apply_controlnet(positive, negative, self.control_net, cnet_image, self.strength, self.start_percent, self.end_percent)
return conditioning[0], conditioning[1], cnet_tensors
return positive, negative, cnet_image_list
# REQUIREMENTS: BlenderNeko/ComfyUI_TiledKSampler
@@ -109,11 +109,14 @@ class SimpleCfgScheduleHook(PixelKSampleHook):
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
gap = self.target_cfg - cfg
current_cfg = cfg + gap * progress
def pre_ksample(self, model, seed, steps, cfg, sampler_name, scheduler, positive, negative, upscaled_latent, denoise):
if self.total_step > 1:
progress = self.cur_step / (self.total_step - 1)
gap = self.target_cfg - cfg
current_cfg = int(cfg + gap * progress)
else:
current_cfg = self.target_cfg
return model, seed, steps, current_cfg, sampler_name, scheduler, positive, negative, upscaled_latent, denoise
@@ -122,14 +125,33 @@ 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):
progress = self.cur_step / self.total_step
gap = self.target_denoise - denoise
current_denoise = denoise + gap * progress
def pre_ksample(self, model, seed, steps, cfg, sampler_name, scheduler, positive, negative, upscaled_latent, denoise):
if self.total_step > 1:
progress = self.cur_step / (self.total_step - 1)
gap = self.target_denoise - denoise
current_denoise = denoise + gap * progress
else:
current_denoise = self.target_denoise
return model, seed, steps, cfg, sampler_name, scheduler, positive, negative, upscaled_latent, current_denoise
class SimpleStepsScheduleHook(PixelKSampleHook):
def __init__(self, target_steps):
super().__init__()
self.target_steps = target_steps
def pre_ksample(self, model, seed, steps, cfg, sampler_name, scheduler, positive, negative, upscaled_latent, denoise):
if self.total_step > 1:
progress = self.cur_step / (self.total_step - 1)
gap = self.target_steps - steps
current_steps = int(steps + gap * progress)
else:
current_steps = self.target_steps
return model, seed, current_steps, cfg, sampler_name, scheduler, positive, negative, upscaled_latent, denoise
class DetailerHook(PixelKSampleHook):
def cycle_latent(self, latent):
return latent
@@ -147,9 +169,14 @@ class SimpleDetailerDenoiseSchedulerHook(DetailerHook):
self.target_denoise = target_denoise
def pre_ksample(self, model, seed, steps, cfg, sampler_name, scheduler, positive, negative, latent, denoise):
progress = self.cur_step / self.total_step
gap = self.target_denoise - denoise
current_denoise = denoise + gap * progress
if self.total_step > 1:
progress = self.cur_step / (self.total_step - 1)
gap = self.target_denoise - denoise
current_denoise = denoise + gap * progress
else:
# ignore hook if total cycle <= 1
current_denoise = denoise
return model, seed, steps, cfg, sampler_name, scheduler, positive, negative, latent, current_denoise
@@ -237,8 +237,10 @@ class DetailerForEach:
else:
cropped_mask = None
if wildcard_chooser is not None:
if wildcard_chooser is not None and wmode != "LAB":
seg_seed, wildcard_item = wildcard_chooser.get(seg)
elif wildcard_chooser is not None and wmode == "LAB":
seg_seed, wildcard_item = None, wildcard_chooser.get(seg)
else:
seg_seed, wildcard_item = None, None
@@ -272,7 +274,7 @@ class DetailerForEach:
# Convert enhanced_pil_alpha to RGBA mode
enhanced_image_alpha = tensor_convert_rgba(enhanced_image)
new_seg_image = enhanced_image.numpy() # alpha should not be applied to seg_image
# Apply the mask
mask = tensor_resize(mask, *tensor_get_size(enhanced_image))
tensor_putalpha(enhanced_image_alpha, mask)
@@ -780,6 +782,30 @@ class DenoiseScheduleHookProvider:
return (hook, )
class StepsScheduleHookProvider:
schedules = ["simple"]
@classmethod
def INPUT_TYPES(s):
return {"required": {
"schedule_for_iteration": (s.schedules,),
"target_steps": ("INT", {"default": 20, "min": 1, "max": 10000}),
},
}
RETURN_TYPES = ("PK_HOOK",)
FUNCTION = "doit"
CATEGORY = "ImpactPack/Upscale"
def doit(self, schedule_for_iteration, target_steps):
hook = None
if schedule_for_iteration == "simple":
hook = hooks.SimpleStepsScheduleHook(target_steps)
return (hook, )
class DetailerHookCombine:
@classmethod
def INPUT_TYPES(s):
@@ -1104,7 +1130,7 @@ class IterativeLatentUpscale:
new_h = h*upscale_factor
core.update_node_status(unique_id, f"Final step | x{upscale_factor:.2f}", 1.0)
print(f"IterativeLatentUpscale[Final]: {new_w:.1f}x{new_h:.1f} (scale:{upscale_factor:.2f}) ")
step_info = steps, steps
step_info = steps-1, steps
current_latent = upscaler.upscale_shape(step_info, current_latent, new_w, new_h, temp_prefix)
core.update_node_status(unique_id, "", None)
@@ -1451,7 +1477,7 @@ class SegsBitwiseAndMask:
def doit(self, segs, mask):
return (core.segs_bitwise_and_mask(segs, mask), )
class SegsBitwiseAndMaskForEach:
@classmethod
@@ -1626,7 +1652,7 @@ class SubtractMask:
"mask2": ("MASK", ),
}
}
RETURN_TYPES = ("MASK",)
FUNCTION = "doit"
@@ -1757,7 +1783,7 @@ class ImageReceiver:
return hash(image_data)
else:
return hash(image)
from server import PromptServer
@@ -119,18 +119,18 @@ def separated_sample(model, add_noise, seed, steps, cfg, sampler_name, scheduler
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):
refiner_ratio=None, refiner_model=None, refiner_clip=None, refiner_positive=None, refiner_negative=None, sigma_factor=1.0):
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]
refined_latent = nodes.KSampler().sample(model, seed, steps, cfg, sampler_name, scheduler, positive, negative, latent_image, denoise * sigma_factor)[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}")
# print(f"pre: {start_at_step} .. {end_at_step} / {advanced_steps}")
temp_latent = separated_sample(model, True, seed, advanced_steps, cfg, sampler_name, scheduler,
positive, negative, latent_image, start_at_step, end_at_step, True)
positive, negative, latent_image, start_at_step, end_at_step, True, sigma_ratio=sigma_factor)
if 'noise_mask' in latent_image:
# noise_latent = \
@@ -141,9 +141,9 @@ def ksampler_wrapper(model, seed, steps, cfg, sampler_name, scheduler, positive,
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}")
# print(f"post: {end_at_step} .. {advanced_steps + 1} / {advanced_steps}")
refined_latent = separated_sample(refiner_model, False, seed, advanced_steps, cfg, sampler_name, scheduler,
refiner_positive, refiner_negative, temp_latent, end_at_step, advanced_steps + 1, False)
refiner_positive, refiner_negative, temp_latent, end_at_step, advanced_steps + 1, False, sigma_ratio=sigma_factor)
return refined_latent
@@ -151,18 +151,19 @@ def ksampler_wrapper(model, seed, steps, cfg, sampler_name, scheduler, positive,
class KSamplerAdvancedWrapper:
params = None
def __init__(self, model, cfg, sampler_name, scheduler, positive, negative, sampler_opt=None):
self.params = model, cfg, sampler_name, scheduler, positive, negative
def __init__(self, model, cfg, sampler_name, scheduler, positive, negative, sampler_opt=None, sigma_factor=1.0):
self.params = model, cfg, sampler_name, scheduler, positive, negative, sigma_factor
self.sampler_opt = sampler_opt
def clone_with_conditionings(self, positive, negative):
model, cfg, sampler_name, scheduler, _, _ = self.params
model, cfg, sampler_name, scheduler, _, _, _ = self.params
return KSamplerAdvancedWrapper(model, cfg, sampler_name, scheduler, positive, negative, self.sampler_opt)
def sample_advanced(self, add_noise, seed, steps, latent_image, start_at_step, end_at_step, return_with_leftover_noise, hook=None,
recovery_mode="ratio additional", recovery_sampler="AUTO", recovery_sigma_ratio=1.0):
model, cfg, sampler_name, scheduler, positive, negative = self.params
model, cfg, sampler_name, scheduler, positive, negative, sigma_factor = self.params
# steps, start_at_step, end_at_step = self.compensate_denoise(steps, start_at_step, end_at_step)
if hook is not None:
model, seed, steps, cfg, sampler_name, scheduler, positive, negative, upscaled_latent = hook.pre_ksample_advanced(model, add_noise, seed, steps, cfg, sampler_name, scheduler,
@@ -183,7 +184,7 @@ class KSamplerAdvancedWrapper:
if sigma_ratio > 0:
latent_image = separated_sample(model, add_noise, seed, steps, cfg, sampler_name, scheduler,
positive, negative, latent_image, start_at_step, end_at_step,
return_with_leftover_noise, sigma_ratio=sigma_ratio, sampler_opt=self.sampler_opt)
return_with_leftover_noise, sigma_ratio=sigma_ratio * sigma_factor, sampler_opt=self.sampler_opt)
except ValueError as e:
if str(e) == 'sigma_min and sigma_max must not be 0':
print(f"\nWARN: sampling skipped - sigma_min and sigma_max are 0")
@@ -207,7 +208,7 @@ class KSamplerAdvancedWrapper:
try:
latent_image = separated_sample(model, add_noise, seed, steps, cfg, recovery_sampler, scheduler,
positive, negative, latent_image, start_at_step-compensate, end_at_step,
return_with_leftover_noise, sigma_ratio=recovery_sigma_ratio, sampler_opt=self.sampler_opt)
return_with_leftover_noise, sigma_ratio=recovery_sigma_ratio * sigma_factor, sampler_opt=self.sampler_opt)
except ValueError as e:
if str(e) == 'sigma_min and sigma_max must not be 0':
print(f"\nWARN: sampling skipped - sigma_min and sigma_max are 0")
@@ -1,5 +1,6 @@
import folder_paths
from impact.core import *
import os
import mmcv
from mmdet.apis import (inference_detector, init_detector)
@@ -415,6 +415,44 @@ class SEGSLabelFilter:
return SEGSLabelFilter.filter(segs, labels)
class SEGSLabelAssign:
@classmethod
def INPUT_TYPES(s):
return {"required": {
"segs": ("SEGS", ),
"labels": ("STRING", {"multiline": True, "placeholder": "List the label to be assigned in order of segs, separated by commas"}),
},
}
RETURN_TYPES = ("SEGS",)
RETURN_NAMES = ("SEGS",)
FUNCTION = "doit"
CATEGORY = "ImpactPack/Util"
@staticmethod
def assign(segs, labels):
labels = [label.strip() for label in labels]
if len(labels) != len(segs[1]):
print(f'Warning (SEGSLabelAssign): length of labels ({len(labels)}) != length of segs ({len(segs[1])})')
labeled_segs = []
idx = 0
for x in segs[1]:
if len(labels) > idx:
x = x._replace(label=labels[idx])
labeled_segs.append(x)
idx += 1
return ((segs[0], labeled_segs), )
def doit(self, segs, labels):
labels = labels.split(',')
return SEGSLabelAssign.assign(segs, labels)
class SEGSOrderedFilter:
@classmethod
def INPUT_TYPES(s):
@@ -67,6 +67,7 @@ class KSamplerAdvancedProvider:
"cfg": ("FLOAT", {"default": 8.0, "min": 0.0, "max": 100.0}),
"sampler_name": (comfy.samplers.KSampler.SAMPLERS, ),
"scheduler": (comfy.samplers.KSampler.SCHEDULERS, ),
"sigma_factor": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 10.0, "step": 0.01}),
"basic_pipe": ("BASIC_PIPE", )
},
"optional": {
@@ -79,9 +80,9 @@ class KSamplerAdvancedProvider:
CATEGORY = "ImpactPack/Sampler"
def doit(self, cfg, sampler_name, scheduler, basic_pipe, sampler_opt=None):
def doit(self, cfg, sampler_name, scheduler, basic_pipe, sigma_factor=1.0, sampler_opt=None):
model, _, _, positive, negative = basic_pipe
sampler = KSamplerAdvancedWrapper(model, cfg, sampler_name, scheduler, positive, negative, sampler_opt=sampler_opt)
sampler = KSamplerAdvancedWrapper(model, cfg, sampler_name, scheduler, positive, negative, sampler_opt=sampler_opt, sigma_factor=sigma_factor)
return (sampler, )
@@ -251,7 +252,7 @@ class ConcatConditionings:
RETURN_TYPES = ("CONDITIONING", )
FUNCTION = "doit"
CATEGORY = "ImpactPack/__for_testing"
CATEGORY = "ImpactPack/Util"
def doit(self, **kwargs):
conditioning_to = list(kwargs.values())[0]
@@ -495,9 +495,16 @@ def to_latent_image(pixels, vae):
y = pixels.shape[2]
if pixels.shape[1] != x or pixels.shape[2] != y:
pixels = pixels[:, :x, :y, :]
pixels = nodes.VAEEncode.vae_encode_crop_pixels(pixels)
t = vae.encode(pixels[:, :, :, :3])
return {"samples": t}
vae_encode = nodes.VAEEncode()
if hasattr(nodes.VAEEncode, "vae_encode_crop_pixels"):
# backward compatibility
print(f"[Impact Pack] ComfyUI is outdated.")
pixels = nodes.VAEEncode.vae_encode_crop_pixels(pixels)
t = vae.encode(pixels[:, :, :, :3])
return {"samples": t}
return vae_encode.encode(vae, pixels)[0]
def empty_pil_tensor(w=64, h=64):