Compare commits

...
4 Commits
Author SHA1 Message Date
Dr.Lt.Data b2f382776f FIXED: ControlNetApplySEGS - compatiblity patch
- https://github.com/ltdrdata/ComfyUI/commit/7a415f47a90915d755767c29e9f5bcc157fedefe
- Make existing ControlNetApply (SEGS) deprecated
- Rename `ControlNetApplyAdvanced (SEGS)` to `ControlNetApply (SEGS)`

https://github.com/ltdrdata/ComfyUI-Impact-Pack/issues/764
2024-10-02 01:43:33 +09:00
Dr.Lt.Data 0e4e439d39 feat: SEGS Merge 2024-09-27 23:17:35 +09:00
RyuukeisyouandRyuukeisyou 18d25a29a0 add ImpactBoolean (#759)
Co-authored-by: Ryuukeisyou <jingxiang.liu@live.com>
2024-09-27 22:55:46 +09:00
Dr.Lt.Data 2b724e5ed2 version marker 2024-09-25 11:03:07 +09:00
7 changed files with 110 additions and 10 deletions
+2 -1
View File
@@ -108,6 +108,7 @@ This custom node helps to conveniently enhance images through Detector, Detailer
* `SEGS Filter (range)` - This node retrieves only SEGs from SEGS that have a size and position 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. * `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. * `SEGSConcat` - Concatenate segs1 and segs2. If source shape of segs1 and segs2 are different from segs2 will be ignored.
* `SEGS Merge` - SEGS contains multiple SEGs. SEGS Merge integrates several SEGs into a single merged SEG. The label is changed to `merged` and the confidence becomes the minimum confidence. The applied controlnet and cropped_image are removed.
* `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. * `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. * `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.
* `Remove Image from SEGS` - Remove the image set for the SEGS that has been configured by "Set Default Image for SEGS" or SEGSDetailer. When the image for the SEGS is removed, the Detailer node will operate based on the currently processed image instead of the SEGS. * `Remove Image from SEGS` - Remove the image set for the SEGS that has been configured by "Set Default Image for SEGS" or SEGSDetailer. When the image for the SEGS is removed, the Detailer node will operate based on the currently processed image instead of the SEGS.
@@ -242,7 +243,7 @@ This custom node helps to conveniently enhance images through Detector, Detailer
### Logics (experimental) ### Logics (experimental)
* These nodes are experimental nodes designed to implement the logic for loops and dynamic switching. * These nodes are experimental nodes designed to implement the logic for loops and dynamic switching.
* `ImpactCompare`, `ImpactConditionalBranch`, `ImpactConditionalBranchSelMode`, `ImpactInt`, `ImpactValueSender`, `ImpactValueReceiver`, `ImpactImageInfo`, `ImpactMinMax`, `ImpactNeg`, `ImpactConditionalStopIteration` * `ImpactCompare`, `ImpactConditionalBranch`, `ImpactConditionalBranchSelMode`, `ImpactInt`, `ImpactBoolean`, `ImpactValueSender`, `ImpactValueReceiver`, `ImpactImageInfo`, `ImpactMinMax`, `ImpactNeg`, `ImpactConditionalStopIteration`
* `ImpactIsNotEmptySEGS` - This node returns `true` only if the input SEGS is not empty. * `ImpactIsNotEmptySEGS` - This node returns `true` only if the input SEGS is not empty.
* `ImpactIfNone` - Returns `true` if any_input is None, and returns `false` if it is not None. * `ImpactIfNone` - Returns `true` if any_input is None, and returns `false` if it is not None.
* `Queue Trigger` - When this node is executed, it adds a new queue to assist with repetitive tasks. It will only execute if the signal's status changes. * `Queue Trigger` - When this node is executed, it adds a new queue to assist with repetitive tasks. It will only execute if the signal's status changes.
+5 -2
View File
@@ -223,6 +223,7 @@ NODE_CLASS_MAPPINGS = {
"ImpactSEGSConcat": SEGSConcat, "ImpactSEGSConcat": SEGSConcat,
"ImpactSEGSPicker": SEGSPicker, "ImpactSEGSPicker": SEGSPicker,
"ImpactMakeTileSEGS": MakeTileSEGS, "ImpactMakeTileSEGS": MakeTileSEGS,
"ImpactSEGSMerge": SEGSMerge,
"SEGSDetailerForAnimateDiff": SEGSDetailerForAnimateDiff, "SEGSDetailerForAnimateDiff": SEGSDetailerForAnimateDiff,
@@ -260,6 +261,7 @@ NODE_CLASS_MAPPINGS = {
"ImpactLogicalOperators": ImpactLogicalOperators, "ImpactLogicalOperators": ImpactLogicalOperators,
"ImpactInt": ImpactInt, "ImpactInt": ImpactInt,
"ImpactFloat": ImpactFloat, "ImpactFloat": ImpactFloat,
"ImpactBoolean": ImpactBoolean,
"ImpactValueSender": ImpactValueSender, "ImpactValueSender": ImpactValueSender,
"ImpactValueReceiver": ImpactValueReceiver, "ImpactValueReceiver": ImpactValueReceiver,
"ImpactImageInfo": ImpactImageInfo, "ImpactImageInfo": ImpactImageInfo,
@@ -304,8 +306,8 @@ NODE_DISPLAY_NAME_MAPPINGS = {
"ImpactSimpleDetectorSEGS_for_AD": "Simple Detector for AnimateDiff (SEGS)", "ImpactSimpleDetectorSEGS_for_AD": "Simple Detector for AnimateDiff (SEGS)",
"ImpactSimpleDetectorSEGS": "Simple Detector (SEGS)", "ImpactSimpleDetectorSEGS": "Simple Detector (SEGS)",
"ImpactSimpleDetectorSEGSPipe": "Simple Detector (SEGS/pipe)", "ImpactSimpleDetectorSEGSPipe": "Simple Detector (SEGS/pipe)",
"ImpactControlNetApplySEGS": "ControlNetApply (SEGS)", "ImpactControlNetApplySEGS": "ControlNetApply (SEGS) - DEPRECATED",
"ImpactControlNetApplyAdvancedSEGS": "ControlNetApplyAdvanced (SEGS)", "ImpactControlNetApplyAdvancedSEGS": "ControlNetApply (SEGS)",
"ImpactIPAdapterApplySEGS": "IPAdapterApply (SEGS)", "ImpactIPAdapterApplySEGS": "IPAdapterApply (SEGS)",
"BboxDetectorCombined_v2": "BBOX Detector (combined)", "BboxDetectorCombined_v2": "BBOX Detector (combined)",
@@ -367,6 +369,7 @@ NODE_DISPLAY_NAME_MAPPINGS = {
"ImpactSEGSToMaskBatch": "SEGS to Mask Batch", "ImpactSEGSToMaskBatch": "SEGS to Mask Batch",
"ImpactSEGSPicker": "Picker (SEGS)", "ImpactSEGSPicker": "Picker (SEGS)",
"ImpactMakeTileSEGS": "Make Tile SEGS", "ImpactMakeTileSEGS": "Make Tile SEGS",
"ImpactSEGSMerge": "SEGS Merge",
"ImpactDecomposeSEGS": "Decompose (SEGS)", "ImpactDecomposeSEGS": "Decompose (SEGS)",
"ImpactAssembleSEGS": "Assemble (SEGS)", "ImpactAssembleSEGS": "Assemble (SEGS)",
+1 -1
View File
@@ -1,7 +1,7 @@
import configparser import configparser
import os import os
version_code = [7, 7, 2] version_code = [7, 9]
version = f"V{version_code[0]}.{version_code[1]}" + (f'.{version_code[2]}' if len(version_code) > 2 else '') version = f"V{version_code[0]}.{version_code[1]}" + (f'.{version_code[2]}' if len(version_code) > 2 else '')
dependency_version = 23 dependency_version = 23
+15 -2
View File
@@ -24,6 +24,8 @@ from comfy import model_management
from impact import utils from impact import utils
from impact import impact_sampling from impact import impact_sampling
from concurrent.futures import ThreadPoolExecutor from concurrent.futures import ThreadPoolExecutor
import inspect
try: try:
from comfy_extras import nodes_differential_diffusion from comfy_extras import nodes_differential_diffusion
@@ -1825,13 +1827,14 @@ class ControlNetWrapper:
class ControlNetAdvancedWrapper: class ControlNetAdvancedWrapper:
def __init__(self, control_net, strength, start_percent, end_percent, preprocessor, prev_control_net=None, def __init__(self, control_net, strength, start_percent, end_percent, preprocessor, prev_control_net=None,
original_size=None, crop_region=None, control_image=None): original_size=None, crop_region=None, control_image=None, vae=None):
self.control_net = control_net self.control_net = control_net
self.strength = strength self.strength = strength
self.preprocessor = preprocessor self.preprocessor = preprocessor
self.prev_control_net = prev_control_net self.prev_control_net = prev_control_net
self.start_percent = start_percent self.start_percent = start_percent
self.end_percent = end_percent self.end_percent = end_percent
self.vae = vae
if original_size is not None and crop_region is not None and control_image is not None: if original_size is not None and crop_region is not None and control_image is not None:
self.control_image = utils.tensor_resize(control_image, original_size[1], original_size[0]) self.control_image = utils.tensor_resize(control_image, original_size[1], original_size[0])
@@ -1872,7 +1875,17 @@ class ControlNetAdvancedWrapper:
"To use 'ControlNetAdvancedWrapper' for AnimateDiff, 'ComfyUI-Advanced-ControlNet' extension is required.") "To use 'ControlNetAdvancedWrapper' for AnimateDiff, 'ComfyUI-Advanced-ControlNet' extension is required.")
raise Exception("'ACN_AdvancedControlNetApply' node isn't installed.") raise Exception("'ACN_AdvancedControlNetApply' node isn't installed.")
else: else:
positive, negative = nodes.ControlNetApplyAdvanced().apply_controlnet(positive, negative, self.control_net, cnet_image, self.strength, self.start_percent, self.end_percent) if self.vae is not None:
apply_controlnet = nodes.ControlNetApplyAdvanced().apply_controlnet
signature = inspect.signature(apply_controlnet)
if 'vae' in signature.parameters:
positive, negative = nodes.ControlNetApplyAdvanced().apply_controlnet(positive, negative, self.control_net, cnet_image, self.strength, self.start_percent, self.end_percent, vae=self.vae)
else:
print(f"[Impact Pack] ERROR: The ComfyUI version is outdated. VAE cannot be used in ApplyControlNet.")
raise Exception("[Impact Pack] ERROR: The ComfyUI version is outdated. VAE cannot be used in ApplyControlNet.")
else:
positive, negative = nodes.ControlNetApplyAdvanced().apply_controlnet(positive, negative, self.control_net, cnet_image, self.strength, self.start_percent, self.end_percent)
return positive, negative, cnet_image_list return positive, negative, cnet_image_list
+18
View File
@@ -272,6 +272,24 @@ class ImpactFloat:
return (value, ) return (value, )
class ImpactBoolean:
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"value": ("BOOLEAN", {"default": False}),
},
}
FUNCTION = "doit"
CATEGORY = "ImpactPack/Logic"
RETURN_TYPES = ("BOOLEAN", )
def doit(self, value):
return (value, )
class ImpactValueSender: class ImpactValueSender:
@classmethod @classmethod
def INPUT_TYPES(cls): def INPUT_TYPES(cls):
+68 -3
View File
@@ -704,6 +704,68 @@ class SEGSToMaskBatch:
return (mask_batch,) return (mask_batch,)
class SEGSMerge:
@classmethod
def INPUT_TYPES(s):
return {"required": {
"segs": ("SEGS", ),
},
}
RETURN_TYPES = ("SEGS",)
FUNCTION = "doit"
CATEGORY = "ImpactPack/Util"
DESCRIPTION = "SEGS contains multiple SEGs. SEGS Merge integrates several SEGs into a single merged SEG. The label is changed to `merged` and the confidence becomes the minimum confidence. The applied controlnet and cropped_image are removed."
def doit(self, segs):
crop_left = sys.maxsize
crop_right = 0
crop_top = sys.maxsize
crop_bottom = 0
bbox_left = sys.maxsize
bbox_right = 0
bbox_top = sys.maxsize
bbox_bottom = 0
min_confidence = 1.0
for seg in segs[1]:
cx1 = seg.crop_region[0]
cy1 = seg.crop_region[1]
cx2 = seg.crop_region[2]
cy2 = seg.crop_region[3]
bx1 = seg.bbox[0]
by1 = seg.bbox[1]
bx2 = seg.bbox[2]
by2 = seg.bbox[3]
crop_left = min(crop_left, cx1)
crop_top = min(crop_top, cy1)
crop_right = max(crop_right, cx2)
crop_bottom = max(crop_bottom, cy2)
bbox_left = min(bbox_left, bx1)
bbox_top = min(bbox_top, by1)
bbox_right = max(bbox_right, bx2)
bbox_bottom = max(bbox_bottom, by2)
min_confidence = min(min_confidence, seg.confidence)
combined_mask = core.segs_to_combined_mask(segs)
cropped_mask = combined_mask[crop_top:crop_bottom, crop_left:crop_right]
cropped_mask = cropped_mask.unsqueeze(0)
crop_region = [crop_left, crop_top, crop_right, crop_bottom]
bbox = [bbox_left, bbox_top, bbox_right, bbox_bottom]
seg = SEG(None, cropped_mask, min_confidence, crop_region, bbox, 'merged', None)
return ((segs[0], [seg]),)
class SEGSConcat: class SEGSConcat:
@classmethod @classmethod
def INPUT_TYPES(s): def INPUT_TYPES(s):
@@ -1300,6 +1362,8 @@ class ControlNetApplySEGS:
RETURN_TYPES = ("SEGS",) RETURN_TYPES = ("SEGS",)
FUNCTION = "doit" FUNCTION = "doit"
DEPRECATED = True
CATEGORY = "ImpactPack/Util" CATEGORY = "ImpactPack/Util"
@staticmethod @staticmethod
@@ -1327,7 +1391,8 @@ class ControlNetApplyAdvancedSEGS:
}, },
"optional": { "optional": {
"segs_preprocessor": ("SEGS_PREPROCESSOR",), "segs_preprocessor": ("SEGS_PREPROCESSOR",),
"control_image": ("IMAGE",) "control_image": ("IMAGE",),
"vae": ("VAE",)
} }
} }
@@ -1337,13 +1402,13 @@ class ControlNetApplyAdvancedSEGS:
CATEGORY = "ImpactPack/Util" CATEGORY = "ImpactPack/Util"
@staticmethod @staticmethod
def doit(segs, control_net, strength, start_percent, end_percent, segs_preprocessor=None, control_image=None): def doit(segs, control_net, strength, start_percent, end_percent, segs_preprocessor=None, control_image=None, vae=None):
new_segs = [] new_segs = []
for seg in segs[1]: for seg in segs[1]:
control_net_wrapper = core.ControlNetAdvancedWrapper(control_net, strength, start_percent, end_percent, segs_preprocessor, control_net_wrapper = core.ControlNetAdvancedWrapper(control_net, strength, start_percent, end_percent, segs_preprocessor,
seg.control_net_wrapper, original_size=segs[0], crop_region=seg.crop_region, seg.control_net_wrapper, original_size=segs[0], crop_region=seg.crop_region,
control_image=control_image) control_image=control_image, vae=vae)
new_seg = SEG(seg.cropped_image, seg.cropped_mask, seg.confidence, seg.crop_region, seg.bbox, seg.label, control_net_wrapper) 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) new_segs.append(new_seg)
+1 -1
View File
@@ -1,7 +1,7 @@
[project] [project]
name = "comfyui-impact-pack" name = "comfyui-impact-pack"
description = "This extension offers various detector nodes and detailer nodes that allow you to configure a workflow that automatically enhances facial details. And provide iterative upscaler." description = "This extension offers various detector nodes and detailer nodes that allow you to configure a workflow that automatically enhances facial details. And provide iterative upscaler."
version = "7.7.1" version = "7.9"
license = { file = "LICENSE.txt" } license = { file = "LICENSE.txt" }
dependencies = ["segment-anything", "scikit-image", "piexif", "transformers", "opencv-python-headless", "GitPython", "scipy>=1.11.4"] dependencies = ["segment-anything", "scikit-image", "piexif", "transformers", "opencv-python-headless", "GitPython", "scipy>=1.11.4"]