diff --git a/README.md b/README.md
index 35425014..53a47a25 100644
--- a/README.md
+++ b/README.md
@@ -1,30 +1,56 @@
# ComfyUI-Impact-Pack
+This custom node helps to conveniently enhance images through Detector, Detailer, Upscaler, Pipe, and more.
+
## Custom nodes pack for ComfyUI
# Features
-* MMDetLoader - Load MMDet model
* SAMLoader - Load SAM model
-* ONNXLoader - Load ONNX model
-* SegmDetectorCombined - Detect segmentation and return mask from input image.
-* BboxDetectorCombined - Detect bbox(bounding box) and return mask from input image.
-* SamDetectorCombined - Using the technology of SAM, extract the segment at the location indicated by the input SEGS on the input image, and output it as a unified mask.
-* BitwiseAndMask - Perform 'bitwise and' operations between 2 masks
-* SubtractMask - Perform subtract operations between 2 masks
-* SegmDetectorForEach - Detect segmentation and return SEGS from input image.
-* BboxDetectorForEach - Detect bbox(bounding box) and return SEGS from input image.
-* ONNXDetectorForeach - Using the ONNX model, identify the bbox and retrieve the SEGS from the input image
-* DetailerForEach - Refine image rely on SEGS.
-* DetailerForEachDebug - Refine image rely on SEGS. Additionally, you can monitor cropped image and refined image of cropped image.
+* MMDetDetectorProvider - Load MMDet model to provide BBOX_DETECTOR, SEGM_DETECTOR
+* ONNXDetectorProvider - Load ONNX model to provide SEGM_DETECTOR
+* CLIPSegDetectorProvider - CLIPSeg wrapper to provide BBOX_DETECTOR
+* SEGM Detector (combined) - Detect segmentation and return mask from input image.
+* BBOX Detector (combined) - Detect bbox(bounding box) and return mask from input image.
+* SAMDetector (combined) - Using the technology of SAM, extract the segment at the location indicated by the input SEGS on the input image, and output it as a unified mask.
+* Bitwise(SEGS & SEGS) - Perform 'bitwise and' operations between 2 SEGS.
+* Bitwise(SEGS - SEGS) - Perform subtract operations between 2 SEGS.
+* Bitwise(SEGS & MASK) - Perform a bitwise AND operation on SEGS and MASK.
+* Bitwise(MASK & MASK) - Perform 'bitwise and' operations between 2 masks
+* Bitwise(MASK - MASK) - Perform subtract operations between 2 masks
+* SEGM Detector (SEGS) - Detect segmentation and return SEGS from input image.
+* BBOX Detector (SEGS) - Detect bbox(bounding box) and return SEGS from input image.
+* ONNX Detector (SEGS) - Using the ONNX model, identify the bbox and retrieve the SEGS from the input image
+* Detailer (SEGS) - Refine image rely on SEGS.
+* DetailerDebug (SEGS) - Refine image rely on SEGS. Additionally, you can monitor cropped image and refined image of cropped image.
* The 'DetailerForEach' and 'DetailerForEachDebug' now support an 'external_seed' that is obtained from the Seed node on the [WAS suite](https://github.com/WASasquatch/was-node-suite-comfyui)
* To prevent the regeneration caused by the seed that does not change every time when using 'external_seed', please disable the 'seed random generate' option in the 'Detailer...' node
-* BitwiseAndMaskForEach - Perform 'bitwise and' operations between 2 SEGS.
-* BitwiseAndMaskForEach - Perform subtract operations between 2 SEGS.
-* Segs & Masks - Perform a bitwise AND operation on SEGS and MASK.
-* MaskToSegs - This node generates SEGS based on the mask.
+* MASK to SEGS - This node generates SEGS based on the mask.
* ToBinaryMask - This node separates the mask generated with alpha values between 0 and 255 into 0 and 255. The non-zero parts are always set to 255.
* EmptySEGS - This node provides a empty SEGS.
* MaskPainter - This node provides a feature to draw masks.
+* FaceDetailer - This is a node that can easily detect faces and improve them.
+* FaceDetailer (pipe) - This is a node that can easily detect faces and improve them. (for multipass)
+* Pipe nodes
+ * ToDetailerPipe, FromDetailerPipe - These nodes are used to bundle multiple inputs used in the detailer, such as models and vae, ..., into a single DETAILER_PIPE or extract the elements that are bundled in the DETAILER_PIPE.
+ * ToBasicPipe, FromBasicPipe - These nodes are used to bundle model, clip, vae, positive conditioning, and negative conditioning into a single BASIC_PIPE, or extract each element from the BASIC_PIPE.
+ * EditBasicPipe, EditDetailerPipe - These nodes are used to replace some elements in BASIC_PIPE or DETAILER_PIPE.
+* Latent Scale (on Pixel Space) - This node converts latent to pixel space, upscales it, and then converts it back to latent.
+ * If upscale_model_opt is provided, it uses the model to upscale the pixel and then downscales it using the interpolation method provided in scale_method to the target resolution.
+* PixelKSampleUpscalerProvider - An upscaler is provided that converts latent to pixels using VAEDecode, performs upscaling, converts back to latent using VAEEncode, and then performs k-sampling. This upscaler can be attached to nodes such as 'Iterative Upscale' for use.
+ * Similar to 'Latent Scale (on Pixel Space)', if upscale_model_opt is provided, it performs pixel upscaling using the model.
+* Iterative Upscale (Latent) - The upscaler takes the input upscaler and splits the scale_factor into steps, then iteratively performs upscaling.
+This takes latent as input and outputs latent as the result.
+* Iterative Upscale (Image) - The upscaler takes the input upscaler and splits the scale_factor into steps, then iteratively performs upscaling. This takes image as input and outputs image as the result.
+ * Internally, this node uses 'Iterative Upscale (Latent)'.
+
+# Depercated
+* The following nodes have been kept only for compatibility with existing workflows, and are no longer supported. Please replace them with new nodes.
+ * MMDetLoader -> MMDetDetectorProvider
+ * SegsMaskCombine -> SEGS to MASK (combined)
+ * BboxDetectorForEach -> BBOX Detector (SEGS)
+ * SegmDetectorForEach -> SEGM Detector (SEGS)
+ * BboxDetectorCombined -> BBOX Detector (combined)
+ * SegmDetectorCombined -> SEGM Detector (combined)
# Installation
@@ -61,65 +87,52 @@
# How to use (DDetailer feature)
#### 1. Basic auto face detection and refine exapmle.
-
+
* The face that has been damaged due to low resolution is restored with high resolution by generating and synthesizing it, in order to restore the details.
-* The FaceDetailer node is a combination of a Detector node for face detection and a Detailer node for image enhancement. See the [Advanced Tutorial](tutorial/advanced.md) for a more detailed explanation.
+* The FaceDetailer node is a combination of a Detector node for face detection and a Detailer node for image enhancement. See the [Advanced Tutorial](https://github.com/ltdrdata/ComfyUI-extension-tutorials/raw/Main/ComfyUI-Impact-Pack/tutorial/advanced.md) for a more detailed explanation.
* Pass the MMDetLoader 's bbox model and the detection model loaded by SAMLoader to FaceDetailer . Since it performs the function of KSampler for image enhancement, it overlaps with KSampler's options.
* The MASK output of FaceDetailer provides a visualization of where the detected and enhanced areas are.
- 
+ 
* You can see that the face in the image on the left has increased detail as in the image on the right.
#### 2. 2Pass refine (restore a severely damaged face)
-
+
* Although two FaceDetailers can be attached together for a 2-pass configuration, various common inputs used in KSampler can be passed through DETAILER_PIPE, so FaceDetailerPipe can be used to configure easily.
* In 1pass, only rough outline recovery is required, so restore with a reasonable resolution and low options. However, if you increase the dilation at this time, not only the face but also the surrounding parts are included in the recovery range, so it is useful when you need to reshape the face other than the facial part.
-  
+  
* In the first stage, the severely damaged face is restored to some extent, and in the second stage, the details are restored
-#### 3. Face Bbox(bounding box) + Person silhouette segmantation (prevent distortion of the background.)
-
- 
+#### 3. Face Bbox(bounding box) + Person silhouette segmentation (prevent distortion of the background.)
+
+ 
* Facial synthesis that emphasizes details is delicately aligned with the contours of the face, and it can be observed that it does not affect the image outside of the face.
* The BBoxDetectorForEach node is used to detect faces, and the SAMDetectorCombined node is used to find the segment related to the detected face. By using the Segs & Mask node with the two masks obtained in this way, an accurate mask that intersects based on segs can be generated. If this generated mask is input to the DetailerForEach node, only the target area can be created in high resolution from the image and then composited.
-#### Mask feature
+#### 4. Iterative Upscale
+
+
+* The IterativeUpscale node is a node that enlarges an image/latent by a scale_factor. In this process, the upscale is carried out progressively by dividing it into steps.
+* IterativeUpscale takes an Upscaler as an input, similar to a plugin, and uses it during each iteration. PixelKSampleUpscalerProvider is an Upscaler that converts the latent representation to pixel space and applies ksampling.
+ * The upscale_model_opt is an optional parameter that determines whether to use the upscale function of the model base if available. Using the upscale function of the model base can significantly reduce the number of iterative steps required. If an x2 upscaler is used, the image/latent is first upscaled by a factor of 2 and then downscaled to the target scale at each step before further processing is done.
-
+* The following image is an image of 304x512 pixels and the same image scaled up to three times its original size using IterativeUpscale.
-* SEGS generated by the ...Detector nodes can also be converted to a MASK using nodes such as SegsCombineMask and used accordingly.
+ 
-#### SAMDetection Application
-
-  
-
-* By using the segmentation feature of SAM, it is possible to automatically generate the optimal mask and apply it to areas other than the face. The image on the left is the original image, the middle image is the result of applying a mask to the alpha channel, and the image on the right is the final result.
-
-* The "detection_hint" in "SAMDetectorCombined" is a specifier that indicates which points should be included in the segmentation when performing segmentation. "center-1" specifies one point in the center of the mask, "horizontal-2" specifies two points on the center horizontal line, "vertical-2" specifies two points on the center vertical line, "rectangle-4" specifies four points in a rectangular shape inside the mask, and "diamond-4" specifies four points in a diamond shape centered around the center point.
-
-* Unlike in face detection, for non-rigid objects, the center point may not always be the segmentation area, so be careful not to assume that the center point is always the segmentation area.
-
-#### Mask Painter
-
-
-* Click "Edit mask" button
-* **Don't connect to 'mask_image' input**
-
-
-* You can draw mask on Mask Painter
-* Currently, this editor only provides basic functionalities
-
-
-* When used together, SAMDetector and MaskPainter can be used to enhance specific elements of an image.
# Others Tutorials
-* [Advanced Tutorial](tutorial/advanced.md)
-* [Mask Pointer](tutorial/maskpointer.md)
-* [ONNX Tutorial](tutorial/ONNX.md)
+* [ComfyUI-extension-tutorials/ComfyUI-Impact-Pack](https://github.com/ltdrdata/ComfyUI-extension-tutorials/tree/Main/ComfyUI-Impact-Pack)
+* [Advanced Tutorial](https://github.com/ltdrdata/ComfyUI-extension-tutorials/blob/Main/ComfyUI-Impact-Pack/tutorial/advanced.md)
+* [SAM Application](https://github.com/ltdrdata/ComfyUI-extension-tutorials/blob/Main/ComfyUI-Impact-Pack/tutorial/sam.md)
+* [Mask Painter](https://github.com/ltdrdata/ComfyUI-extension-tutorials/blob/Main/ComfyUI-Impact-Pack/tutorial/maskpainter.md)
+* [Mask Pointer](https://github.com/ltdrdata/ComfyUI-extension-tutorials/blob/Main/ComfyUI-Impact-Pack/tutorial/maskpointer.md)
+* [ONNX Tutorial](https://github.com/ltdrdata/ComfyUI-extension-tutorials/blob/Main/ComfyUI-Impact-Pack/tutorial/ONNX.md)
+* [CLIPSeg Tutorial](https://github.com/ltdrdata/ComfyUI-extension-tutorials/blob/Main/ComfyUI-Impact-Pack/tutorial/clipseg.md)
# Credits
@@ -136,4 +149,6 @@ hysts/[anime-face-detector](https://github.com/hysts/anime-face-detector) - Crea
open-mmlab/[mmdetection](https://github.com/open-mmlab/mmdetection) - Object detection toolset. `dd-person_mask2former` was trained via transfer learning using their [R-50 Mask2Former instance segmentation model](https://github.com/open-mmlab/mmdetection/tree/master/configs/mask2former#instance-segmentation) as a base.
+biegert/[ComfyUI-CLIPSeg](https://github.com/biegert/ComfyUI-CLIPSeg) - This is a custom node that enables the use of CLIPSeg technology, which can find segments through prompts, in ComfyUI.
+
WASasquatch/[was-node-suite-comfyui](https://github.com/WASasquatch/was-node-suite-comfyui) - A powerful custom node extensions of ComfyUI.
diff --git a/__init__.py b/__init__.py
index a0cf4381..947c60f6 100644
--- a/__init__.py
+++ b/__init__.py
@@ -1,21 +1,156 @@
import shutil
import folder_paths
-import os, sys, subprocess
-
-
-# ensure .js
-print("### Loading: ComfyUI-Impact-Pack")
+import os
+import sys
comfy_path = os.path.dirname(folder_paths.__file__)
+impact_path = os.path.dirname(__file__)
+
+sys.path.append(impact_path)
+
+import impact_config
+print(f"### Loading: ComfyUI-Impact-Pack ({impact_config.version})")
+
+# ensure dependency
+if impact_config.read_config()[1] < impact_config.dependency_version:
+ import install # to install dependencies
+# Core
+# recheck dependencies for colab
+try:
+ import folder_paths
+ import torch
+ import cv2
+ import mmcv
+ import numpy as np
+ from mmdet.apis import (inference_detector, init_detector)
+ import comfy.samplers
+ import comfy.sd
+ import warnings
+ from PIL import Image, ImageFilter
+ from mmdet.evaluation import get_classes
+ from skimage.measure import label, regionprops
+ from collections import namedtuple
+except:
+ print("### ComfyUI-Impact-Pack: Reinstall dependencies (several dependencies are missing.)")
+ import install
+
+import impact_server # to load server api
def setup_js():
- impact_path = os.path.dirname(__file__)
- js_dest_path = os.path.join(comfy_path, "web", "extensions", "core")
+ # remove garbage
+ old_js_path = os.path.join(comfy_path, "web", "extensions", "core", "impact-pack.js")
+ if os.path.exists(old_js_path):
+ os.remove(old_js_path)
+
+ # setup js
+ js_dest_path = os.path.join(comfy_path, "web", "extensions", "impact-pack")
+ if not os.path.exists(js_dest_path):
+ os.makedirs(js_dest_path)
js_src_path = os.path.join(impact_path, "js", "impact-pack.js")
shutil.copy(js_src_path, js_dest_path)
setup_js()
-from .impact_pack import NODE_CLASS_MAPPINGS
+import legacy_nodes
+from impact_pack import *
+from detectors import *
+from impact_pipe import *
-__all__ = ['NODE_CLASS_MAPPINGS']
\ No newline at end of file
+NODE_CLASS_MAPPINGS = {
+ "SAMLoader": SAMLoader,
+ "MMDetDetectorProvider": MMDetDetectorProvider,
+ "CLIPSegDetectorProvider": CLIPSegDetectorProvider,
+ "ONNXDetectorProvider": ONNXDetectorProvider,
+
+ "BitwiseAndMaskForEach": BitwiseAndMaskForEach,
+ "SubtractMaskForEach": SubtractMaskForEach,
+
+ "DetailerForEach": DetailerForEach,
+ "DetailerForEachDebug": DetailerForEachTest,
+ "DetailerForEachPipe": DetailerForEachPipe,
+ "DetailerForEachDebugPipe": DetailerForEachTestPipe,
+
+ "SAMDetectorCombined": SAMDetectorCombined,
+
+ "FaceDetailer": FaceDetailer,
+ "FaceDetailerPipe": FaceDetailerPipe,
+
+ "ToDetailerPipe": ToDetailerPipe ,
+ "FromDetailerPipe": FromDetailerPipe,
+ "ToBasicPipe": ToBasicPipe,
+ "FromBasicPipe": FromBasicPipe,
+ "BasicPipeToDetailerPipe": BasicPipeToDetailerPipe,
+ "DetailerPipeToBasicPipe": DetailerPipeToBasicPipe,
+ "EditBasicPipe": EditBasicPipe,
+ "EditDetailerPipe": EditDetailerPipe,
+
+ "LatentPixelScale": LatentPixelScale,
+ "PixelKSampleUpscalerProvider": PixelKSampleUpscalerProvider,
+ "PixelKSampleUpscalerProviderPipe": PixelKSampleUpscalerProviderPipe,
+ "IterativeLatentUpscale": IterativeLatentUpscale,
+ "IterativeImageUpscale": IterativeImageUpscale,
+
+ "BitwiseAndMask": BitwiseAndMask,
+ "SubtractMask": SubtractMask,
+ "Segs & Mask": SegsBitwiseAndMask,
+ "EmptySegs": EmptySEGS,
+
+ "MaskToSEGS": MaskToSEGS,
+ "ToBinaryMask": ToBinaryMask,
+
+ "MaskPainter": MaskPainter,
+
+ "BboxDetectorSEGS": BboxDetectorForEach,
+ "SegmDetectorSEGS": SegmDetectorForEach,
+ "ONNXDetectorSEGS": ONNXDetectorForEach,
+
+ "BboxDetectorCombined": BboxDetectorCombined,
+ "SegmDetectorCombined": SegmDetectorCombined,
+ "SegsToCombinedMask": SegsToCombinedMask,
+
+ "MMDetLoader": legacy_nodes.MMDetLoader,
+ "SegsMaskCombine": legacy_nodes.SegsMaskCombine,
+ "BboxDetectorForEach": legacy_nodes.BboxDetectorForEach,
+ "SegmDetectorForEach": legacy_nodes.SegmDetectorForEach,
+ "BboxDetectorCombined": legacy_nodes.BboxDetectorCombined,
+ "SegmDetectorCombined": legacy_nodes.SegmDetectorCombined,
+}
+
+NODE_DISPLAY_NAME_MAPPINGS = {
+ "BboxDetectorSEGS": "BBOX Detector (SEGS)",
+ "SegmDetectorSEGS": "SEGM Detector (SEGS)",
+ "ONNXDetectorSEGS": "ONNX Detector (SEGS)",
+ "BboxDetectorCombined": "BBOX Detector (combined)",
+ "SegmDetectorCombined": "SEGM Detector (combined)",
+ "SegsToCombinedMask": "SEGS to MASK (combined)",
+ "MaskToSEGS": "MASK to SEGS",
+ "BitwiseAndMaskForEach": "Bitwise(SEGS & SEGS)",
+ "SubtractMaskForEach": "Bitwise(SEGS - SEGS)",
+ "Segs & Mask": "Bitwise(SEGS & MASK)",
+ "BitwiseAndMask": "Bitwise(MASK & MASK)",
+ "SubtractMask": "Bitwise(MASK - MASK)",
+ "DetailerForEach": "Detailer (SEGS)",
+ "DetailerForEachPipe": "Detailer (SEGS/pipe)",
+ "DetailerForEachDebug": "DetailerDebug (SEGS)",
+ "DetailerForEachDebugPipe": "DetailerDebug (SEGS/pipe)",
+ "SAMDetectorCombined": "SAMDetector (combined)",
+ "FaceDetailerPipe": "FaceDetailer (pipe)",
+
+ "BasicPipeToDetailerPipe": "BasicPipe -> DetailerPipe",
+ "DetailerPipeToBasicPipe": "DetailerPipe -> BasicPipe",
+ "EditBasicPipe": "Edit BasicPipe",
+ "EditDetailerPipe": "Edit DetailerPipe",
+
+ "LatentPixelScale": "Latent Scale (on Pixel Space)",
+ "IterativeLatentUpscale": "Iterative Upscale (Latent)",
+ "IterativeImageUpscale": "Iterative Upscale (Image)",
+
+ "MMDetLoader": "MMDetLoader (Legacy)",
+ "SegsMaskCombine": "SegsMaskCombine (Legacy)",
+ "BboxDetectorForEach": "BboxDetectorForEach (Legacy)",
+ "SegmDetectorForEach": "SegmDetectorForEach (Legacy)",
+ "BboxDetectorCombined": "BboxDetectorCombined (Legacy)",
+ "SegmDetectorCombined": "SegmDetectorCombined (Legacy)",
+}
+
+__all__ = ['NODE_CLASS_MAPPINGS', 'NODE_DISPLAY_NAME_MAPPINGS']
diff --git a/detectors.py b/detectors.py
new file mode 100644
index 00000000..47354be7
--- /dev/null
+++ b/detectors.py
@@ -0,0 +1,109 @@
+import impact_core as core
+
+
+class SAMDetectorCombined:
+ @classmethod
+ def INPUT_TYPES(s):
+ return {"required": {
+ "sam_model": ("SAM_MODEL", ),
+ "segs": ("SEGS", ),
+ "image": ("IMAGE", ),
+ "detection_hint": (["center-1", "horizontal-2", "vertical-2", "rect-4", "diamond-4", "mask-area",
+ "mask-points", "mask-point-bbox", "none"],),
+ "dilation": ("INT", {"default": 0, "min": 0, "max": 255, "step": 1}),
+ "threshold": ("FLOAT", {"default": 0.93, "min": 0.0, "max": 1.0, "step": 0.01}),
+ "bbox_expansion": ("INT", {"default": 0, "min": 0, "max": 1000, "step": 1}),
+ "mask_hint_threshold": ("FLOAT", {"default": 0.7, "min": 0.0, "max": 1.0, "step": 0.01}),
+ "mask_hint_use_negative": (["False", "Small", "Outter"], )
+ }
+ }
+
+ RETURN_TYPES = ("MASK",)
+ FUNCTION = "doit"
+
+ CATEGORY = "ImpactPack/Detector"
+
+ def doit(self, sam_model, segs, image, detection_hint, dilation,
+ threshold, bbox_expansion, mask_hint_threshold, mask_hint_use_negative):
+ return (core.make_sam_mask(sam_model, segs, image, detection_hint, dilation,
+ threshold, bbox_expansion, mask_hint_threshold, mask_hint_use_negative), )
+
+class BboxDetectorForEach:
+ @classmethod
+ def INPUT_TYPES(s):
+ return {"required": {
+ "bbox_detector": ("BBOX_DETECTOR", ),
+ "image": ("IMAGE", ),
+ "threshold": ("FLOAT", {"default": 0.5, "min": 0.0, "max": 1.0, "step": 0.01}),
+ "dilation": ("INT", {"default": 10, "min": 0, "max": 255, "step": 1}),
+ "crop_factor": ("FLOAT", {"default": 3.0, "min": 1.0, "max": 10, "step": 0.1}),
+ }
+ }
+
+ RETURN_TYPES = ("SEGS", )
+ FUNCTION = "doit"
+
+ CATEGORY = "ImpactPack/Detector"
+
+ def doit(self, bbox_detector, image, threshold, dilation, crop_factor):
+ segs = bbox_detector.detect(image, threshold, dilation, crop_factor)
+ return (segs, )
+
+
+class SegmDetectorForEach:
+ @classmethod
+ def INPUT_TYPES(s):
+ return {"required": {
+ "segm_detector": ("SEGM_DETECTOR", ),
+ "image": ("IMAGE", ),
+ "threshold": ("FLOAT", {"default": 0.5, "min": 0.0, "max": 1.0, "step": 0.01}),
+ "dilation": ("INT", {"default": 10, "min": 0, "max": 255, "step": 1}),
+ "crop_factor": ("FLOAT", {"default": 3.0, "min": 1.0, "max": 10, "step": 0.1}),
+ }
+ }
+
+ RETURN_TYPES = ("SEGS", )
+ FUNCTION = "doit"
+
+ CATEGORY = "ImpactPack/Detector"
+
+ def doit(self, segm_detector, image, threshold, dilation, crop_factor):
+ segs = segm_detector.detect(image, threshold, dilation, crop_factor)
+ return (segs, )
+
+
+class SegmDetectorCombined:
+ @classmethod
+ def INPUT_TYPES(s):
+ return {"required": {
+ "segm_detector": ("SEGM_DETECTOR", ),
+ "image": ("IMAGE", ),
+ "threshold": ("FLOAT", {"default": 0.5, "min": 0.0, "max": 1.0, "step": 0.01}),
+ "dilation": ("INT", {"default": 0, "min": 0, "max": 255, "step": 1}),
+ }
+ }
+
+ RETURN_TYPES = ("MASK",)
+ FUNCTION = "doit"
+
+ CATEGORY = "ImpactPack/Detector"
+
+ def doit(self, segm_detector, image, threshold, dilation):
+ mask = segm_detector.detect_combined(image, threshold, dilation)
+ return (mask,)
+
+
+class BboxDetectorCombined(SegmDetectorCombined):
+ @classmethod
+ def INPUT_TYPES(s):
+ return {"required": {
+ "bbox_detector": ("BBOX_DETECTOR", ),
+ "image": ("IMAGE", ),
+ "threshold": ("FLOAT", {"default": 0.5, "min": 0.0, "max": 1.0, "step": 0.01}),
+ "dilation": ("INT", {"default": 4, "min": 0, "max": 255, "step": 1}),
+ }
+ }
+
+ def doit(self, bbox_detector, image, threshold, dilation):
+ mask = bbox_detector.detect_combined(image, threshold, dilation)
+ return (mask,)
diff --git a/impact_config.py b/impact_config.py
index 1e0fd647..b32a345d 100644
--- a/impact_config.py
+++ b/impact_config.py
@@ -1,6 +1,8 @@
import configparser
import os
+version = "V2.0"
+
dependency_version = 1
my_path = os.path.dirname(__file__)
diff --git a/impact_core.py b/impact_core.py
new file mode 100644
index 00000000..4900d10a
--- /dev/null
+++ b/impact_core.py
@@ -0,0 +1,748 @@
+import os
+import sys
+import mmcv
+from mmdet.apis import (inference_detector, init_detector)
+from mmdet.evaluation import get_classes
+from segment_anything import SamPredictor
+import cv2
+
+from impact_utils import *
+from collections import namedtuple
+import numpy as np
+from skimage.measure import label, regionprops
+
+main_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
+sys.path.append(os.path.dirname(__file__))
+sys.path.append(main_dir)
+
+import nodes
+import onnx
+import comfy_extras.nodes_upscale_model as model_upscale
+
+SEG = namedtuple("SEG", ['cropped_image', 'cropped_mask', 'confidence', 'crop_region', 'bbox', 'label'],
+ defaults=[None])
+
+
+class NO_BBOX_DETECTOR:
+ pass
+
+
+class NO_SEGM_DETECTOR:
+ pass
+
+
+def load_mmdet(model_path):
+ model_config = os.path.splitext(model_path)[0] + ".py"
+ model = init_detector(model_config, model_path, device="cpu")
+ return model
+
+
+def create_segmasks(results):
+ bboxs = results[1]
+ segms = results[2]
+ confidence = results[3]
+
+ results = []
+ for i in range(len(segms)):
+ item = (bboxs[i], segms[i].astype(np.float32), confidence[i])
+ results.append(item)
+ return results
+
+
+def inference_segm_old(model, image, conf_threshold):
+ image = image.numpy()[0] * 255
+ mmdet_results = inference_detector(model, image)
+
+ bbox_results, segm_results = mmdet_results
+ label = "A"
+
+ classes = get_classes("coco")
+ labels = [
+ np.full(bbox.shape[0], i, dtype=np.int32)
+ for i, bbox in enumerate(bbox_results)
+ ]
+ n, m = bbox_results[0].shape
+ if n == 0:
+ return [[], [], []]
+ labels = np.concatenate(labels)
+ bboxes = np.vstack(bbox_results)
+ segms = mmcv.concat_list(segm_results)
+ filter_idxs = np.where(bboxes[:, -1] > conf_threshold)[0]
+ results = [[], [], []]
+ for i in filter_idxs:
+ results[0].append(label + "-" + classes[labels[i]])
+ results[1].append(bboxes[i])
+ results[2].append(segms[i])
+
+ return results
+
+
+def inference_segm(image, modelname, conf_thres, lab="A"):
+ image = image.numpy()[0] * 255
+ mmdet_results = inference_detector(modelname, image).pred_instances
+ bboxes = mmdet_results.bboxes.numpy()
+ segms = mmdet_results.masks.numpy()
+ scores = mmdet_results.scores.numpy()
+
+ classes = get_classes("coco")
+
+ n, m = bboxes.shape
+ if n == 0:
+ return [[], [], [], []]
+ labels = mmdet_results.labels
+ filter_inds = np.where(mmdet_results.scores > conf_thres)[0]
+ results = [[], [], [], []]
+ for i in filter_inds:
+ results[0].append(lab + "-" + classes[labels[i]])
+ results[1].append(bboxes[i])
+ results[2].append(segms[i])
+ results[3].append(scores[i])
+
+ return results
+
+
+def inference_bbox(modelname, image, conf_threshold):
+ image = image.numpy()[0] * 255
+ label = "A"
+ output = inference_detector(modelname, image).pred_instances
+ cv2_image = np.array(image)
+ cv2_image = cv2_image[:, :, ::-1].copy()
+ cv2_gray = cv2.cvtColor(cv2_image, cv2.COLOR_BGR2GRAY)
+
+ segms = []
+ for x0, y0, x1, y1 in output.bboxes:
+ cv2_mask = np.zeros(cv2_gray.shape, np.uint8)
+ cv2.rectangle(cv2_mask, (int(x0), int(y0)), (int(x1), int(y1)), 255, -1)
+ cv2_mask_bool = cv2_mask.astype(bool)
+ segms.append(cv2_mask_bool)
+
+ n, m = output.bboxes.shape
+ if n == 0:
+ return [[], [], [], []]
+
+ bboxes = output.bboxes.numpy()
+ scores = output.scores.numpy()
+ filter_idxs = np.where(scores > conf_threshold)[0]
+ results = [[], [], [], []]
+ for i in filter_idxs:
+ results[0].append(label)
+ results[1].append(bboxes[i])
+ results[2].append(segms[i])
+ results[3].append(scores[i])
+
+ return results
+
+
+def gen_detection_hints_from_mask_area(x, y, mask, threshold, use_negative):
+ points = []
+ plabs = []
+
+ # minimum sampling step >= 3
+ 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))
+ plabs.append(1)
+ elif use_negative and mask[i][j] == 0:
+ points.append((x+j, y+i))
+ plabs.append(0)
+
+ return points, plabs
+
+
+def gen_negative_hints(w, h, x1, y1, x2, y2):
+ npoints = []
+ 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):
+ npoints.append((j, i))
+ nplabs.append(0)
+
+ return npoints, nplabs
+
+
+def enhance_detail(image, model, vae, guide_size, guide_size_for, bbox, seed, steps, cfg, sampler_name, scheduler,
+ positive, negative, denoise, noise_mask, force_inpaint):
+ h = image.shape[1]
+ w = image.shape[2]
+
+ bbox_h = bbox[3] - bbox[1]
+ bbox_w = bbox[2] - bbox[0]
+
+ # Skip processing if the detected bbox is already larger than the guide_size
+ if bbox_h >= guide_size and bbox_w >= guide_size:
+ print(f"Detailer: segment skip")
+ None
+
+ if guide_size_for == "bbox":
+ # Scale up based on the smaller dimension between width and height.
+ upscale = guide_size / min(bbox_w, bbox_h)
+ else:
+ # for cropped_size
+ upscale = guide_size / min(w, h)
+
+ new_w = int(((w * upscale) // 8) * 8)
+ new_h = int(((h * upscale) // 8) * 8)
+
+ if not force_inpaint:
+ if upscale <= 1.0:
+ print(f"Detailer: segment skip [determined upscale factor={upscale}]")
+ return None
+
+ if new_w == 0 or new_h == 0:
+ print(f"Detailer: segment skip [zero size={new_w, new_h}]")
+ return None
+ else:
+ if upscale <= 1.0 or new_w == 0 or new_h == 0:
+ print(f"Detailer: force inpaint")
+ upscale = 1.0
+ new_w = w
+ new_h = h
+
+ print(f"Detailer: segment upscale for ({bbox_w, bbox_h}) | crop region {w, h} x {upscale} -> {new_w, new_h}")
+
+ # upscale
+ upscaled_image = scale_tensor(new_w, new_h, torch.from_numpy(image))
+
+ # ksampler
+ latent_image = to_latent_image(upscaled_image, vae)
+
+ if noise_mask is not None:
+ # upscale the mask tensor by a factor of 2 using bilinear interpolation
+ noise_mask = torch.from_numpy(noise_mask)
+ upscaled_mask = torch.nn.functional.interpolate(noise_mask.unsqueeze(0).unsqueeze(0), size=(new_h, new_w),
+ mode='bilinear', align_corners=False)
+
+ # remove the extra dimensions added by unsqueeze
+ upscaled_mask = upscaled_mask.squeeze().squeeze()
+ latent_image['noise_mask'] = upscaled_mask
+
+ sampler = nodes.KSampler()
+ refined_latent = sampler.sample(model, seed, steps, cfg, sampler_name, scheduler,
+ positive, negative, latent_image, denoise)
+ refined_latent = refined_latent[0]
+
+ # non-latent downscale - latent downscale cause bad quality
+ refined_image = vae.decode(refined_latent['samples'])
+
+ # downscale
+ refined_image = scale_tensor_and_to_pil(w, h, refined_image)
+
+ # don't convert to latent - latent break image
+ # preserving pil is much better
+ return refined_image
+
+
+def composite_to(dest_latent, crop_region, src_latent):
+ x1 = crop_region[0]
+ y1 = crop_region[1]
+
+ # composite to original latent
+ lc = nodes.LatentComposite()
+
+ # 현재 mask 를 고려한 composite 가 없음... 이거 처리 필요.
+
+ orig_image = lc.composite(dest_latent, src_latent, x1, y1)
+
+ return orig_image[0]
+
+
+def sam_predict(predictor, points, plabs, bbox, threshold):
+ point_coords = None if not points else np.array(points)
+ point_labels = None if not plabs else np.array(plabs)
+
+ box = np.array([bbox]) if bbox is not None else None
+
+ cur_masks, scores, _ = predictor.predict(point_coords=point_coords, point_labels=point_labels, box=box)
+
+ total_masks = []
+
+ selected = False
+ max_score = 0
+ for idx in range(len(scores)):
+ if scores[idx] > max_score:
+ max_score = scores[idx]
+ max_mask = cur_masks[idx]
+
+ if scores[idx] >= threshold:
+ selected = True
+ total_masks.append(cur_masks[idx])
+ else:
+ pass
+
+ if not selected:
+ total_masks.append(max_mask)
+
+ return total_masks
+
+
+def make_sam_mask(sam_model, segs, image, detection_hint, dilation,
+ threshold, bbox_expansion, mask_hint_threshold, mask_hint_use_negative):
+ predictor = SamPredictor(sam_model)
+ image = np.clip(255. * image.cpu().numpy().squeeze(), 0, 255).astype(np.uint8)
+
+ predictor.set_image(image, "RGB")
+
+ total_masks = []
+
+ use_small_negative = mask_hint_use_negative == "Small"
+
+ # seg_shape = segs[0]
+ segs = segs[1]
+ if detection_hint == "mask-points":
+ points = []
+ plabs = []
+
+ for i in range(len(segs)):
+ bbox = segs[i].bbox
+ center = center_of_bbox(segs[i].bbox)
+ points.append(center)
+
+ # small point is background, big point is foreground
+ if use_small_negative and bbox[2] - bbox[0] < 10:
+ plabs.append(0)
+ else:
+ plabs.append(1)
+
+ detected_masks = sam_predict(predictor, points, plabs, None, threshold)
+ total_masks += detected_masks
+
+ else:
+ for i in range(len(segs)):
+ bbox = segs[i].bbox
+ center = center_of_bbox(bbox)
+
+ x1 = max(bbox[0] - bbox_expansion, 0)
+ y1 = max(bbox[1] - bbox_expansion, 0)
+ x2 = min(bbox[2] + bbox_expansion, image.shape[1])
+ y2 = min(bbox[3] + bbox_expansion, image.shape[0])
+
+ dilated_bbox = [x1, y1, x2, y2]
+
+ points = []
+ plabs = []
+ if detection_hint == "center-1":
+ points.append(center)
+ plabs = [1] # 1 = foreground point, 0 = background point
+
+ elif detection_hint == "horizontal-2":
+ gap = (x2 - x1) / 3
+ points.append((x1 + gap, center[1]))
+ points.append((x1 + gap * 2, center[1]))
+ plabs = [1, 1]
+
+ elif detection_hint == "vertical-2":
+ gap = (y2 - y1) / 3
+ points.append((center[0], y1 + gap))
+ points.append((center[0], y1 + gap * 2))
+ plabs = [1, 1]
+
+ elif detection_hint == "rect-4":
+ x_gap = (x2 - x1) / 3
+ y_gap = (y2 - y1) / 3
+ points.append((x1 + x_gap, center[1]))
+ points.append((x1 + x_gap * 2, center[1]))
+ points.append((center[0], y1 + y_gap))
+ points.append((center[0], y1 + y_gap * 2))
+ plabs = [1, 1, 1, 1]
+
+ elif detection_hint == "diamond-4":
+ x_gap = (x2 - x1) / 3
+ y_gap = (y2 - y1) / 3
+ points.append((x1 + x_gap, y1 + y_gap))
+ points.append((x1 + x_gap * 2, y1 + y_gap))
+ points.append((x1 + x_gap, y1 + y_gap * 2))
+ points.append((x1 + x_gap * 2, y1 + y_gap * 2))
+ plabs = [1, 1, 1, 1]
+
+ elif detection_hint == "mask-point-bbox":
+ center = center_of_bbox(segs[i].bbox)
+ points.append(center)
+ plabs = [1]
+
+ elif detection_hint == "mask-area":
+ points, plabs = gen_detection_hints_from_mask_area(segs[i].crop_region[0], segs[i].crop_region[1],
+ segs[i].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],
+ segs[i].crop_region[0], segs[i].crop_region[1],
+ segs[i].crop_region[2], segs[i].crop_region[3])
+
+ points += npoints
+ plabs += nplabs
+
+ detected_masks = sam_predict(predictor, points, plabs, dilated_bbox, threshold)
+ total_masks += detected_masks
+
+ # merge every collected masks
+ mask = combine_masks2(total_masks)
+
+ if mask is not None:
+ mask = mask.float()
+ mask = dilate_mask(mask.numpy(), dilation)
+ mask = torch.from_numpy(mask)
+ else:
+ mask = torch.zeros((8, 8), dtype=torch.float32, device="cpu") # empty mask
+
+ return mask
+
+
+def segs_bitwise_and_mask(segs, mask):
+ if mask is None:
+ print("[SegsBitwiseAndMask] Cannot operate: MASK is empty.")
+ return ([], )
+
+ items = []
+
+ mask = (mask.numpy() * 255).astype(np.uint8)
+
+ for seg in segs[1]:
+ cropped_mask = (seg.cropped_mask * 255).astype(np.uint8)
+ crop_region = seg.crop_region
+
+ cropped_mask2 = mask[crop_region[1]:crop_region[3], crop_region[0]:crop_region[2]]
+
+ new_mask = np.bitwise_and(cropped_mask.astype(np.uint8), cropped_mask2)
+ new_mask = new_mask.astype(np.float32) / 255.0
+
+ item = SEG(seg.cropped_image, new_mask, seg.confidence, seg.crop_region, seg.bbox, seg.label)
+ items.append(item)
+
+ return segs[0], items
+
+
+class BBoxDetector:
+ bbox_model = None
+
+ def __init__(self, bbox_model):
+ self.bbox_model = bbox_model
+
+ def detect(self, image, threshold, dilation, crop_factor):
+ mmdet_results = inference_bbox(self.bbox_model, image, threshold)
+ segmasks = create_segmasks(mmdet_results)
+
+ if dilation > 0:
+ segmasks = dilate_masks(segmasks, dilation)
+
+ items = []
+ h = image.shape[1]
+ w = image.shape[2]
+ for x in segmasks:
+ item_bbox = x[0]
+ item_mask = x[1]
+
+ crop_region = make_crop_region(w, h, item_bbox, crop_factor)
+ cropped_image = crop_image(image, crop_region)
+ cropped_mask = crop_ndarray2(item_mask, crop_region)
+ confidence = x[2]
+ # bbox_size = (item_bbox[2]-item_bbox[0],item_bbox[3]-item_bbox[1]) # (w,h)
+
+ item = SEG(cropped_image, cropped_mask, confidence, crop_region, item_bbox)
+ items.append(item)
+
+ shape = image.shape[1],image.shape[2]
+ return shape, items
+
+ def detect_combined(self, image, threshold, dilation):
+ mmdet_results = inference_bbox(self.bbox_model, image, threshold)
+ segmasks = create_segmasks(mmdet_results)
+ if dilation > 0:
+ segmasks = dilate_masks(segmasks, dilation)
+
+ return combine_masks(segmasks)
+
+ def setAux(self, x):
+ pass
+
+
+class ONNXDetector(BBoxDetector):
+ onnx_model = None
+
+ def __init__(self, onnx_model):
+ self.onnx_model = onnx_model
+
+ def detect(self, image, threshold, dilation, crop_factor):
+ h = image.shape[1]
+ w = image.shape[2]
+
+ labels, scores, boxes = onnx.onnx_inference(image, self.onnx_model)
+
+ # collect feasible item
+ result = []
+
+ for i in range(len(labels)):
+ if scores[i] > threshold:
+ item_bbox = boxes[i]
+ x1, y1, x2, y2 = item_bbox
+
+ crop_region = make_crop_region(w, h, item_bbox, crop_factor)
+ 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
+
+ # make items
+ item = SEG(None, cropped_mask, scores[i], crop_region, item_bbox)
+ result.append(item)
+
+ shape = h, w
+ return shape, result
+
+ def detect_combined(self, image, threshold, dilation):
+ return segs_to_combined_mask(self.detect(image, threshold, dilation, 1))
+
+ def setAux(self, x):
+ pass
+
+
+class SegmDetector(BBoxDetector):
+ segm_model = None
+
+ def __init__(self, segm_model):
+ self.segm_model = segm_model
+
+ def detect(self, image, threshold, dilation, crop_factor):
+ mmdet_results = inference_segm(image, self.segm_model, threshold)
+ segmasks = create_segmasks(mmdet_results)
+
+ if dilation > 0:
+ segmasks = dilate_masks(segmasks, dilation)
+
+ items = []
+ h = image.shape[1]
+ w = image.shape[2]
+ for x in segmasks:
+ item_bbox = x[0]
+ item_mask = x[1]
+
+ crop_region = make_crop_region(w, h, item_bbox, crop_factor)
+ cropped_image = crop_image(image, crop_region)
+ cropped_mask = crop_ndarray2(item_mask, crop_region)
+ confidence = x[2]
+
+ item = SEG(cropped_image, cropped_mask, confidence, crop_region, item_bbox)
+ items.append(item)
+
+ return image.shape, items
+
+ def detect_combined(self, image, threshold, dilation):
+ mmdet_results = inference_bbox(self.bbox_model, image, threshold)
+ segmasks = create_segmasks(mmdet_results)
+ if dilation > 0:
+ segmasks = dilate_masks(segmasks, dilation)
+
+ return combine_masks(segmasks)
+
+ def setAux(self, x):
+ pass
+
+
+def mask_to_segs(mask, combined, crop_factor, bbox_fill):
+ if mask is None:
+ print("[mask_to_segs] Cannot operate: MASK is empty.")
+ return ([], )
+
+ mask = mask.numpy()
+
+ result = []
+ if combined == "True":
+ # Find the indices of the non-zero elements
+ indices = np.nonzero(mask)
+
+ if len(indices[0]) > 0 and len(indices[1]) > 0:
+ # Determine the bounding box of the non-zero elements
+ bbox = np.min(indices[1]), np.min(indices[0]), np.max(indices[1]), np.max(indices[0])
+ crop_region = make_crop_region(mask.shape[1], mask.shape[0], bbox, crop_factor)
+ x1, y1, x2, y2 = crop_region
+
+ if x2 - x1 > 0 and y2 - y1 > 0:
+ cropped_mask = mask[y1:y2, x1:x2]
+ item = SEG(None, cropped_mask, 1.0, crop_region, bbox, 'A')
+ result.append(item)
+
+ else:
+ # label the connected components
+ labelled_mask = label(mask)
+
+ # get the region properties for each connected component
+ regions = regionprops(labelled_mask)
+
+ # iterate over the regions and print their bounding boxes
+ for region in regions:
+ y1, x1, y2, x2 = region.bbox
+ bbox = x1, y1, x2, y2
+ crop_region = make_crop_region(mask.shape[1], mask.shape[0], bbox, crop_factor)
+
+ if x2 - x1 > 0 and y2 - y1 > 0:
+ cropped_mask = np.array(mask[crop_region[1]:crop_region[3], crop_region[0]:crop_region[2]])
+
+ if bbox_fill:
+ cropped_mask.fill(1.0)
+
+ item = SEG(None, cropped_mask, 1.0, crop_region, bbox, 'A')
+
+ result.append(item)
+
+ if not result:
+ print(f"[mask_to_segs] Empty mask.")
+
+ print(f"# of Detected SEGS: {len(result)}")
+ # for r in result:
+ # print(f"\tbbox={r.bbox}, crop={r.crop_region}, label={r.label}")
+
+ return mask.shape, result
+
+
+def segs_to_combined_mask(segs):
+ shape = segs[0]
+ h = shape[0]
+ w = shape[1]
+
+ mask = np.zeros((h, w), dtype=np.uint8)
+
+ for seg in segs[1]:
+ cropped_mask = seg.cropped_mask
+ crop_region = seg.crop_region
+ mask[crop_region[1]:crop_region[3], crop_region[0]:crop_region[2]] |= (cropped_mask * 255).astype(np.uint8)
+
+ return torch.from_numpy(mask.astype(np.float32) / 255.0)
+
+
+def latent_upscale_on_pixel_space_shape(samples, scale_method, w, h, vae):
+ pixels = nodes.VAEDecode().decode(vae, samples)[0]
+ new_w = max(8, (w//8)*8)
+ new_h = max(8, (h//8)*8)
+ pixels = nodes.ImageScale().upscale(pixels, scale_method, int(new_w), int(new_h), False)
+ return nodes.VAEEncode().encode(vae, pixels[0])[0]
+
+
+def latent_upscale_on_pixel_space(samples, scale_method, scale_factor, vae):
+ pixels = nodes.VAEDecode().decode(vae, samples)[0]
+ w = pixels.shape[2] * scale_factor
+ h = pixels.shape[1] * scale_factor
+ pixels = nodes.ImageScale().upscale(pixels, scale_method, int(w), int(h), False)
+ return nodes.VAEEncode().encode(vae, pixels[0])[0]
+
+
+def latent_upscale_on_pixel_space_with_model_shape(samples, scale_method, upscale_model, new_w, new_h, vae):
+ pixels = nodes.VAEDecode().decode(vae, samples)[0]
+ w = pixels.shape[2]
+
+ # upscale by model upscaler
+ current_w = w
+ while current_w < new_w:
+ pixels = model_upscale.ImageUpscaleWithModel().upscale(upscale_model, pixels)[0]
+ current_w = pixels.shape[2]
+
+ # downscale to target scale
+ pixels = nodes.ImageScale().upscale(pixels, scale_method, int(new_w), int(new_h), False)
+ return nodes.VAEEncode().encode(vae, pixels[0])[0]
+
+
+def latent_upscale_on_pixel_space_with_model(samples, scale_method, upscale_model, scale_factor, vae):
+ pixels = nodes.VAEDecode().decode(vae, samples)[0]
+ w = pixels.shape[2]
+ h = pixels.shape[1]
+
+ new_w = w * scale_factor
+ new_h = h * scale_factor
+
+ # upscale by model upscaler
+ current_w = w
+ while current_w < new_w:
+ pixels = model_upscale.ImageUpscaleWithModel().upscale(upscale_model, pixels)[0]
+ current_w = pixels.shape[2]
+
+ # downscale to target scale
+ pixels = nodes.ImageScale().upscale(pixels, scale_method, int(new_w), int(new_h), False)
+ return nodes.VAEEncode().encode(vae, pixels[0])[0]
+
+
+class PixelKSampleUpscaler:
+ params = None
+ upscale_model = None
+
+ def __init__(self, scale_method, model, vae, seed, steps, cfg, sampler_name, scheduler, positive, negative, denoise, upscale_model_opt=None):
+ self.params = scale_method, model, vae, seed, steps, cfg, sampler_name, scheduler, positive, negative, denoise
+ self.upscale_model = upscale_model_opt
+
+ def upscale(self, samples, upscale_factor):
+ scale_method, model, vae, seed, steps, cfg, sampler_name, scheduler, positive, negative, denoise = self.params
+
+ if self.upscale_model is None:
+ upscaled_latent = latent_upscale_on_pixel_space(samples, scale_method, upscale_factor, vae)
+ else:
+ upscaled_latent = latent_upscale_on_pixel_space_with_model(samples, scale_method, self.upscale_model, upscale_factor, vae)
+
+ refined_latent = nodes.KSampler().sample(model, seed, steps, cfg, sampler_name, scheduler,
+ positive, negative, upscaled_latent, denoise)
+ return refined_latent
+
+ def upscale_shape(self, samples, w, h):
+ scale_method, model, vae, seed, steps, cfg, sampler_name, scheduler, positive, negative, denoise = self.params
+
+ if self.upscale_model is None:
+ upscaled_latent = latent_upscale_on_pixel_space_shape(samples, scale_method, w, h, vae)
+ else:
+ upscaled_latent = latent_upscale_on_pixel_space_with_model_shape(samples, scale_method, self.upscale_model, w, h, vae)
+
+ refined_latent = nodes.KSampler().sample(model, seed, steps, cfg, sampler_name, scheduler,
+ positive, negative, upscaled_latent, denoise)
+ return refined_latent[0]
+
+try:
+ class BBoxDetectorBasedOnCLIPSeg(BBoxDetector):
+ prompt = None
+ blur = None
+ threshold = None
+ dilation_factor = None
+ aux = None
+
+ def __init__(self, prompt, blur, threshold, dilation_factor):
+ self.prompt = prompt
+ self.blur = blur
+ self.threshold = threshold
+ self.dilation_factor = dilation_factor
+
+ def detect(self, image, bbox_threshold, bbox_dilation, bbox_crop_factor):
+ mask = self.detect_combined(image, bbox_threshold, bbox_dilation)
+ segs = mask_to_segs(mask, False, bbox_crop_factor, True)
+ return segs
+
+ def detect_combined(self, image, bbox_threshold, bbox_dilation):
+ from custom_nodes.clipseg import CLIPSeg
+
+ if self.threshold is None:
+ threshold = bbox_threshold
+ else:
+ threshold = self.threshold
+
+ if self.dilation_factor is None:
+ dilation_factor = bbox_dilation
+ else:
+ dilation_factor = self.dilation_factor
+
+ prompt = self.aux if self.prompt == '' and self.aux is not None else self.prompt
+
+ mask, _, _ = CLIPSeg().segment_image(image, prompt, self.blur, threshold, dilation_factor)
+ mask = to_binary_mask(mask)
+ return mask
+
+ def setAux(self, x):
+ self.aux = x
+
+except:
+ pass
\ No newline at end of file
diff --git a/impact_pack.py b/impact_pack.py
index 04cd8933..ea6c3a7f 100644
--- a/impact_pack.py
+++ b/impact_pack.py
@@ -1,295 +1,18 @@
import os
-import sys
-
-main_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
-sys.path.append(os.path.dirname(__file__))
-sys.path.append(main_dir)
-
-import impact_config
-
-# ensure dependency
-if impact_config.read_config()[1] < impact_config.dependency_version:
- import install
-
-# ----- MAIN CODE --------------------------------------------------------------
-
-# Core
-# recheck dependencies for colab
-try:
- import folder_paths
- import torch
- import cv2
- import mmcv
- import numpy as np
- from mmdet.apis import (inference_detector, init_detector)
- import comfy.samplers
- import comfy.sd
- import warnings
- from PIL import Image, ImageFilter
- from mmdet.evaluation import get_classes
- from skimage.measure import label, regionprops
- from collections import namedtuple
-except:
- print("### ComfyUI-Impact-Pack: Reinstall dependencies (several dependencies are missing.)")
- import install
-
import folder_paths
-import torch
-import cv2
-import mmcv
-import numpy as np
-from mmdet.apis import (inference_detector, init_detector)
import comfy.samplers
import comfy.sd
import warnings
-from PIL import Image, ImageFilter
-from mmdet.evaluation import get_classes
-from skimage.measure import label, regionprops
-from collections import namedtuple
+from segment_anything import sam_model_registry
+
+from impact_utils import *
+import impact_core as core
+from impact_core import SEG, NO_BBOX_DETECTOR, NO_SEGM_DETECTOR
warnings.filterwarnings('ignore', category=UserWarning, message='TypedStorage is deprecated')
model_path = folder_paths.models_dir
-SEG = namedtuple("SEG", ['cropped_image', 'cropped_mask', 'confidence', 'crop_region', 'bbox', 'label'],
- defaults=[None])
-
-
-def load_mmdet(model_path):
- model_config = os.path.splitext(model_path)[0] + ".py"
- model = init_detector(model_config, model_path, device="cpu")
- return model
-
-
-def pil2tensor(image):
- return torch.from_numpy(np.array(image).astype(np.float32) / 255.0).unsqueeze(0)
-
-
-def tensor2pil(image):
- return Image.fromarray(np.clip(255. * image.cpu().numpy().squeeze(), 0, 255).astype(np.uint8))
-
-
-def center_of_bbox(bbox):
- w, h = bbox[2] - bbox[0], bbox[3] - bbox[1]
- return bbox[0] + w/2, bbox[1] + h/2
-
-
-def create_segmasks(results):
- bboxs = results[1]
- segms = results[2]
- confidence = results[3]
-
- results = []
- for i in range(len(segms)):
- item = (bboxs[i], segms[i].astype(np.float32), confidence[i])
- results.append(item)
- return results
-
-
-def combine_masks(masks):
- if len(masks) == 0:
- return None
- else:
- initial_cv2_mask = np.array(masks[0][1])
- combined_cv2_mask = initial_cv2_mask
-
- for i in range(1, len(masks)):
- cv2_mask = np.array(masks[i][1])
- combined_cv2_mask = cv2.bitwise_or(combined_cv2_mask, cv2_mask)
-
- mask = torch.from_numpy(combined_cv2_mask)
- return mask
-
-
-def combine_masks2(masks):
- if len(masks) == 0:
- return None
- else:
- initial_cv2_mask = np.array(masks[0]).astype(np.uint8)
- combined_cv2_mask = initial_cv2_mask
-
- for i in range(1, len(masks)):
- cv2_mask = np.array(masks[i]).astype(np.uint8)
- combined_cv2_mask = cv2.bitwise_or(combined_cv2_mask, cv2_mask)
-
- mask = torch.from_numpy(combined_cv2_mask)
- return mask
-
-
-def bitwise_and_masks(mask1, mask2):
- cv2_mask1 = np.array(mask1)
- cv2_mask2 = np.array(mask2)
- cv2_mask = cv2.bitwise_and(cv2_mask1, cv2_mask2)
- mask = torch.from_numpy(cv2_mask)
- return mask
-
-
-def to_binary_mask(mask):
- mask = mask.clone()
- mask[mask != 0] = 1.
- return mask
-
-
-def dilate_mask(mask, dilation_factor, iter=1):
- if dilation_factor == 0:
- return mask
-
- kernel = np.ones((dilation_factor,dilation_factor), np.uint8)
- return cv2.dilate(mask, kernel, iter)
-
-
-def dilate_masks(segmasks, dilation_factor, iter=1):
- if dilation_factor == 0:
- return segmasks
-
- dilated_masks = []
- kernel = np.ones((dilation_factor,dilation_factor), np.uint8)
- for i in range(len(segmasks)):
- cv2_mask = segmasks[i][1]
- dilated_mask = cv2.dilate(cv2_mask, kernel, iter)
- item = (segmasks[i][0], dilated_mask, segmasks[i][2])
- dilated_masks.append(item)
- return dilated_masks
-
-
-def feather_mask(mask, thickness):
- pil_mask = Image.fromarray(np.uint8(mask * 255))
-
- # Create a feathered mask by applying a Gaussian blur to the mask
- blurred_mask = pil_mask.filter(ImageFilter.GaussianBlur(thickness))
- feathered_mask = Image.new("L", pil_mask.size, 0)
- feathered_mask.paste(blurred_mask, (0, 0), blurred_mask)
- return feathered_mask
-
-
-def subtract_masks(mask1, mask2):
- cv2_mask1 = np.array(mask1) * 255
- cv2_mask2 = np.array(mask2) * 255
- cv2_mask = cv2.subtract(cv2_mask1, cv2_mask2)
- mask = torch.from_numpy(cv2_mask) / 255.0
- return mask
-
-
-def inference_segm_old(model, image, conf_threshold):
- image = image.numpy()[0] * 255
- mmdet_results = inference_detector(model, image)
-
- bbox_results, segm_results = mmdet_results
- label = "A"
-
- classes = get_classes("coco")
- labels = [
- np.full(bbox.shape[0], i, dtype=np.int32)
- for i, bbox in enumerate(bbox_results)
- ]
- n, m = bbox_results[0].shape
- if n == 0:
- return [[], [], []]
- labels = np.concatenate(labels)
- bboxes = np.vstack(bbox_results)
- segms = mmcv.concat_list(segm_results)
- filter_inds = np.where(bboxes[:, -1] > conf_threshold)[0]
- results = [[], [], []]
- for i in filter_inds:
- results[0].append(label + "-" + classes[labels[i]])
- results[1].append(bboxes[i])
- results[2].append(segms[i])
-
- return results
-
-
-def inference_segm(image, modelname, conf_thres, lab="A"):
- image = image.numpy()[0] * 255
- mmdet_results = inference_detector(modelname, image).pred_instances
- bboxes = mmdet_results.bboxes.numpy()
- segms = mmdet_results.masks.numpy()
- scores = mmdet_results.scores.numpy()
-
- classes = get_classes("coco")
-
- n, m = bboxes.shape
- if n == 0:
- return [[], [], [], []]
- labels = mmdet_results.labels
- filter_inds = np.where(mmdet_results.scores > conf_thres)[0]
- results = [[], [], [], []]
- for i in filter_inds:
- results[0].append(lab + "-" + classes[labels[i]])
- results[1].append(bboxes[i])
- results[2].append(segms[i])
- results[3].append(scores[i])
-
- return results
-
-
-def inference_bbox(modelname, image, conf_threshold):
- image = image.numpy()[0] * 255
- label = "A"
- output = inference_detector(modelname, image).pred_instances
- cv2_image = np.array(image)
- cv2_image = cv2_image[:, :, ::-1].copy()
- cv2_gray = cv2.cvtColor(cv2_image, cv2.COLOR_BGR2GRAY)
-
- segms = []
- for x0, y0, x1, y1 in output.bboxes:
- cv2_mask = np.zeros(cv2_gray.shape, np.uint8)
- cv2.rectangle(cv2_mask, (int(x0), int(y0)), (int(x1), int(y1)), 255, -1)
- cv2_mask_bool = cv2_mask.astype(bool)
- segms.append(cv2_mask_bool)
-
- n, m = output.bboxes.shape
- if n == 0:
- return [[], [], [], []]
-
- bboxes = output.bboxes.numpy()
- scores = output.scores.numpy()
- filter_inds = np.where(scores > conf_threshold)[0]
- results = [[], [], [], []]
- for i in filter_inds:
- results[0].append(label)
- results[1].append(bboxes[i])
- results[2].append(segms[i])
- results[3].append(scores[i])
-
- return results
-
-
-def gen_detection_hints_from_mask_area(x, y, mask, threshold, use_negative):
- points = []
- plabs = []
-
- # minimum sampling step >= 3
- 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))
- plabs.append(1)
- elif use_negative and mask[i][j] == 0:
- points.append((x+j, y+i))
- plabs.append(0)
-
- return points, plabs
-
-
-def gen_negative_hints(w, h, x1, y1, x2, y2):
- npoints = []
- 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):
- npoints.append((j,i))
- nplabs.append(0)
-
- return npoints, nplabs
-
# Nodes
# folder_paths.supported_pt_extensions
@@ -300,242 +23,66 @@ folder_paths.folder_names_and_paths["sams"] = ([os.path.join(model_path, "sams")
folder_paths.folder_names_and_paths["onnx"] = ([os.path.join(model_path, "onnx")], {'.onnx'})
-class NO_BBOX_MODEL:
- ERROR = ""
+class ONNXDetectorProvider:
+ @classmethod
+ def INPUT_TYPES(s):
+ return {"required": {"model_name": (folder_paths.get_filename_list("onnx"), )}}
+
+ RETURN_TYPES = ("ONNX_DETECTOR", )
+ FUNCTION = "load_onnx"
+
+ CATEGORY = "ImpactPack"
+
+ def load_onnx(self, model_name):
+ model = folder_paths.get_full_path("onnx", model_name)
+ return (core.ONNXDetector(model), )
-class NO_SEGM_MODEL:
- ERROR = ""
-
-
-def normalize_region(limit, startp, size):
- if startp < 0:
- new_endp = min(limit, size)
- new_startp = 0
- elif startp + size > limit:
- new_startp = limit - size
- new_endp = limit
- else:
- new_startp = startp
- new_endp = min(limit, startp+size)
-
- return int(new_startp), int(new_endp)
-
-
-def make_crop_region(w, h, bbox, crop_factor):
- x1 = bbox[0]
- y1 = bbox[1]
- x2 = bbox[2]
- y2 = bbox[3]
-
- bbox_w = x2-x1
- bbox_h = y2-y1
-
- crop_w = bbox_w * crop_factor
- crop_h = bbox_h * crop_factor
-
- kernel_x = x1 + bbox_w / 2
- kernel_y = y1 + bbox_h / 2
-
- new_x1 = int(kernel_x - crop_w/2)
- new_y1 = int(kernel_y - crop_h/2)
-
- # make sure position in (w,h)
- new_x1, new_x2 = normalize_region(w, new_x1, crop_w)
- new_y1, new_y2 = normalize_region(h, new_y1, crop_h)
-
- return [new_x1, new_y1, new_x2, new_y2]
-
-
-def crop_ndarray4(npimg, crop_region):
- x1 = crop_region[0]
- y1 = crop_region[1]
- x2 = crop_region[2]
- y2 = crop_region[3]
-
- cropped = npimg[:, y1:y2, x1:x2, :]
-
- return cropped
-
-
-def crop_ndarray2(npimg, crop_region):
- x1 = crop_region[0]
- y1 = crop_region[1]
- x2 = crop_region[2]
- y2 = crop_region[3]
-
- cropped = npimg[y1:y2, x1:x2]
-
- return cropped
-
-
-def crop_image(image, crop_region):
- return crop_ndarray4(np.array(image), crop_region)
-
-
-def to_latent_image(pixels, vae):
- x = (pixels.shape[1] // 64) * 64
- y = (pixels.shape[2] // 64) * 64
- if pixels.shape[1] != x or pixels.shape[2] != y:
- pixels = pixels[:, :x, :y, :]
- t = vae.encode(pixels[:, :, :, :3])
- return {"samples": t}
-
-
-LANCZOS = (Image.Resampling.LANCZOS if hasattr(Image, 'Resampling') else Image.LANCZOS)
-
-
-def scale_tensor(w, h, image):
- image = tensor2pil(image)
- scaled_image = image.resize((w, h), resample=LANCZOS)
- return pil2tensor(scaled_image)
-
-
-def scale_tensor_and_to_pil(w,h, image):
- image = tensor2pil(image)
- return image.resize((w, h), resample=LANCZOS)
-
-
-def enhance_detail(image, model, vae, guide_size, guide_size_for, bbox, seed, steps, cfg, sampler_name, scheduler,
- positive, negative, denoise, noise_mask, force_inpaint):
-
- h = image.shape[1]
- w = image.shape[2]
-
- bbox_h = bbox[3]-bbox[1]
- bbox_w = bbox[2]-bbox[0]
-
- # Skip processing if the detected bbox is already larger than the guide_size
- if bbox_h >= guide_size and bbox_w >= guide_size:
- print(f"Detailer: segment skip")
- None
-
- if guide_size_for == "bbox":
- # Scale up based on the smaller dimension between width and height.
- upscale = guide_size/min(bbox_w, bbox_h)
- else:
- # for cropped_size
- upscale = guide_size/min(w, h)
-
- new_w = int(((w * upscale)//64) * 64)
- new_h = int(((h * upscale)//64) * 64)
-
- if not force_inpaint:
- if upscale <= 1.0:
- print(f"Detailer: segment skip [determined upscale factor={upscale}]")
- return None
-
- if new_w == 0 or new_h == 0:
- print(f"Detailer: segment skip [zero size={new_w,new_h}]")
- return None
- else:
- if upscale <= 1.0 or new_w == 0 or new_h == 0:
- print(f"Detailer: force inpaint")
- upscale = 1.0
- new_w = w
- new_h = h
-
- print(f"Detailer: segment upscale for ({bbox_w,bbox_h}) | crop region {w, h} x {upscale} -> {new_w, new_h}")
-
- # upscale
- upscaled_image = scale_tensor(new_w, new_h, torch.from_numpy(image))
-
- # ksampler
- latent_image = to_latent_image(upscaled_image, vae)
-
- if noise_mask is not None:
- # upscale the mask tensor by a factor of 2 using bilinear interpolation
- noise_mask = torch.from_numpy(noise_mask)
- upscaled_mask = torch.nn.functional.interpolate(noise_mask.unsqueeze(0).unsqueeze(0), size=(new_h, new_w),
- mode='bilinear', align_corners=False)
-
- # remove the extra dimensions added by unsqueeze
- upscaled_mask = upscaled_mask.squeeze().squeeze()
- latent_image['noise_mask'] = upscaled_mask
-
- sampler = nodes.KSampler()
- refined_latent = sampler.sample(model, seed, steps, cfg, sampler_name, scheduler,
- positive, negative, latent_image, denoise)
- refined_latent = refined_latent[0]
-
- # non-latent downscale - latent downscale cause bad quality
- refined_image = vae.decode(refined_latent['samples'])
-
- # downscale
- refined_image = scale_tensor_and_to_pil(w, h, refined_image)
-
- # don't convert to latent - latent break image
- # preserving pil is much better
- return refined_image
-
-
-def composite_to(dest_latent, crop_region, src_latent):
- x1 = crop_region[0]
- y1 = crop_region[1]
-
- # composite to original latent
- lc = nodes.LatentComposite()
-
- # 현재 mask 를 고려한 composite 가 없음... 이거 처리 필요.
-
- orig_image = lc.composite(dest_latent, src_latent, x1, y1)
-
- return orig_image[0]
-
-
-def onnx_inference(image, onnx_model):
- # prepare image
- pil = tensor2pil(image)
- image = np.ascontiguousarray(pil)
- image = image[:, :, ::-1] # to BGR image
- image = image.astype(np.float32)
- image -= [103.939, 116.779, 123.68] # 'caffe' mode image preprocessing
-
- # do detection
- onnx_model = onnxruntime.InferenceSession(onnx_model)
- outputs = onnx_model.run(
- [s_i.name for s_i in onnx_model.get_outputs()],
- {onnx_model.get_inputs()[0].name: np.expand_dims(image, axis=0)},
- )
-
- labels = [op for op in outputs if op.dtype == "int32"][0]
- scores = [op for op in outputs if isinstance(op[0][0], np.float32)][0]
- boxes = [op for op in outputs if isinstance(op[0][0], np.ndarray)][0]
-
- # filter-out useless item
- idx = np.where(labels[0] == -1)[0][0]
-
- labels = labels[0][:idx]
- scores = scores[0][:idx]
- boxes = boxes[0][:idx].astype(np.uint32)
-
- return labels, scores, boxes
-
-
-class MMDetLoader:
+class MMDetDetectorProvider:
@classmethod
def INPUT_TYPES(s):
bboxs = ["bbox/"+x for x in folder_paths.get_filename_list("mmdets_bbox")]
segms = ["segm/"+x for x in folder_paths.get_filename_list("mmdets_segm")]
return {"required": {"model_name": (bboxs + segms, )}}
- RETURN_TYPES = ("BBOX_MODEL", "SEGM_MODEL")
+ RETURN_TYPES = ("BBOX_DETECTOR", "SEGM_DETECTOR")
FUNCTION = "load_mmdet"
CATEGORY = "ImpactPack"
def load_mmdet(self, model_name):
mmdet_path = folder_paths.get_full_path("mmdets", model_name)
- model = load_mmdet(mmdet_path)
+ model = core.load_mmdet(mmdet_path)
if model_name.startswith("bbox"):
- return model, NO_SEGM_MODEL()
+ return core.BBoxDetector(model), NO_SEGM_DETECTOR()
else:
- return NO_BBOX_MODEL(), model
+ return NO_BBOX_DETECTOR(), model
-from segment_anything import SamPredictor
-from segment_anything import sam_model_registry
-import onnxruntime
+class CLIPSegDetectorProvider:
+ @classmethod
+ def INPUT_TYPES(s):
+ return {"required": {
+ "text": ("STRING", {"multiline": False}),
+ "blur": ("FLOAT", {"min": 0, "max": 15, "step": 0.1, "default": 7}),
+ "threshold": ("FLOAT", {"min": 0, "max": 1, "step": 0.05, "default": 0.4}),
+ "dilation_factor": ("INT", {"min": 0, "max": 10, "step": 1, "default": 4}),
+ }
+ }
+
+ RETURN_TYPES = ("BBOX_DETECTOR", )
+ FUNCTION = "doit"
+
+ CATEGORY = "ImpactPack/Util"
+
+ def doit(self, text, blur, threshold, dilation_factor):
+ try:
+ import custom_nodes.clipseg
+ return (core.BBoxDetectorBasedOnCLIPSeg(text, blur, threshold, dilation_factor), )
+ except Exception as e:
+ print("[ERROR] CLIPSegToBboxDetector: CLIPSeg custom node isn't installed. You must install ComfyUI-CLIPSeg extension to use this node.")
+ print(f"\t{e}")
+ pass
class SAMLoader:
@@ -555,29 +102,14 @@ class SAMLoader:
return (sam, )
-class ONNXLoader:
- @classmethod
- def INPUT_TYPES(s):
- return {"required": {"model_name": (folder_paths.get_filename_list("onnx"), )}}
-
- RETURN_TYPES = ("ONNX_MODEL", )
- FUNCTION = "load_model"
-
- CATEGORY = "ImpactPack"
-
- def load_model(self, model_name):
- modelname = folder_paths.get_full_path("onnx", model_name)
- print(f"Loads ONNX model: {modelname}")
- return (modelname, )
-
-
class ONNXDetectorForEach:
@classmethod
def INPUT_TYPES(s):
return {"required": {
- "onnx_model": ("ONNX_MODEL",),
+ "onnx_detector": ("ONNX_DETECTOR",),
"image": ("IMAGE",),
"threshold": ("FLOAT", {"default": 0.8, "min": 0.0, "max": 1.0, "step": 0.01}),
+ "dilation": ("INT", {"default": 10, "min": 0, "max": 255, "step": 1}),
"crop_factor": ("FLOAT", {"default": 1.0, "min": 0.5, "max": 10, "step": 0.1}),
}
}
@@ -589,33 +121,9 @@ class ONNXDetectorForEach:
OUTPUT_NODE = True
- def doit(self, onnx_model, image, threshold, crop_factor):
- h = image.shape[1]
- w = image.shape[2]
-
- labels, scores, boxes = onnx_inference(image, onnx_model)
-
- # collect feasible item
- result = []
-
- for i in range(len(labels)):
- if scores[i] > threshold:
- item_bbox = boxes[i]
- x1, y1, x2, y2 = item_bbox
-
- crop_region = make_crop_region(w, h, item_bbox, crop_factor)
- 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
-
- # make items
- item = SEG(None, cropped_mask, scores[i], crop_region, item_bbox)
- result.append(item)
-
- return (result,)
+ def doit(self, onnx_detector, image, threshold, dilation, crop_factor):
+ segs = onnx_detector.detect(image, threshold, dilation, crop_factor)
+ return (segs, )
class DetailerForEach:
@@ -626,7 +134,7 @@ class DetailerForEach:
"segs": ("SEGS", ),
"model": ("MODEL",),
"vae": ("VAE",),
- "guide_size": ("FLOAT", {"default": 256, "min": 128, "max": nodes.MAX_RESOLUTION, "step": 64}),
+ "guide_size": ("FLOAT", {"default": 256, "min": 64, "max": nodes.MAX_RESOLUTION, "step": 8}),
"guide_size_for": (["bbox", "crop_region"],),
"seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}),
"steps": ("INT", {"default": 20, "min": 1, "max": 10000}),
@@ -650,10 +158,10 @@ class DetailerForEach:
@staticmethod
def do_detail(image, segs, model, vae, guide_size, guide_size_for, seed, steps, cfg, sampler_name, scheduler,
positive, negative, denoise, feather, noise_mask, force_inpaint):
-
+
image_pil = tensor2pil(image).convert('RGBA')
- for seg in segs:
+ for seg in segs[1]:
cropped_image = seg.cropped_image if seg.cropped_image is not None \
else crop_ndarray4(image.numpy(), seg.crop_region)
@@ -664,7 +172,7 @@ class DetailerForEach:
else:
cropped_mask = None
- enhanced_pil = enhance_detail(cropped_image, model, vae, guide_size, guide_size_for, seg.bbox,
+ enhanced_pil = core.enhance_detail(cropped_image, model, vae, guide_size, guide_size_for, seg.bbox,
seed, steps, cfg, sampler_name, scheduler,
positive, negative, denoise, cropped_mask, force_inpaint)
@@ -675,7 +183,7 @@ class DetailerForEach:
image_tensor = pil2tensor(image_pil.convert('RGB'))
- if len(segs) > 0:
+ if len(segs[1]) > 0:
enhanced_tensor = pil2tensor(enhanced_pil) if enhanced_pil is not None else None
return image_tensor, torch.from_numpy(cropped_image), enhanced_tensor,
else:
@@ -692,6 +200,44 @@ class DetailerForEach:
return (enhanced_img, )
+class DetailerForEachPipe:
+ @classmethod
+ def INPUT_TYPES(s):
+ return {"required": {
+ "image": ("IMAGE", ),
+ "segs": ("SEGS", ),
+ "guide_size": ("FLOAT", {"default": 256, "min": 64, "max": nodes.MAX_RESOLUTION, "step": 8}),
+ "guide_size_for": (["bbox", "crop_region"],),
+ "seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}),
+ "steps": ("INT", {"default": 20, "min": 1, "max": 10000}),
+ "cfg": ("FLOAT", {"default": 8.0, "min": 0.0, "max": 100.0}),
+ "sampler_name": (comfy.samplers.KSampler.SAMPLERS,),
+ "scheduler": (comfy.samplers.KSampler.SCHEDULERS,),
+ "denoise": ("FLOAT", {"default": 0.5, "min": 0.0001, "max": 1.0, "step": 0.01}),
+ "feather": ("INT", {"default": 5, "min": 0, "max": 100, "step": 1}),
+ "noise_mask": (["enabled", "disabled"], ),
+ "force_inpaint": (["disabled", "enabled"], ),
+ "basic_pipe": ("BASIC_PIPE", )
+ },
+ }
+
+ RETURN_TYPES = ("IMAGE", )
+ FUNCTION = "doit"
+
+ CATEGORY = "ImpactPack/Detailer"
+
+ def doit(self, image, segs, guide_size, guide_size_for, seed, steps, cfg, sampler_name, scheduler,
+ denoise, feather, noise_mask, force_inpaint, basic_pipe):
+
+ model, _, vae, positive, negative = basic_pipe
+ enhanced_img, cropped, cropped_enhanced = \
+ DetailerForEach.do_detail(image, segs, model, vae, guide_size, guide_size_for, seed, steps, cfg,
+ sampler_name, scheduler, positive, negative, denoise, feather, noise_mask,
+ force_inpaint)
+
+ return (enhanced_img, )
+
+
class FaceDetailer:
@classmethod
def INPUT_TYPES(s):
@@ -699,7 +245,7 @@ class FaceDetailer:
"image": ("IMAGE", ),
"model": ("MODEL",),
"vae": ("VAE",),
- "guide_size": ("FLOAT", {"default": 256, "min": 128, "max": nodes.MAX_RESOLUTION, "step": 64}),
+ "guide_size": ("FLOAT", {"default": 256, "min": 64, "max": nodes.MAX_RESOLUTION, "step": 8}),
"guide_size_for": (["bbox", "crop_region"],),
"seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}),
"steps": ("INT", {"default": 20, "min": 1, "max": 10000}),
@@ -724,58 +270,218 @@ class FaceDetailer:
"sam_mask_hint_threshold": ("FLOAT", {"default": 0.7, "min": 0.0, "max": 1.0, "step": 0.01}),
"sam_mask_hint_use_negative": (["False", "Small", "Outter"],),
- "bbox_model": ("BBOX_MODEL", ),
+ "bbox_detector": ("BBOX_DETECTOR", ),
},
"optional": {
"sam_model_opt": ("SAM_MODEL", ),
}}
- RETURN_TYPES = ("IMAGE", "MASK", "DETAILER_PIPE", )
+ RETURN_TYPES = ("IMAGE", "IMAGE", "MASK", "DETAILER_PIPE", )
+ RETURN_NAMES = ("image", "cropped_refined", "mask", "detailer_pipe")
FUNCTION = "doit"
CATEGORY = "ImpactPack/Simple"
@staticmethod
- def enhance(image, model, vae, guide_size, guide_size_for, 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,
- bbox_model, sam_model_opt=None):
-
- segs = BboxDetectorForEach.detect(bbox_model, image, bbox_threshold, bbox_dilation, bbox_crop_factor)
+ def enhance_face(image, model, vae, guide_size, guide_size_for, 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,
+ bbox_detector, sam_model_opt=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)
+ bbox_detector.setAux(None)
# bbox + sam combination
if sam_model_opt is not None:
- sam_mask = SAMDetectorCombined.make_mask(sam_model_opt, segs, image, sam_detection_hint, sam_dilation,
- sam_threshold, sam_bbox_expansion, sam_mask_hint_threshold, sam_mask_hint_use_negative,)
- segs = SegsBitwiseAndMask.operate(segs, sam_mask)
+ sam_mask = core.make_sam_mask(sam_model_opt, segs, image, sam_detection_hint, sam_dilation,
+ sam_threshold, sam_bbox_expansion, sam_mask_hint_threshold,
+ sam_mask_hint_use_negative, )
+ segs = core.segs_bitwise_and_mask(segs, sam_mask)
- enhanced_img, _, _ = \
+ enhanced_img, _, cropped_enhanced = \
DetailerForEach.do_detail(image, segs, model, vae, guide_size, guide_size_for, seed, steps, cfg,
sampler_name, scheduler, positive, negative, denoise, feather, noise_mask,
force_inpaint)
# Mask Generator
- mask = SegsMaskCombine.combine(segs, image)
+ mask = core.segs_to_combined_mask(segs)
- return enhanced_img, mask
+ return enhanced_img, cropped_enhanced, mask
def doit(self, image, model, vae, guide_size, guide_size_for, 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,
- bbox_model, sam_model_opt=None):
+ bbox_detector, sam_model_opt=None):
- enhanced_img, mask = FaceDetailer.enhance(
+ enhanced_img, cropped_enhanced, mask = FaceDetailer.enhance_face(
image, model, vae, guide_size, guide_size_for, 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,
- bbox_model, sam_model_opt)
+ bbox_detector, sam_model_opt)
- pipe = (vae, model, vae, positive, negative, bbox_model, sam_model_opt)
- return enhanced_img, mask, pipe
+ pipe = (model, vae, positive, negative, bbox_detector, sam_model_opt)
+ return enhanced_img, cropped_enhanced, mask, pipe
+
+
+class LatentPixelScale:
+ upscale_methods = ["nearest-exact", "bilinear", "area"]
+
+ @classmethod
+ def INPUT_TYPES(s):
+ return {"required": {
+ "samples": ("LATENT", ),
+ "scale_method": (s.upscale_methods,),
+ "scale_factor": ("FLOAT", {"default": 1.5, "min": 0.1, "max": 10000, "step": 0.1}),
+ "vae": ("VAE", ),
+ },
+ "optional": {
+ "upscale_model_opt": ("UPSCALE_MODEL", ),
+ }
+ }
+
+ RETURN_TYPES = ("LATENT",)
+ FUNCTION = "doit"
+
+ CATEGORY = "ImpactPack/Upscale"
+
+ def doit(self, samples, scale_method, scale_factor, vae, upscale_model_opt=None):
+ if upscale_model_opt is None:
+ latent = core.latent_upscale_on_pixel_space(samples, scale_method, scale_factor, vae)
+ else:
+ latent = core.latent_upscale_on_pixel_space_with_model(samples, scale_method, upscale_model_opt, scale_factor, vae)
+ return (latent,)
+
+
+class PixelKSampleUpscalerProvider:
+ upscale_methods = ["nearest-exact", "bilinear", "area"]
+
+ @classmethod
+ def INPUT_TYPES(s):
+ return {"required": {
+ "scale_method": (s.upscale_methods,),
+ "model": ("MODEL",),
+ "vae": ("VAE",),
+ "seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}),
+ "steps": ("INT", {"default": 20, "min": 1, "max": 10000}),
+ "cfg": ("FLOAT", {"default": 8.0, "min": 0.0, "max": 100.0}),
+ "sampler_name": (comfy.samplers.KSampler.SAMPLERS, ),
+ "scheduler": (comfy.samplers.KSampler.SCHEDULERS, ),
+ "positive": ("CONDITIONING", ),
+ "negative": ("CONDITIONING", ),
+ "denoise": ("FLOAT", {"default": 1.0, "min": 0.0, "max": 1.0, "step": 0.01}),
+ },
+ "optional": {
+ "upscale_model_opt": ("UPSCALE_MODEL", ),
+ }
+ }
+
+ RETURN_TYPES = ("UPSCALER",)
+ FUNCTION = "doit"
+
+ CATEGORY = "ImpactPack/Upscale"
+
+ def doit(self, scale_method, model, vae, seed, steps, cfg, sampler_name, scheduler, positive, negative, denoise, upscale_model_opt=None):
+ upscaler = core.PixelKSampleUpscaler(scale_method, model, vae, seed, steps, cfg, sampler_name, scheduler, positive, negative, denoise, upscale_model_opt)
+ return (upscaler, )
+
+
+class PixelKSampleUpscalerProviderPipe(PixelKSampleUpscalerProvider):
+ upscale_methods = ["nearest-exact", "bilinear", "area"]
+
+ @classmethod
+ def INPUT_TYPES(s):
+ return {"required": {
+ "scale_method": (s.upscale_methods,),
+ "seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}),
+ "steps": ("INT", {"default": 20, "min": 1, "max": 10000}),
+ "cfg": ("FLOAT", {"default": 8.0, "min": 0.0, "max": 100.0}),
+ "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}),
+ "basic_pipe": ("BASIC_PIPE",) },
+ "optional": {
+ "upscale_model_opt": ("UPSCALE_MODEL", ),
+ }
+ }
+
+ RETURN_TYPES = ("UPSCALER",)
+ FUNCTION = "doit"
+
+ CATEGORY = "ImpactPack/Upscale"
+
+ def doit(self, scale_method, seed, steps, cfg, sampler_name, scheduler, denoise, basic_pipe, upscale_model_opt=None):
+ model, _, vae, positive, negative = basic_pipe
+ upscaler = core.PixelKSampleUpscaler(scale_method, model, vae, seed, steps, cfg, sampler_name, scheduler, positive, negative, denoise, upscale_model_opt)
+ return (upscaler, )
+
+
+class IterativeLatentUpscale:
+ @classmethod
+ def INPUT_TYPES(s):
+ return {"required": {
+ "samples": ("LATENT", ),
+ "upscale_factor": ("FLOAT", {"default": 1.5, "min": 1, "max": 10000, "step": 0.1}),
+ "steps": ("INT", {"default": 3, "min": 1, "max": 10000, "step": 1}),
+ "upscaler": ("UPSCALER",),
+ }}
+
+ RETURN_TYPES = ("LATENT",)
+ RETURN_NAMES = ("latent",)
+ FUNCTION = "doit"
+
+ CATEGORY = "ImpactPack/Upscale"
+
+ def doit(self, samples, upscale_factor, steps, upscaler):
+ w = samples['samples'].shape[3]*8 # image width
+ h = samples['samples'].shape[2]*8 # image height
+
+ upscale_factor_unit = max(0, (upscale_factor-1.0)/steps)
+ current_latent = samples
+ scale = 1
+ for i in range(steps-1):
+ scale += upscale_factor_unit
+ new_w = (w*scale//8)*8
+ new_h = (h*scale//8)*8
+ print(f"IterativeLatentUpscale[{i+1}/{steps}]: {new_w}x{new_h} (scale:{scale:.2f}) ")
+ current_latent = upscaler.upscale_shape(current_latent, new_w, new_h)
+
+ if scale < upscale_factor:
+ new_w = (w*upscale_factor//8)*8
+ new_h = (h*upscale_factor//8)*8
+ print(f"IterativeLatentUpscale[Final]: {new_w}x{new_h} (scale:{upscale_factor:.2f}) ")
+ current_latent = upscaler.upscale_shape(current_latent, new_w, new_h)
+
+ return (current_latent, )
+
+
+class IterativeImageUpscale:
+ @classmethod
+ def INPUT_TYPES(s):
+ return {"required": {
+ "pixels": ("IMAGE", ),
+ "upscale_factor": ("FLOAT", {"default": 1.5, "min": 1, "max": 10000, "step": 0.1}),
+ "steps": ("INT", {"default": 3, "min": 1, "max": 10000, "step": 1}),
+ "upscaler": ("UPSCALER",),
+ "vae": ("VAE",),
+ }}
+
+ RETURN_TYPES = ("IMAGE",)
+ RETURN_NAMES = ("image",)
+ FUNCTION = "doit"
+
+ CATEGORY = "ImpactPack/Upscale"
+
+ def doit(self, pixels, upscale_factor, steps, upscaler, vae):
+ latent = nodes.VAEEncode().encode(vae, pixels)[0]
+ refined_latent = IterativeLatentUpscale().doit(latent, upscale_factor, steps, upscaler)
+ pixels = nodes.VAEDecode().decode(vae, refined_latent[0])[0]
+ return (pixels, )
class FaceDetailerPipe:
@@ -784,7 +490,7 @@ class FaceDetailerPipe:
return {"required": {
"image": ("IMAGE", ),
"detailer_pipe": ("DETAILER_PIPE",),
- "guide_size": ("FLOAT", {"default": 256, "min": 128, "max": nodes.MAX_RESOLUTION, "step": 64}),
+ "guide_size": ("FLOAT", {"default": 256, "min": 64, "max": nodes.MAX_RESOLUTION, "step": 8}),
"guide_size_for": (["bbox", "crop_region"],),
"seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}),
"steps": ("INT", {"default": 20, "min": 1, "max": 10000}),
@@ -809,7 +515,8 @@ class FaceDetailerPipe:
},
}
- RETURN_TYPES = ("IMAGE", "MASK", "DETAILER_PIPE", )
+ RETURN_TYPES = ("IMAGE", "IMAGE", "MASK", "DETAILER_PIPE", )
+ RETURN_NAMES = ("image", "cropped_refined", "mask", "detailer_pipe")
FUNCTION = "doit"
CATEGORY = "ImpactPack/Simple"
@@ -818,22 +525,22 @@ class FaceDetailerPipe:
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):
- vae, model, vae, positive, negative, bbox_model, sam_model_opt = detailer_pipe
+ model, vae, positive, negative, bbox_detector, sam_model_opt = detailer_pipe
- enhanced_img, mask = FaceDetailer.enhance(
+ enhanced_img, cropped_enhanced, mask = FaceDetailer.enhance_face(
image, model, vae, guide_size, guide_size_for, 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,
- bbox_model, sam_model_opt)
+ bbox_detector, sam_model_opt)
- return enhanced_img, mask, detailer_pipe
+ return enhanced_img, cropped_enhanced, mask, detailer_pipe
class DetailerForEachTest(DetailerForEach):
RETURN_TYPES = ("IMAGE", "IMAGE", "IMAGE", )
- RETURN_NAMES = ("image","cropped","cropped_refined")
+ RETURN_NAMES = ("image", "cropped", "cropped_refined")
FUNCTION = "doit"
CATEGORY = "ImpactPack/Detailer"
@@ -856,6 +563,32 @@ class DetailerForEachTest(DetailerForEach):
return enhanced_img, cropped, cropped_enhanced,
+class DetailerForEachTestPipe(DetailerForEachPipe):
+ RETURN_TYPES = ("IMAGE", "IMAGE", "IMAGE", )
+ RETURN_NAMES = ("image", "cropped", "cropped_refined")
+ FUNCTION = "doit"
+
+ CATEGORY = "ImpactPack/Detailer"
+
+ def doit(self, image, segs, guide_size, guide_size_for, seed, steps, cfg, sampler_name, scheduler,
+ denoise, feather, noise_mask, force_inpaint, basic_pipe):
+
+ model, _, vae, positive, negative = basic_pipe
+ enhanced_img, cropped, cropped_enhanced = \
+ DetailerForEach.do_detail(image, segs, model, vae, guide_size, guide_size_for, seed, steps, cfg,
+ sampler_name, scheduler, positive, negative, denoise, feather, noise_mask,
+ force_inpaint)
+
+ # set fallback image
+ if cropped is None:
+ cropped = enhanced_img
+
+ if cropped_enhanced is None:
+ cropped_enhanced = enhanced_img
+
+ return enhanced_img, cropped, cropped_enhanced,
+
+
class EmptySEGS:
@classmethod
def INPUT_TYPES(s):
@@ -867,15 +600,15 @@ class EmptySEGS:
CATEGORY = "ImpactPack/Util"
def doit(self):
- return ([],)
+ shape = 0, 0
+ return ((shape, []),)
-class SegsMaskCombine:
+class SegsToCombinedMask:
@classmethod
def INPUT_TYPES(s):
return {"required": {
"segs": ("SEGS", ),
- "image": ("IMAGE", ),
}
}
@@ -884,277 +617,8 @@ class SegsMaskCombine:
CATEGORY = "ImpactPack/Operation"
- @staticmethod
- def combine(segs, image):
- h = image.shape[1]
- w = image.shape[2]
-
- mask = np.zeros((h, w), dtype=np.uint8)
-
- for seg in segs:
- cropped_mask = seg.cropped_mask
- crop_region = seg.crop_region
- mask[crop_region[1]:crop_region[3], crop_region[0]:crop_region[2]] |= (cropped_mask * 255).astype(np.uint8)
-
- return torch.from_numpy(mask.astype(np.float32) / 255.0)
-
- def doit(self, segs, image):
- return (SegsMaskCombine.combine(segs, image), )
-
-def sam_predict(predictor, points, plabs, bbox, threshold):
- point_coords = None if not points else np.array(points)
- point_labels = None if not plabs else np.array(plabs)
-
- box = np.array([bbox]) if bbox is not None else None
-
- cur_masks, scores, _ = predictor.predict(point_coords=point_coords, point_labels=point_labels, box=box)
-
- total_masks = []
-
- selected = False
- max_score = 0
- for idx in range(len(scores)):
- if scores[idx] > max_score:
- max_score = scores[idx]
- max_mask = cur_masks[idx]
-
- if scores[idx] >= threshold:
- selected = True
- total_masks.append(cur_masks[idx])
- else:
- pass
-
- if not selected:
- total_masks.append(max_mask)
-
- return total_masks
-
-
-class SAMDetectorCombined:
- @classmethod
- def INPUT_TYPES(s):
- return {"required": {
- "sam_model": ("SAM_MODEL", ),
- "segs": ("SEGS", ),
- "image": ("IMAGE", ),
- "detection_hint": (["center-1", "horizontal-2", "vertical-2", "rect-4", "diamond-4", "mask-area",
- "mask-points", "mask-point-bbox", "none"],),
- "dilation": ("INT", {"default": 0, "min": 0, "max": 255, "step": 1}),
- "threshold": ("FLOAT", {"default": 0.93, "min": 0.0, "max": 1.0, "step": 0.01}),
- "bbox_expansion": ("INT", {"default": 0, "min": 0, "max": 1000, "step": 1}),
- "mask_hint_threshold": ("FLOAT", {"default": 0.7, "min": 0.0, "max": 1.0, "step": 0.01}),
- "mask_hint_use_negative": (["False", "Small", "Outter"], )
- }
- }
-
- RETURN_TYPES = ("MASK",)
- FUNCTION = "doit"
-
- CATEGORY = "ImpactPack/Detector"
-
- @staticmethod
- def make_mask(sam_model, segs, image, detection_hint, dilation,
- threshold, bbox_expansion, mask_hint_threshold, mask_hint_use_negative):
-
- predictor = SamPredictor(sam_model)
- image = np.clip(255. * image.cpu().numpy().squeeze(), 0, 255).astype(np.uint8)
-
- predictor.set_image(image, "RGB")
-
- total_masks = []
-
- use_small_negative = mask_hint_use_negative == "Small"
-
- if detection_hint == "mask-points":
- points = []
- plabs = []
-
- for i in range(len(segs)):
- bbox = segs[i].bbox
- center = center_of_bbox(segs[i].bbox)
- points.append(center)
-
- # small point is background, big point is foreground
- if use_small_negative and bbox[2]-bbox[0] < 10:
- plabs.append(0)
- else:
- plabs.append(1)
-
- detected_masks = sam_predict(predictor, points, plabs, None, threshold)
- total_masks += detected_masks
-
- else:
- for i in range(len(segs)):
- bbox = segs[i].bbox
- center = center_of_bbox(bbox)
-
- x1 = max(bbox[0] - bbox_expansion, 0)
- y1 = max(bbox[1] - bbox_expansion, 0)
- x2 = min(bbox[2] + bbox_expansion, image.shape[1])
- y2 = min(bbox[3] + bbox_expansion, image.shape[0])
-
- dilated_bbox = [x1, y1, x2, y2]
-
- points = []
- plabs = []
- if detection_hint == "center-1":
- points.append(center)
- plabs = [1] # 1 = foreground point, 0 = background point
-
- elif detection_hint == "horizontal-2":
- gap = (x2 - x1) / 3
- points.append((x1 + gap, center[1]))
- points.append((x1 + gap*2, center[1]))
- plabs = [1, 1]
-
- elif detection_hint == "vertical-2":
- gap = (y2 - y1) / 3
- points.append((center[0], y1 + gap))
- points.append((center[0], y1 + gap*2))
- plabs = [1, 1]
-
- elif detection_hint == "rect-4":
- x_gap = (x2 - x1) / 3
- y_gap = (y2 - y1) / 3
- points.append((x1 + x_gap, center[1]))
- points.append((x1 + x_gap*2, center[1]))
- points.append((center[0], y1 + y_gap))
- points.append((center[0], y1 + y_gap*2))
- plabs = [1, 1, 1, 1]
-
- elif detection_hint == "diamond-4":
- x_gap = (x2 - x1) / 3
- y_gap = (y2 - y1) / 3
- points.append((x1 + x_gap, y1 + y_gap))
- points.append((x1 + x_gap*2, y1 + y_gap))
- points.append((x1 + x_gap, y1 + y_gap*2))
- points.append((x1 + x_gap*2, y1 + y_gap*2))
- plabs = [1, 1, 1, 1]
-
- elif detection_hint == "mask-point-bbox":
- center = center_of_bbox(segs[i].bbox)
- points.append(center)
- plabs = [1]
-
- elif detection_hint == "mask-area":
- points, plabs = gen_detection_hints_from_mask_area(segs[i].crop_region[0], segs[i].crop_region[1], segs[i].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],
- segs[i].crop_region[0], segs[i].crop_region[1], segs[i].crop_region[2], segs[i].crop_region[3])
-
- points += npoints
- plabs += nplabs
-
- detected_masks = sam_predict(predictor, points, plabs, dilated_bbox, threshold)
- total_masks += detected_masks
-
- # merge every collected masks
- mask = combine_masks2(total_masks)
-
- if mask is not None:
- mask = mask.float()
- mask = dilate_mask(mask.numpy(), dilation)
- mask = torch.from_numpy(mask)
- else:
- mask = torch.zeros((64,64), dtype=torch.float32, device="cpu") # empty mask
-
- return mask
-
- def doit(self, sam_model, segs, image, detection_hint, dilation,
- threshold, bbox_expansion, mask_hint_threshold, mask_hint_use_negative):
- return (SAMDetectorCombined.make_mask(sam_model, segs, image, detection_hint, dilation,
- threshold, bbox_expansion, mask_hint_threshold, mask_hint_use_negative), )
-
-
-class BboxDetectorForEach:
- @classmethod
- def INPUT_TYPES(s):
- return {"required": {
- "bbox_model": ("BBOX_MODEL", ),
- "image": ("IMAGE", ),
- "threshold": ("FLOAT", {"default": 0.5, "min": 0.0, "max": 1.0, "step": 0.01}),
- "dilation": ("INT", {"default": 10, "min": 0, "max": 255, "step": 1}),
- "crop_factor": ("FLOAT", {"default": 3.0, "min": 1.0, "max": 10, "step": 0.1}),
- }
- }
-
- RETURN_TYPES = ("SEGS", )
- FUNCTION = "doit"
-
- CATEGORY = "ImpactPack/Detector"
-
- @staticmethod
- def detect(bbox_model, image, threshold, dilation, crop_factor):
- mmdet_results = inference_bbox(bbox_model, image, threshold)
- segmasks = create_segmasks(mmdet_results)
-
- if dilation > 0:
- segmasks = dilate_masks(segmasks, dilation)
-
- items = []
- h = image.shape[1]
- w = image.shape[2]
- for x in segmasks:
- item_bbox = x[0]
- item_mask = x[1]
-
- crop_region = make_crop_region(w, h, item_bbox, crop_factor)
- cropped_image = crop_image(image, crop_region)
- cropped_mask = crop_ndarray2(item_mask, crop_region)
- confidence = x[2]
- # bbox_size = (item_bbox[2]-item_bbox[0],item_bbox[3]-item_bbox[1]) # (w,h)
-
- item = SEG(cropped_image, cropped_mask, confidence, crop_region, item_bbox)
- items.append(item)
-
- return items
-
- def doit(self, bbox_model, image, threshold, dilation, crop_factor):
- return (BboxDetectorForEach.detect(bbox_model, image, threshold, dilation, crop_factor), )
-
-
-class SegmDetectorForEach:
- @classmethod
- def INPUT_TYPES(s):
- return {"required": {
- "segm_model": ("SEGM_MODEL", ),
- "image": ("IMAGE", ),
- "threshold": ("FLOAT", {"default": 0.5, "min": 0.0, "max": 1.0, "step": 0.01}),
- "dilation": ("INT", {"default": 10, "min": 0, "max": 255, "step": 1}),
- "crop_factor": ("FLOAT", {"default": 3.0, "min": 1.0, "max": 10, "step": 0.1}),
- }
- }
-
- RETURN_TYPES = ("SEGS", )
- FUNCTION = "doit"
-
- CATEGORY = "ImpactPack/Detector"
-
- def doit(self, segm_model, image, threshold, dilation, crop_factor):
- mmdet_results = inference_segm(image, segm_model, threshold)
- segmasks = create_segmasks(mmdet_results)
-
- if dilation > 0:
- segmasks = dilate_masks(segmasks, dilation)
-
- items = []
- h = image.shape[1]
- w = image.shape[2]
- for x in segmasks:
- item_bbox = x[0]
- item_mask = x[1]
-
- crop_region = make_crop_region(w, h, item_bbox, crop_factor)
- cropped_image = crop_image(image, crop_region)
- cropped_mask = crop_ndarray2(item_mask, crop_region)
- confidence = x[2]
-
- item = SEG(cropped_image, cropped_mask, confidence, crop_region, item_bbox)
- items.append(item)
-
- return (items, )
+ def doit(self, segs):
+ return (core.segs_to_combined_mask(segs), )
class SegsBitwiseAndMask:
@@ -1171,32 +635,8 @@ class SegsBitwiseAndMask:
CATEGORY = "ImpactPack/Operation"
- @staticmethod
- def operate(segs, mask):
- if mask is None:
- print("[SegsBitwiseAndMask] Cannot operate: MASK is empty.")
- return ([], )
-
- items = []
-
- mask = (mask.numpy() * 255).astype(np.uint8)
-
- for seg in segs:
- cropped_mask = (seg.cropped_mask * 255).astype(np.uint8)
- crop_region = seg.crop_region
-
- cropped_mask2 = mask[crop_region[1]:crop_region[3], crop_region[0]:crop_region[2]]
-
- new_mask = np.bitwise_and(cropped_mask.astype(np.uint8), cropped_mask2)
- new_mask = new_mask.astype(np.float32) / 255.0
-
- item = SEG(seg.cropped_image, new_mask, seg.confidence, seg.crop_region, seg.bbox, seg.label)
- items.append(item)
-
- return items
-
def doit(self, segs, mask):
- return (SegsBitwiseAndMask.operate(segs, mask), )
+ return (core.segs_bitwise_and_mask(segs, mask), )
class BitwiseAndMaskForEach:
@@ -1218,11 +658,11 @@ class BitwiseAndMaskForEach:
result = []
- for bseg in base_segs:
+ for bseg in base_segs[1]:
cropped_mask1 = bseg.cropped_mask.copy()
crop_region1 = bseg.crop_region
- for mseg in mask_segs:
+ for mseg in mask_segs[1]:
cropped_mask2 = mseg.cropped_mask
crop_region2 = mseg.crop_region
@@ -1250,7 +690,7 @@ class BitwiseAndMaskForEach:
item = SEG(bseg.cropped_image, cropped_mask1, bseg.confidence, bseg.crop_region, bseg.bbox, bseg.label)
result.append(item)
- return (result,)
+ return ((base_segs[0], result),)
class SubtractMaskForEach:
@@ -1271,11 +711,11 @@ class SubtractMaskForEach:
result = []
- for bseg in base_segs:
+ for bseg in base_segs[1]:
cropped_mask1 = bseg.cropped_mask.copy()
crop_region1 = bseg.crop_region
- for mseg in mask_segs:
+ for mseg in mask_segs[1]:
cropped_mask2 = mseg.cropped_mask
crop_region2 = mseg.crop_region
@@ -1305,7 +745,7 @@ class SubtractMaskForEach:
else:
result.append(base_segs)
- return (result,)
+ return ((base_segs[0], result),)
class MaskToSEGS:
@@ -1315,6 +755,7 @@ class MaskToSEGS:
"mask": ("MASK",),
"combined": (["False", "True"], ),
"crop_factor": ("FLOAT", {"default": 3.0, "min": 1.0, "max": 10, "step": 0.1}),
+ "bbox_fill": (["disabled", "enabled"], ),
}
}
@@ -1323,104 +764,11 @@ class MaskToSEGS:
CATEGORY = "ImpactPack/Operation"
- def doit(self, mask, combined, crop_factor):
- if mask is None:
- print("[MaskToSEGS] Cannot operate: MASK is empty.")
- return ([], )
-
- mask = mask.numpy()
-
- result = []
- if combined == "True":
- # Find the indices of the non-zero elements
- indices = np.nonzero(mask)
-
- if len(indices[0]) > 0 and len(indices[1]) > 0:
- # Determine the bounding box of the non-zero elements
- bbox = np.min(indices[1]), np.min(indices[0]), np.max(indices[1]), np.max(indices[0])
- crop_region = make_crop_region(mask.shape[1], mask.shape[0], bbox, crop_factor)
- x1, y1, x2, y2 = crop_region
-
- if x2 - x1 > 0 and y2 - y1 > 0:
- cropped_mask = mask[y1:y2, x1:x2]
- item = SEG(None, cropped_mask, 1.0, crop_region, bbox)
- result.append(item)
-
- else:
- # label the connected components
- labelled_mask = label(mask)
-
- # get the region properties for each connected component
- regions = regionprops(labelled_mask)
-
- # iterate over the regions and print their bounding boxes
- for region in regions:
- y1, x1, y2, x2 = region.bbox
- bbox = x1, y1, x2, y2
- crop_region = make_crop_region(mask.shape[1], mask.shape[0], bbox, crop_factor)
-
- if x2 - x1 > 0 and y2 - y1 > 0:
- cropped_mask = mask[crop_region[1]:crop_region[3], crop_region[0]:crop_region[2]]
- item = SEG(None, cropped_mask, 1.0, crop_region, bbox)
- result.append(item)
-
- if not result:
- print(f"[MaskToSEGS] Empty mask.")
-
- print(f"# of Detected SEGS: {len(result)}")
- # for r in result:
- # print(f"\tbbox={r.bbox}, crop={r.crop_region}, label={r.label}")
-
+ def doit(self, mask, combined, crop_factor, bbox_fill):
+ result = core.mask_to_segs(mask, combined, crop_factor, bbox_fill == "enabled")
return (result, )
-class SegmDetectorCombined:
- @classmethod
- def INPUT_TYPES(s):
- return {"required": {
- "segm_model": ("SEGM_MODEL", ),
- "image": ("IMAGE", ),
- "threshold": ("FLOAT", {"default": 0.5, "min": 0.0, "max": 1.0, "step": 0.01}),
- "dilation": ("INT", {"default": 0, "min": 0, "max": 255, "step": 1}),
- }
- }
-
- RETURN_TYPES = ("MASK",)
- FUNCTION = "doit"
-
- CATEGORY = "ImpactPack/Detector"
-
- def doit(self, segm_model, image, threshold, dilation):
- mmdet_results = inference_segm(image, segm_model, threshold)
- segmasks = create_segmasks(mmdet_results)
- if dilation > 0:
- segmasks = dilate_masks(segmasks, dilation)
-
- mask = combine_masks(segmasks)
- return (mask,)
-
-
-class BboxDetectorCombined(SegmDetectorCombined):
- @classmethod
- def INPUT_TYPES(s):
- return {"required": {
- "bbox_model": ("BBOX_MODEL", ),
- "image": ("IMAGE", ),
- "threshold": ("FLOAT", {"default": 0.5, "min": 0.0, "max": 1.0, "step": 0.01}),
- "dilation": ("INT", {"default": 4, "min": 0, "max": 255, "step": 1}),
- }
- }
-
- def doit(self, bbox_model, image, threshold, dilation):
- mmdet_results = inference_bbox(bbox_model, image, threshold)
- segmasks = create_segmasks(mmdet_results)
- if dilation > 0:
- segmasks = dilate_masks(segmasks, dilation)
-
- mask = combine_masks(segmasks)
- return (mask,)
-
-
class ToBinaryMask:
@classmethod
def INPUT_TYPES(s):
@@ -1513,9 +861,9 @@ class MaskPainter(nodes.PreviewImage):
mask = np.array(i.getchannel('A')).astype(np.float32) / 255.0
mask = 1. - torch.from_numpy(mask)
else:
- mask = torch.zeros((64, 64), dtype=torch.float32, device="cpu")
+ mask = torch.zeros((8, 8), dtype=torch.float32, device="cpu")
else:
- mask = torch.zeros((64, 64), dtype=torch.float32, device="cpu")
+ mask = torch.zeros((8, 8), dtype=torch.float32, device="cpu")
return (mask, )
@@ -1526,77 +874,84 @@ class MaskPainter(nodes.PreviewImage):
if mask_image is not None:
res['result'] = self.load_mask(mask_image)
else:
- mask = torch.zeros((64, 64), dtype=torch.float32, device="cpu")
+ mask = torch.zeros((8, 8), dtype=torch.float32, device="cpu")
res['result'] = (mask, )
return res
-NODE_CLASS_MAPPINGS = {
- "MMDetLoader": MMDetLoader,
- "SAMLoader": SAMLoader,
- "ONNXLoader": ONNXLoader,
+class DetailerForEach:
+ @classmethod
+ def INPUT_TYPES(s):
+ return {"required": {
+ "image": ("IMAGE",),
+ "segs": ("SEGS",),
+ "model": ("MODEL",),
+ "vae": ("VAE",),
+ "guide_size": ("FLOAT", {"default": 256, "min": 64, "max": nodes.MAX_RESOLUTION, "step": 8}),
+ "guide_size_for": (["bbox", "crop_region"],),
+ "seed": ("INT", {"default": 0, "min": 0, "max": 0xffffffffffffffff}),
+ "steps": ("INT", {"default": 20, "min": 1, "max": 10000}),
+ "cfg": ("FLOAT", {"default": 8.0, "min": 0.0, "max": 100.0}),
+ "sampler_name": (comfy.samplers.KSampler.SAMPLERS,),
+ "scheduler": (comfy.samplers.KSampler.SCHEDULERS,),
+ "positive": ("CONDITIONING",),
+ "negative": ("CONDITIONING",),
+ "denoise": ("FLOAT", {"default": 0.5, "min": 0.0001, "max": 1.0, "step": 0.01}),
+ "feather": ("INT", {"default": 5, "min": 0, "max": 100, "step": 1}),
+ "noise_mask": (["enabled", "disabled"],),
+ "force_inpaint": (["disabled", "enabled"],),
+ },
+ }
- "BboxDetectorForEach": BboxDetectorForEach,
- "SegmDetectorForEach": SegmDetectorForEach,
- "ONNXDetectorForEach": ONNXDetectorForEach,
+ RETURN_TYPES = ("IMAGE",)
+ FUNCTION = "doit"
- "BitwiseAndMaskForEach": BitwiseAndMaskForEach,
+ CATEGORY = "ImpactPack/Detailer"
- "DetailerForEach": DetailerForEach,
- "DetailerForEachDebug": DetailerForEachTest,
+ @staticmethod
+ def do_detail(image, segs, model, vae, guide_size, guide_size_for, seed, steps, cfg, sampler_name, scheduler,
+ positive, negative, denoise, feather, noise_mask, force_inpaint):
- "BboxDetectorCombined": BboxDetectorCombined,
- "SegmDetectorCombined": SegmDetectorCombined,
- "SAMDetectorCombined": SAMDetectorCombined,
+ image_pil = tensor2pil(image).convert('RGBA')
- "FaceDetailer": FaceDetailer,
- "FaceDetailerPipe": FaceDetailerPipe,
+ # shape = segs[0]
+ segs = segs[1]
+ for seg in segs:
+ cropped_image = seg.cropped_image if seg.cropped_image is not None \
+ else crop_ndarray4(image.numpy(), seg.crop_region)
- "BitwiseAndMask": BitwiseAndMask,
- "SubtractMask": SubtractMask,
- "Segs & Mask": SegsBitwiseAndMask,
- "SegsMaskCombine": SegsMaskCombine,
- "EmptySegs": EmptySEGS,
+ mask_pil = feather_mask(seg.cropped_mask, feather)
- "MaskToSEGS": MaskToSEGS,
- "ToBinaryMask": ToBinaryMask,
-
- "MaskPainter": MaskPainter,
-}
+ if noise_mask == "enabled":
+ cropped_mask = seg.cropped_mask
+ else:
+ cropped_mask = None
-# Expand Server api
+ enhanced_pil = core.enhance_detail(cropped_image, model, vae, guide_size, guide_size_for, seg.bbox,
+ seed, steps, cfg, sampler_name, scheduler,
+ positive, negative, denoise, cropped_mask, force_inpaint)
-import server
-from aiohttp import web
+ if not (enhanced_pil is None):
+ # don't latent composite-> converting to latent caused poor quality
+ # use image paste
+ image_pil.paste(enhanced_pil, (seg.crop_region[0], seg.crop_region[1]), mask_pil)
+ image_tensor = pil2tensor(image_pil.convert('RGB'))
-@server.PromptServer.instance.routes.post("/upload/temp")
-async def upload_image(request):
- upload_dir = folder_paths.get_temp_directory()
+ if len(segs) > 0:
+ enhanced_tensor = pil2tensor(enhanced_pil) if enhanced_pil is not None else None
+ return image_tensor, torch.from_numpy(cropped_image), enhanced_tensor,
+ else:
+ return image_tensor, None, None,
- if not os.path.exists(upload_dir):
- os.makedirs(upload_dir)
-
- post = await request.post()
- image = post.get("image")
+ def doit(self, image, segs, model, vae, guide_size, guide_size_for, seed, steps, cfg, sampler_name, scheduler,
+ positive, negative, denoise, feather, noise_mask, force_inpaint):
- if image and image.file:
- filename = image.filename
- if not filename:
- return web.Response(status=400)
+ enhanced_img, cropped, cropped_enhanced = \
+ DetailerForEach.do_detail(image, segs, model, vae, guide_size, guide_size_for, seed, steps, cfg,
+ sampler_name, scheduler, positive, negative, denoise, feather, noise_mask,
+ force_inpaint)
- split = os.path.splitext(filename)
- i = 1
- while os.path.exists(os.path.join(upload_dir, filename)):
- filename = f"{split[0]} ({i}){split[1]}"
- i += 1
+ return (enhanced_img,)
- filepath = os.path.join(upload_dir, filename)
-
- with open(filepath, "wb") as f:
- f.write(image.file.read())
-
- return web.json_response({"name": filename})
- else:
- return web.Response(status=400)
diff --git a/impact_pipe.py b/impact_pipe.py
new file mode 100644
index 00000000..0079be03
--- /dev/null
+++ b/impact_pipe.py
@@ -0,0 +1,205 @@
+class ToDetailerPipe:
+ @classmethod
+ def INPUT_TYPES(s):
+ return {"required": {
+ "model": ("MODEL",),
+ "vae": ("VAE",),
+ "positive": ("CONDITIONING",),
+ "negative": ("CONDITIONING",),
+ "bbox_detector": ("BBOX_DETECTOR", ),
+ },
+ "optional": {
+ "sam_model_opt": ("SAM_MODEL", ),
+ }}
+
+ RETURN_TYPES = ("DETAILER_PIPE", )
+ RETURN_NAMES = ("detailer_pipe", )
+ FUNCTION = "doit"
+
+ CATEGORY = "ImpactPack/Pipe"
+
+ def doit(self, model, vae, positive, negative, bbox_detector, sam_model_opt=None):
+ pipe = (model, vae, positive, negative, bbox_detector, sam_model_opt)
+ return (pipe, )
+
+
+class FromDetailerPipe:
+ @classmethod
+ def INPUT_TYPES(s):
+ return {"required": {"detailer_pipe": ("DETAILER_PIPE",), }, }
+
+ RETURN_TYPES = ("MODEL", "VAE", "CONDITIONING", "CONDITIONING", "BBOX_DETECTOR", "SAM_MODEL")
+ RETURN_NAMES = ("model", "vae", "positive", "negative", "bbox_detector", "sam_model_opt")
+ FUNCTION = "doit"
+
+ CATEGORY = "ImpactPack/Pipe"
+
+ def doit(self, detailer_pipe):
+ model, vae, positive, negative, bbox_detector, sam_model_opt = detailer_pipe
+ return model, vae, positive, negative, bbox_detector, sam_model_opt
+
+
+class ToBasicPipe:
+ @classmethod
+ def INPUT_TYPES(s):
+ return {"required": {
+ "model": ("MODEL",),
+ "clip": ("CLIP",),
+ "vae": ("VAE",),
+ "positive": ("CONDITIONING",),
+ "negative": ("CONDITIONING",),
+ },
+ }
+
+ RETURN_TYPES = ("BASIC_PIPE", )
+ RETURN_NAMES = ("basic_pipe", )
+ FUNCTION = "doit"
+
+ CATEGORY = "ImpactPack/Pipe"
+
+ def doit(self, model, clip, vae, positive, negative):
+ pipe = (model, clip, vae, positive, negative)
+ return (pipe, )
+
+
+class FromBasicPipe:
+ @classmethod
+ def INPUT_TYPES(s):
+ return {"required": { "basic_pipe": ("BASIC_PIPE",), }, }
+
+ RETURN_TYPES = ("MODEL", "CLIP", "VAE", "CONDITIONING", "CONDITIONING")
+ RETURN_NAMES = ("model", "clip", "vae", "positive", "negative")
+ FUNCTION = "doit"
+
+ CATEGORY = "ImpactPack/Pipe"
+
+ def doit(self, basic_pipe):
+ model, clip, vae, positive, negative = basic_pipe
+ return model, clip, vae, positive, negative
+
+
+class BasicPipeToDetailerPipe:
+ @classmethod
+ def INPUT_TYPES(s):
+ return {"required": {"basic_pipe": ("BASIC_PIPE",),
+ "bbox_detector": ("BBOX_DETECTOR", ), },
+ "optional": {"sam_model_opt": ("SAM_MODEL", ), },
+ }
+
+ RETURN_TYPES = ("DETAILER_PIPE", )
+ RETURN_NAMES = ("detailer_pipe", )
+ FUNCTION = "doit"
+
+ CATEGORY = "ImpactPack/Pipe"
+
+ def doit(self, basic_pipe, bbox_detector, sam_model_opt=None):
+ model, _, vae, positive, negative = basic_pipe
+ pipe = model, vae, positive, negative, bbox_detector, sam_model_opt
+ return (pipe, )
+
+
+class DetailerPipeToBasicPipe:
+ @classmethod
+ def INPUT_TYPES(s):
+ return {"required": {"detailer_pipe": ("DETAILER_PIPE",),
+ "clip": ("CLIP",), }, }
+
+ RETURN_TYPES = ("BASIC_PIPE", )
+ RETURN_NAMES = ("basic_pipe", )
+ FUNCTION = "doit"
+
+ CATEGORY = "ImpactPack/Pipe"
+
+ def doit(self, detailer_pipe, clip):
+ model, vae, positive, negative, _, _ = detailer_pipe
+ pipe = model, clip, vae, positive, negative
+ return (pipe, )
+
+
+class EditBasicPipe:
+ @classmethod
+ def INPUT_TYPES(s):
+ return {
+ "required": {"basic_pipe": ("BASIC_PIPE",), },
+ "optional": {
+ "model": ("MODEL",),
+ "clip": ("CLIP",),
+ "vae": ("VAE",),
+ "positive": ("CONDITIONING",),
+ "negative": ("CONDITIONING",),
+ },
+ }
+
+ RETURN_TYPES = ("BASIC_PIPE", )
+ RETURN_NAMES = ("basic_pipe", )
+ FUNCTION = "doit"
+
+ CATEGORY = "ImpactPack/Pipe"
+
+ def doit(self, basic_pipe, model=None, clip=None, vae=None, positive=None, negative=None):
+ res_model, res_clip, res_vae, res_positive, res_negative = basic_pipe
+
+ if model is not None:
+ res_model = model
+
+ if clip is not None:
+ res_clip = clip
+
+ if vae is not None:
+ res_vae = vae
+
+ if positive is not None:
+ res_positive = positive
+
+ if negative is not None:
+ res_negative = negative
+
+ pipe = res_model, res_clip, res_vae, res_positive, res_negative
+
+ return (pipe, )
+
+
+class EditDetailerPipe:
+ @classmethod
+ def INPUT_TYPES(s):
+ return {
+ "required": {"detailer_pipe": ("DETAILER_PIPE",), },
+ "optional": {
+ "model": ("MODEL",),
+ "vae": ("VAE",),
+ "positive": ("CONDITIONING",),
+ "negative": ("CONDITIONING",),
+ "bbox_detector": ("BBOX_DETECTOR",),
+ "sam_model": ("SAM_MODEL",), },
+ }
+
+ RETURN_TYPES = ("BASIC_PIPE",)
+ RETURN_NAMES = ("basic_pipe",)
+ FUNCTION = "doit"
+
+ CATEGORY = "ImpactPack/Pipe"
+
+ def doit(self, detailer_pipe, model=None, vae=None, positive=None, negative=None, bbox_detector=None, sam_model=None):
+ res_model, res_vae, res_positive, res_negative, res_bbox_detector, res_sam_model = detailer_pipe
+
+ if model is not None:
+ res_model = model
+
+ if vae is not None:
+ res_vae = vae
+
+ if positive is not None:
+ res_positive = positive
+
+ if negative is not None:
+ res_negative = negative
+
+ if bbox_detector is not None:
+ res_bbox_detector = bbox_detector
+
+ if sam_model is not None:
+ res_sam_model = sam_model
+
+ pipe = res_model, res_vae, res_positive, res_negative, res_bbox_detector, res_sam_model
+
+ return (pipe, )
diff --git a/impact_server.py b/impact_server.py
new file mode 100644
index 00000000..310520e0
--- /dev/null
+++ b/impact_server.py
@@ -0,0 +1,35 @@
+import os
+from aiohttp import web
+import server
+import folder_paths
+
+
+@server.PromptServer.instance.routes.post("/upload/temp")
+async def upload_image(request):
+ upload_dir = folder_paths.get_temp_directory()
+
+ if not os.path.exists(upload_dir):
+ os.makedirs(upload_dir)
+
+ post = await request.post()
+ image = post.get("image")
+
+ if image and image.file:
+ filename = image.filename
+ if not filename:
+ return web.Response(status=400)
+
+ split = os.path.splitext(filename)
+ i = 1
+ while os.path.exists(os.path.join(upload_dir, filename)):
+ filename = f"{split[0]} ({i}){split[1]}"
+ i += 1
+
+ filepath = os.path.join(upload_dir, filename)
+
+ with open(filepath, "wb") as f:
+ f.write(image.file.read())
+
+ return web.json_response({"name": filename})
+ else:
+ return web.Response(status=400)
diff --git a/impact_utils.py b/impact_utils.py
new file mode 100644
index 00000000..bed2ba92
--- /dev/null
+++ b/impact_utils.py
@@ -0,0 +1,189 @@
+import torch
+import cv2
+import numpy as np
+from PIL import Image, ImageFilter
+
+LANCZOS = (Image.Resampling.LANCZOS if hasattr(Image, 'Resampling') else Image.LANCZOS)
+
+def pil2tensor(image):
+ return torch.from_numpy(np.array(image).astype(np.float32) / 255.0).unsqueeze(0)
+
+
+def tensor2pil(image):
+ return Image.fromarray(np.clip(255. * image.cpu().numpy().squeeze(), 0, 255).astype(np.uint8))
+
+
+def center_of_bbox(bbox):
+ w, h = bbox[2] - bbox[0], bbox[3] - bbox[1]
+ return bbox[0] + w/2, bbox[1] + h/2
+
+
+def combine_masks(masks):
+ if len(masks) == 0:
+ return None
+ else:
+ initial_cv2_mask = np.array(masks[0][1])
+ combined_cv2_mask = initial_cv2_mask
+
+ for i in range(1, len(masks)):
+ cv2_mask = np.array(masks[i][1])
+ combined_cv2_mask = cv2.bitwise_or(combined_cv2_mask, cv2_mask)
+
+ mask = torch.from_numpy(combined_cv2_mask)
+ return mask
+
+
+def combine_masks2(masks):
+ if len(masks) == 0:
+ return None
+ else:
+ initial_cv2_mask = np.array(masks[0]).astype(np.uint8)
+ combined_cv2_mask = initial_cv2_mask
+
+ for i in range(1, len(masks)):
+ cv2_mask = np.array(masks[i]).astype(np.uint8)
+ combined_cv2_mask = cv2.bitwise_or(combined_cv2_mask, cv2_mask)
+
+ mask = torch.from_numpy(combined_cv2_mask)
+ return mask
+
+
+def bitwise_and_masks(mask1, mask2):
+ cv2_mask1 = np.array(mask1)
+ cv2_mask2 = np.array(mask2)
+ cv2_mask = cv2.bitwise_and(cv2_mask1, cv2_mask2)
+ mask = torch.from_numpy(cv2_mask)
+ return mask
+
+
+def to_binary_mask(mask):
+ mask = mask.clone()
+ mask[mask != 0] = 1.
+ return mask
+
+
+def dilate_mask(mask, dilation_factor, iter=1):
+ if dilation_factor == 0:
+ return mask
+
+ kernel = np.ones((dilation_factor,dilation_factor), np.uint8)
+ return cv2.dilate(mask, kernel, iter)
+
+
+def dilate_masks(segmasks, dilation_factor, iter=1):
+ if dilation_factor == 0:
+ return segmasks
+
+ dilated_masks = []
+ kernel = np.ones((dilation_factor,dilation_factor), np.uint8)
+ for i in range(len(segmasks)):
+ cv2_mask = segmasks[i][1]
+ dilated_mask = cv2.dilate(cv2_mask, kernel, iter)
+ item = (segmasks[i][0], dilated_mask, segmasks[i][2])
+ dilated_masks.append(item)
+ return dilated_masks
+
+
+def feather_mask(mask, thickness):
+ pil_mask = Image.fromarray(np.uint8(mask * 255))
+
+ # Create a feathered mask by applying a Gaussian blur to the mask
+ blurred_mask = pil_mask.filter(ImageFilter.GaussianBlur(thickness))
+ feathered_mask = Image.new("L", pil_mask.size, 0)
+ feathered_mask.paste(blurred_mask, (0, 0), blurred_mask)
+ return feathered_mask
+
+
+def subtract_masks(mask1, mask2):
+ cv2_mask1 = np.array(mask1) * 255
+ cv2_mask2 = np.array(mask2) * 255
+ cv2_mask = cv2.subtract(cv2_mask1, cv2_mask2)
+ mask = torch.from_numpy(cv2_mask) / 255.0
+ return mask
+
+
+def normalize_region(limit, startp, size):
+ if startp < 0:
+ new_endp = min(limit, size)
+ new_startp = 0
+ elif startp + size > limit:
+ new_startp = limit - size
+ new_endp = limit
+ else:
+ new_startp = startp
+ new_endp = min(limit, startp+size)
+
+ return int(new_startp), int(new_endp)
+
+
+def make_crop_region(w, h, bbox, crop_factor):
+ x1 = bbox[0]
+ y1 = bbox[1]
+ x2 = bbox[2]
+ y2 = bbox[3]
+
+ bbox_w = x2 - x1
+ bbox_h = y2 - y1
+
+ crop_w = bbox_w * crop_factor
+ crop_h = bbox_h * crop_factor
+
+ kernel_x = x1 + bbox_w / 2
+ kernel_y = y1 + bbox_h / 2
+
+ new_x1 = int(kernel_x - crop_w / 2)
+ new_y1 = int(kernel_y - crop_h / 2)
+
+ # make sure position in (w,h)
+ new_x1, new_x2 = normalize_region(w, new_x1, crop_w)
+ new_y1, new_y2 = normalize_region(h, new_y1, crop_h)
+
+ return [new_x1, new_y1, new_x2, new_y2]
+
+
+def crop_ndarray4(npimg, crop_region):
+ x1 = crop_region[0]
+ y1 = crop_region[1]
+ x2 = crop_region[2]
+ y2 = crop_region[3]
+
+ cropped = npimg[:, y1:y2, x1:x2, :]
+
+ return cropped
+
+
+def crop_ndarray2(npimg, crop_region):
+ x1 = crop_region[0]
+ y1 = crop_region[1]
+ x2 = crop_region[2]
+ y2 = crop_region[3]
+
+ cropped = npimg[y1:y2, x1:x2]
+
+ return cropped
+
+
+def crop_image(image, crop_region):
+ return crop_ndarray4(np.array(image), crop_region)
+
+
+def to_latent_image(pixels, vae):
+ x = (pixels.shape[1] // 8) * 8
+ y = (pixels.shape[2] // 8) * 8
+ if pixels.shape[1] != x or pixels.shape[2] != y:
+ pixels = pixels[:, :x, :y, :]
+ t = vae.encode(pixels[:, :, :, :3])
+ return {"samples": t}
+
+
+def scale_tensor(w, h, image):
+ image = tensor2pil(image)
+ scaled_image = image.resize((w, h), resample=LANCZOS)
+ return pil2tensor(scaled_image)
+
+
+def scale_tensor_and_to_pil(w,h, image):
+ image = tensor2pil(image)
+ return image.resize((w, h), resample=LANCZOS)
+
+
diff --git a/legacy.py b/legacy.py
new file mode 100644
index 00000000..e69de29b
diff --git a/legacy_nodes.py b/legacy_nodes.py
new file mode 100644
index 00000000..114b3acf
--- /dev/null
+++ b/legacy_nodes.py
@@ -0,0 +1,203 @@
+import folder_paths
+import impact_core as core
+from impact_utils import *
+from impact_core import SEG
+
+
+class NO_BBOX_MODEL:
+ pass
+
+
+class NO_SEGM_MODEL:
+ pass
+
+
+class MMDetLoader:
+ @classmethod
+ def INPUT_TYPES(s):
+ bboxs = ["bbox/"+x for x in folder_paths.get_filename_list("mmdets_bbox")]
+ segms = ["segm/"+x for x in folder_paths.get_filename_list("mmdets_segm")]
+ return {"required": {"model_name": (bboxs + segms, )}}
+ RETURN_TYPES = ("BBOX_MODEL", "SEGM_MODEL")
+ FUNCTION = "load_mmdet"
+
+ CATEGORY = "ImpactPack/Legacy"
+
+ def load_mmdet(self, model_name):
+ mmdet_path = folder_paths.get_full_path("mmdets", model_name)
+ model = core.load_mmdet(mmdet_path)
+
+ if model_name.startswith("bbox"):
+ return model, NO_SEGM_MODEL()
+ else:
+ return NO_BBOX_MODEL(), model
+
+
+class BboxDetectorForEach:
+ @classmethod
+ def INPUT_TYPES(s):
+ return {"required": {
+ "bbox_model": ("BBOX_MODEL", ),
+ "image": ("IMAGE", ),
+ "threshold": ("FLOAT", {"default": 0.5, "min": 0.0, "max": 1.0, "step": 0.01}),
+ "dilation": ("INT", {"default": 10, "min": 0, "max": 255, "step": 1}),
+ "crop_factor": ("FLOAT", {"default": 3.0, "min": 1.0, "max": 10, "step": 0.1}),
+ }
+ }
+
+ RETURN_TYPES = ("SEGS", )
+ FUNCTION = "doit"
+
+ CATEGORY = "ImpactPack/Legacy"
+
+ @staticmethod
+ def detect(bbox_model, image, threshold, dilation, crop_factor):
+ mmdet_results = core.inference_bbox(bbox_model, image, threshold)
+ segmasks = core.create_segmasks(mmdet_results)
+
+ if dilation > 0:
+ segmasks = dilate_masks(segmasks, dilation)
+
+ items = []
+ h = image.shape[1]
+ w = image.shape[2]
+ for x in segmasks:
+ item_bbox = x[0]
+ item_mask = x[1]
+
+ crop_region = make_crop_region(w, h, item_bbox, crop_factor)
+ cropped_image = crop_image(image, crop_region)
+ cropped_mask = crop_ndarray2(item_mask, crop_region)
+ confidence = x[2]
+ # bbox_size = (item_bbox[2]-item_bbox[0],item_bbox[3]-item_bbox[1]) # (w,h)
+
+ item = SEG(cropped_image, cropped_mask, confidence, crop_region, item_bbox)
+ items.append(item)
+
+ shape = h, w
+ return shape, items
+
+ def doit(self, bbox_model, image, threshold, dilation, crop_factor):
+ return (BboxDetectorForEach.detect(bbox_model, image, threshold, dilation, crop_factor), )
+
+
+class SegmDetectorCombined:
+ @classmethod
+ def INPUT_TYPES(s):
+ return {"required": {
+ "segm_model": ("SEGM_MODEL", ),
+ "image": ("IMAGE", ),
+ "threshold": ("FLOAT", {"default": 0.5, "min": 0.0, "max": 1.0, "step": 0.01}),
+ "dilation": ("INT", {"default": 0, "min": 0, "max": 255, "step": 1}),
+ }
+ }
+
+ RETURN_TYPES = ("MASK",)
+ FUNCTION = "doit"
+
+ CATEGORY = "ImpactPack/Legacy"
+
+ def doit(self, segm_model, image, threshold, dilation):
+ mmdet_results = core.inference_segm(image, segm_model, threshold)
+ segmasks = core.create_segmasks(mmdet_results)
+ if dilation > 0:
+ segmasks = dilate_masks(segmasks, dilation)
+
+ mask = combine_masks(segmasks)
+ return (mask,)
+
+
+class BboxDetectorCombined(SegmDetectorCombined):
+ @classmethod
+ def INPUT_TYPES(s):
+ return {"required": {
+ "bbox_model": ("BBOX_MODEL", ),
+ "image": ("IMAGE", ),
+ "threshold": ("FLOAT", {"default": 0.5, "min": 0.0, "max": 1.0, "step": 0.01}),
+ "dilation": ("INT", {"default": 4, "min": 0, "max": 255, "step": 1}),
+ }
+ }
+
+ def doit(self, bbox_model, image, threshold, dilation):
+ mmdet_results = core.inference_bbox(bbox_model, image, threshold)
+ segmasks = core.create_segmasks(mmdet_results)
+ if dilation > 0:
+ segmasks = dilate_masks(segmasks, dilation)
+
+ mask = combine_masks(segmasks)
+ return (mask,)
+
+
+class SegmDetectorForEach:
+ @classmethod
+ def INPUT_TYPES(s):
+ return {"required": {
+ "segm_model": ("SEGM_MODEL", ),
+ "image": ("IMAGE", ),
+ "threshold": ("FLOAT", {"default": 0.5, "min": 0.0, "max": 1.0, "step": 0.01}),
+ "dilation": ("INT", {"default": 10, "min": 0, "max": 255, "step": 1}),
+ "crop_factor": ("FLOAT", {"default": 3.0, "min": 1.0, "max": 10, "step": 0.1}),
+ }
+ }
+
+ RETURN_TYPES = ("SEGS", )
+ FUNCTION = "doit"
+
+ CATEGORY = "ImpactPack/Legacy"
+
+ def doit(self, segm_model, image, threshold, dilation, crop_factor):
+ mmdet_results = core.inference_segm(image, segm_model, threshold)
+ segmasks = core.create_segmasks(mmdet_results)
+
+ if dilation > 0:
+ segmasks = dilate_masks(segmasks, dilation)
+
+ items = []
+ h = image.shape[1]
+ w = image.shape[2]
+ for x in segmasks:
+ item_bbox = x[0]
+ item_mask = x[1]
+
+ crop_region = make_crop_region(w, h, item_bbox, crop_factor)
+ cropped_image = crop_image(image, crop_region)
+ cropped_mask = crop_ndarray2(item_mask, crop_region)
+ confidence = x[2]
+
+ item = SEG(cropped_image, cropped_mask, confidence, crop_region, item_bbox)
+ items.append(item)
+
+ shape = h,w
+ return ((shape, items), )
+
+
+class SegsMaskCombine:
+ @classmethod
+ def INPUT_TYPES(s):
+ return {"required": {
+ "segs": ("SEGS", ),
+ "image": ("IMAGE", ),
+ }
+ }
+
+ RETURN_TYPES = ("MASK",)
+ FUNCTION = "doit"
+
+ CATEGORY = "ImpactPack/Legacy"
+
+ @staticmethod
+ def combine(segs, image):
+ h = image.shape[1]
+ w = image.shape[2]
+
+ mask = np.zeros((h, w), dtype=np.uint8)
+
+ for seg in segs[1]:
+ cropped_mask = seg.cropped_mask
+ crop_region = seg.crop_region
+ mask[crop_region[1]:crop_region[3], crop_region[0]:crop_region[2]] |= (cropped_mask * 255).astype(np.uint8)
+
+ return torch.from_numpy(mask.astype(np.float32) / 255.0)
+
+ def doit(self, segs, image):
+ return (SegsMaskCombine.combine(segs, image), )
\ No newline at end of file
diff --git a/misc/2pass-1pass.png b/misc/2pass-1pass.png
deleted file mode 100644
index 867efafd..00000000
Binary files a/misc/2pass-1pass.png and /dev/null differ
diff --git a/misc/2pass-2pass.png b/misc/2pass-2pass.png
deleted file mode 100644
index 887534b2..00000000
Binary files a/misc/2pass-2pass.png and /dev/null differ
diff --git a/misc/2pass-advanced.png b/misc/2pass-advanced.png
deleted file mode 100644
index e43a239b..00000000
Binary files a/misc/2pass-advanced.png and /dev/null differ
diff --git a/misc/2pass-original.png b/misc/2pass-original.png
deleted file mode 100644
index fa4db390..00000000
Binary files a/misc/2pass-original.png and /dev/null differ
diff --git a/misc/2pass-refine-old.json b/misc/2pass-refine-old.json
deleted file mode 100644
index 7ce3cfb2..00000000
--- a/misc/2pass-refine-old.json
+++ /dev/null
@@ -1,940 +0,0 @@
-{
- "last_node_id": 77,
- "last_link_id": 177,
- "nodes": [
- {
- "id": 67,
- "type": "BboxDetectorForEach",
- "pos": [
- 738.6226098144523,
- 108.70101345825232
- ],
- "size": {
- "0": 290.3233947753906,
- "1": 126.13687896728516
- },
- "flags": {},
- "order": 9,
- "mode": 0,
- "inputs": [
- {
- "name": "bbox_model",
- "type": "BBOX_MODEL",
- "link": 176
- },
- {
- "name": "image",
- "type": "IMAGE",
- "link": 140
- }
- ],
- "outputs": [
- {
- "name": "SEGS",
- "type": "SEGS",
- "links": [
- 152
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "BboxDetectorForEach"
- },
- "widgets_values": [
- 0.5,
- 10,
- 4
- ],
- "color": "#232",
- "bgcolor": "#353"
- },
- {
- "id": 76,
- "type": "Reroute",
- "pos": [
- 961.6226098144517,
- 1.701013458251873
- ],
- "size": [
- 124,
- 26
- ],
- "flags": {},
- "order": 5,
- "mode": 0,
- "inputs": [
- {
- "name": "",
- "type": "*",
- "link": 174,
- "pos": [
- 62,
- 0
- ]
- }
- ],
- "outputs": [
- {
- "name": "BBOX_MODEL",
- "type": "BBOX_MODEL",
- "links": [
- 175,
- 176
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "showOutputText": true,
- "horizontal": true
- }
- },
- {
- "id": 44,
- "type": "EmptyLatentImage",
- "pos": [
- 401.62260981445274,
- 110.70101345825232
- ],
- "size": {
- "0": 297.0506896972656,
- "1": 124.40960693359375
- },
- "flags": {
- "collapsed": false
- },
- "order": 0,
- "mode": 0,
- "outputs": [
- {
- "name": "LATENT",
- "type": "LATENT",
- "links": [
- 73
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "EmptyLatentImage"
- },
- "widgets_values": [
- 256,
- 320,
- 1
- ],
- "color": "#322",
- "bgcolor": "#533"
- },
- {
- "id": 40,
- "type": "VAEDecode",
- "pos": [
- 608.6226098144529,
- 30.701013458251865
- ],
- "size": {
- "0": 311,
- "1": 46
- },
- "flags": {
- "collapsed": true
- },
- "order": 7,
- "mode": 0,
- "inputs": [
- {
- "name": "samples",
- "type": "LATENT",
- "link": 74
- },
- {
- "name": "vae",
- "type": "VAE",
- "link": 137
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 110,
- 140,
- 155
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "VAEDecode"
- },
- "color": "#322",
- "bgcolor": "#533"
- },
- {
- "id": 30,
- "type": "CheckpointLoader",
- "pos": [
- 50.62260981445271,
- 109.70101345825233
- ],
- "size": {
- "0": 289.5052795410156,
- "1": 122
- },
- "flags": {},
- "order": 1,
- "mode": 0,
- "outputs": [
- {
- "name": "MODEL",
- "type": "MODEL",
- "links": [
- 72,
- 153,
- 168
- ],
- "slot_index": 0
- },
- {
- "name": "CLIP",
- "type": "CLIP",
- "links": [
- 49,
- 62
- ],
- "slot_index": 1
- },
- {
- "name": "VAE",
- "type": "VAE",
- "links": [
- 137,
- 156,
- 167
- ],
- "slot_index": 2
- }
- ],
- "properties": {
- "Node name for S&R": "CheckpointLoader"
- },
- "widgets_values": [
- "anything_v3.yaml",
- "V07_v07.safetensors"
- ],
- "color": "#233",
- "bgcolor": "#355"
- },
- {
- "id": 71,
- "type": "SaveImage",
- "pos": [
- 735.4799597167967,
- 759.880029144287
- ],
- "size": {
- "0": 302.5051574707031,
- "1": 388.0459289550781
- },
- "flags": {},
- "order": 11,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 161
- }
- ],
- "title": "Refined Image",
- "properties": {},
- "widgets_values": [
- "refined"
- ],
- "color": "#232",
- "bgcolor": "#353"
- },
- {
- "id": 70,
- "type": "DetailerForEach",
- "pos": [
- 733.6226098144523,
- 289.70101345825253
- ],
- "size": {
- "0": 297.7779235839844,
- "1": 418
- },
- "flags": {},
- "order": 10,
- "mode": 0,
- "inputs": [
- {
- "name": "image",
- "type": "IMAGE",
- "link": 155
- },
- {
- "name": "segs",
- "type": "SEGS",
- "link": 152
- },
- {
- "name": "model",
- "type": "MODEL",
- "link": 153
- },
- {
- "name": "vae",
- "type": "VAE",
- "link": 156
- },
- {
- "name": "positive",
- "type": "CONDITIONING",
- "link": 158
- },
- {
- "name": "negative",
- "type": "CONDITIONING",
- "link": 160
- },
- {
- "name": "external_seed",
- "type": "SEED",
- "link": null
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 161,
- 172,
- 173
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "DetailerForEach"
- },
- "widgets_values": [
- 256,
- "bbox",
- 650434405941391,
- "randomize",
- 20,
- 8,
- "euler",
- "karras",
- 0.6,
- 5,
- "enabled"
- ],
- "color": "#232",
- "bgcolor": "#353"
- },
- {
- "id": 75,
- "type": "SaveImage",
- "pos": [
- 1069.4799597167953,
- 759.880029144287
- ],
- "size": {
- "0": 287.59619140625,
- "1": 388.227783203125
- },
- "flags": {},
- "order": 14,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 171
- }
- ],
- "title": "2nd Refined Image",
- "properties": {},
- "widgets_values": [
- "refined"
- ],
- "color": "#223",
- "bgcolor": "#335"
- },
- {
- "id": 41,
- "type": "PreviewImage",
- "pos": [
- 404.47995971679666,
- 766.880029144287
- ],
- "size": {
- "0": 300.68701171875,
- "1": 383.2276916503906
- },
- "flags": {},
- "order": 8,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 110
- }
- ],
- "title": "Prompt Image",
- "properties": {
- "Node name for S&R": "PreviewImage"
- },
- "color": "#322",
- "bgcolor": "#533"
- },
- {
- "id": 37,
- "type": "CLIPTextEncode",
- "pos": [
- 45.47995971679696,
- 528.880029144287
- ],
- "size": {
- "0": 296.4716796875,
- "1": 176.8111572265625
- },
- "flags": {},
- "order": 4,
- "mode": 0,
- "inputs": [
- {
- "name": "clip",
- "type": "CLIP",
- "link": 62
- }
- ],
- "outputs": [
- {
- "name": "CONDITIONING",
- "type": "CONDITIONING",
- "links": [
- 71,
- 158,
- 160,
- 165
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "CLIPTextEncode"
- },
- "widgets_values": [
- "low quality, worst quality, bad anatomy"
- ],
- "color": "#233",
- "bgcolor": "#355"
- },
- {
- "id": 31,
- "type": "CLIPTextEncode",
- "pos": [
- 48.47995971679696,
- 294.8800291442872
- ],
- "size": {
- "0": 290.4716796875,
- "1": 180.8111572265625
- },
- "flags": {},
- "order": 3,
- "mode": 0,
- "inputs": [
- {
- "name": "clip",
- "type": "CLIP",
- "link": 49
- }
- ],
- "outputs": [
- {
- "name": "CONDITIONING",
- "type": "CONDITIONING",
- "links": [
- 70,
- 166
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "CLIPTextEncode"
- },
- "widgets_values": [
- "1girl, photorealistic:1.4, masterpiece, jump, full shot, jacket, jean shorts, perfect anatomy, street city background, detailed eyes, smile"
- ],
- "color": "#233",
- "bgcolor": "#355"
- },
- {
- "id": 42,
- "type": "KSampler",
- "pos": [
- 402.47995971679666,
- 291.8800291442872
- ],
- "size": {
- "0": 300.4716796875,
- "1": 416.8111572265625
- },
- "flags": {},
- "order": 6,
- "mode": 0,
- "inputs": [
- {
- "name": "model",
- "type": "MODEL",
- "link": 72
- },
- {
- "name": "positive",
- "type": "CONDITIONING",
- "link": 70
- },
- {
- "name": "negative",
- "type": "CONDITIONING",
- "link": 71
- },
- {
- "name": "latent_image",
- "type": "LATENT",
- "link": 73
- }
- ],
- "outputs": [
- {
- "name": "LATENT",
- "type": "LATENT",
- "links": [
- 74
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "KSampler"
- },
- "widgets_values": [
- 805157917915454,
- false,
- 20,
- 8,
- "euler",
- "karras",
- 1
- ],
- "color": "#322",
- "bgcolor": "#533"
- },
- {
- "id": 73,
- "type": "BboxDetectorForEach",
- "pos": [
- 1067.4799597167953,
- 107.88002914428695
- ],
- "size": {
- "0": 284.8689270019531,
- "1": 126
- },
- "flags": {},
- "order": 12,
- "mode": 0,
- "inputs": [
- {
- "name": "bbox_model",
- "type": "BBOX_MODEL",
- "link": 175
- },
- {
- "name": "image",
- "type": "IMAGE",
- "link": 172
- }
- ],
- "outputs": [
- {
- "name": "SEGS",
- "type": "SEGS",
- "links": [
- 164
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "BboxDetectorForEach"
- },
- "widgets_values": [
- 0.5,
- 10,
- 4
- ],
- "color": "#223",
- "bgcolor": "#335"
- },
- {
- "id": 45,
- "type": "MMDetLoader",
- "pos": [
- 1412.1400225830075,
- 115.2000213623046
- ],
- "size": {
- "0": 348.3031005859375,
- "1": 99.29615783691406
- },
- "flags": {},
- "order": 2,
- "mode": 0,
- "outputs": [
- {
- "name": "BBOX_MODEL",
- "type": "BBOX_MODEL",
- "links": [
- 174
- ],
- "slot_index": 0
- },
- {
- "name": "SEGM_MODEL",
- "type": "SEGM_MODEL",
- "links": null
- }
- ],
- "properties": {
- "Node name for S&R": "MMDetLoader"
- },
- "widgets_values": [
- "bbox/mmdet_anime-face_yolov3.pth"
- ],
- "color": "#222",
- "bgcolor": "#000"
- },
- {
- "id": 74,
- "type": "DetailerForEach",
- "pos": [
- 1068,
- 288
- ],
- "size": [
- 285.10000305175777,
- 420.4000015258789
- ],
- "flags": {},
- "order": 13,
- "mode": 0,
- "inputs": [
- {
- "name": "image",
- "type": "IMAGE",
- "link": 173
- },
- {
- "name": "segs",
- "type": "SEGS",
- "link": 164
- },
- {
- "name": "model",
- "type": "MODEL",
- "link": 168
- },
- {
- "name": "vae",
- "type": "VAE",
- "link": 167
- },
- {
- "name": "positive",
- "type": "CONDITIONING",
- "link": 166
- },
- {
- "name": "negative",
- "type": "CONDITIONING",
- "link": 165
- },
- {
- "name": "external_seed",
- "type": "SEED",
- "link": null
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 171
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "DetailerForEach"
- },
- "widgets_values": [
- 256,
- "bbox",
- 621928064748632,
- "randomize",
- 20,
- 8,
- "euler",
- "karras",
- 0.6,
- 5,
- "enabled"
- ],
- "color": "#223",
- "bgcolor": "#335"
- }
- ],
- "links": [
- [
- 49,
- 30,
- 1,
- 31,
- 0,
- "CLIP"
- ],
- [
- 62,
- 30,
- 1,
- 37,
- 0,
- "CLIP"
- ],
- [
- 70,
- 31,
- 0,
- 42,
- 1,
- "CONDITIONING"
- ],
- [
- 71,
- 37,
- 0,
- 42,
- 2,
- "CONDITIONING"
- ],
- [
- 72,
- 30,
- 0,
- 42,
- 0,
- "MODEL"
- ],
- [
- 73,
- 44,
- 0,
- 42,
- 3,
- "LATENT"
- ],
- [
- 74,
- 42,
- 0,
- 40,
- 0,
- "LATENT"
- ],
- [
- 110,
- 40,
- 0,
- 41,
- 0,
- "IMAGE"
- ],
- [
- 137,
- 30,
- 2,
- 40,
- 1,
- "VAE"
- ],
- [
- 140,
- 40,
- 0,
- 67,
- 1,
- "IMAGE"
- ],
- [
- 152,
- 67,
- 0,
- 70,
- 1,
- "SEGS"
- ],
- [
- 153,
- 30,
- 0,
- 70,
- 2,
- "MODEL"
- ],
- [
- 155,
- 40,
- 0,
- 70,
- 0,
- "IMAGE"
- ],
- [
- 156,
- 30,
- 2,
- 70,
- 3,
- "VAE"
- ],
- [
- 158,
- 37,
- 0,
- 70,
- 4,
- "CONDITIONING"
- ],
- [
- 160,
- 37,
- 0,
- 70,
- 5,
- "CONDITIONING"
- ],
- [
- 161,
- 70,
- 0,
- 71,
- 0,
- "IMAGE"
- ],
- [
- 164,
- 73,
- 0,
- 74,
- 1,
- "SEGS"
- ],
- [
- 165,
- 37,
- 0,
- 74,
- 5,
- "CONDITIONING"
- ],
- [
- 166,
- 31,
- 0,
- 74,
- 4,
- "CONDITIONING"
- ],
- [
- 167,
- 30,
- 2,
- 74,
- 3,
- "VAE"
- ],
- [
- 168,
- 30,
- 0,
- 74,
- 2,
- "MODEL"
- ],
- [
- 171,
- 74,
- 0,
- 75,
- 0,
- "IMAGE"
- ],
- [
- 172,
- 70,
- 0,
- 73,
- 1,
- "IMAGE"
- ],
- [
- 173,
- 70,
- 0,
- 74,
- 0,
- "IMAGE"
- ],
- [
- 174,
- 45,
- 0,
- 76,
- 0,
- "*"
- ],
- [
- 175,
- 76,
- 0,
- 73,
- 0,
- "BBOX_MODEL"
- ],
- [
- 176,
- 76,
- 0,
- 67,
- 0,
- "BBOX_MODEL"
- ]
- ],
- "groups": [],
- "config": {},
- "extra": {},
- "version": 0.4
-}
\ No newline at end of file
diff --git a/misc/2pass-simple.json b/misc/2pass-simple.json
deleted file mode 100644
index dafb5975..00000000
--- a/misc/2pass-simple.json
+++ /dev/null
@@ -1,1030 +0,0 @@
-{
- "last_node_id": 27,
- "last_link_id": 55,
- "nodes": [
- {
- "id": 9,
- "type": "Reroute",
- "pos": [
- 890,
- 150
- ],
- "size": [
- 82,
- 26
- ],
- "flags": {},
- "order": 7,
- "mode": 0,
- "inputs": [
- {
- "name": "",
- "type": "*",
- "link": 11,
- "pos": [
- 41,
- 0
- ],
- "slot_index": 0
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 45
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "showOutputText": true,
- "horizontal": true
- }
- },
- {
- "id": 4,
- "type": "CheckpointLoaderSimple",
- "pos": [
- 20,
- 310
- ],
- "size": {
- "0": 315,
- "1": 98
- },
- "flags": {},
- "order": 0,
- "mode": 0,
- "outputs": [
- {
- "name": "MODEL",
- "type": "MODEL",
- "links": [
- 46
- ]
- },
- {
- "name": "CLIP",
- "type": "CLIP",
- "links": [
- 4,
- 5
- ],
- "slot_index": 1
- },
- {
- "name": "VAE",
- "type": "VAE",
- "links": [
- 47
- ],
- "slot_index": 2
- }
- ],
- "properties": {
- "Node name for S&R": "CheckpointLoaderSimple"
- },
- "widgets_values": [
- "V07_v07.safetensors"
- ],
- "color": "#222",
- "bgcolor": "#000"
- },
- {
- "id": 15,
- "type": "MMDetLoader",
- "pos": [
- 20,
- 460
- ],
- "size": {
- "0": 315,
- "1": 78
- },
- "flags": {},
- "order": 1,
- "mode": 0,
- "outputs": [
- {
- "name": "BBOX_MODEL",
- "type": "BBOX_MODEL",
- "links": [
- 50
- ]
- },
- {
- "name": "SEGM_MODEL",
- "type": "SEGM_MODEL",
- "links": null
- }
- ],
- "properties": {
- "Node name for S&R": "MMDetLoader"
- },
- "widgets_values": [
- "bbox/mmdet_anime-face_yolov3.pth"
- ],
- "color": "#223",
- "bgcolor": "#335"
- },
- {
- "id": 10,
- "type": "Reroute",
- "pos": [
- 1530,
- 120
- ],
- "size": [
- 82,
- 26
- ],
- "flags": {},
- "order": 6,
- "mode": 0,
- "inputs": [
- {
- "name": "",
- "type": "*",
- "link": 12,
- "slot_index": 0
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 11
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "showOutputText": true,
- "horizontal": false
- }
- },
- {
- "id": 21,
- "type": "Reroute",
- "pos": [
- 1500,
- 50
- ],
- "size": [
- 149.2,
- 26
- ],
- "flags": {},
- "order": 11,
- "mode": 0,
- "inputs": [
- {
- "name": "",
- "type": "*",
- "link": 54
- }
- ],
- "outputs": [
- {
- "name": "DETAILER_PIPE",
- "type": "DETAILER_PIPE",
- "links": [
- 36
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "showOutputText": true,
- "horizontal": false
- }
- },
- {
- "id": 13,
- "type": "Reroute",
- "pos": [
- 1490,
- 180
- ],
- "size": [
- 82,
- 26
- ],
- "flags": {},
- "order": 12,
- "mode": 0,
- "inputs": [
- {
- "name": "",
- "type": "*",
- "link": 21
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 22,
- 38
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "showOutputText": true,
- "horizontal": false
- }
- },
- {
- "id": 22,
- "type": "Reroute",
- "pos": [
- 1790,
- 180
- ],
- "size": [
- 82,
- 26
- ],
- "flags": {},
- "order": 15,
- "mode": 0,
- "inputs": [
- {
- "name": "",
- "type": "*",
- "link": 38
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 39
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "showOutputText": true,
- "horizontal": false
- }
- },
- {
- "id": 12,
- "type": "Reroute",
- "pos": [
- 1280,
- 180
- ],
- "size": [
- 82,
- 26
- ],
- "flags": {},
- "order": 9,
- "mode": 0,
- "inputs": [
- {
- "name": "",
- "type": "*",
- "link": 52
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 21
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "showOutputText": true,
- "horizontal": false
- }
- },
- {
- "id": 5,
- "type": "CLIPTextEncode",
- "pos": [
- 440,
- 490
- ],
- "size": {
- "0": 400,
- "1": 200
- },
- "flags": {},
- "order": 4,
- "mode": 0,
- "inputs": [
- {
- "name": "clip",
- "type": "CLIP",
- "link": 4
- }
- ],
- "outputs": [
- {
- "name": "CONDITIONING",
- "type": "CONDITIONING",
- "links": [
- 48
- ],
- "slot_index": 0
- }
- ],
- "title": "Positive",
- "properties": {
- "Node name for S&R": "CLIPTextEncode"
- },
- "widgets_values": [
- "1girl, photorealistic:1.4, masterpiece, jump, full shot, jacket, jean shorts, perfect anatomy, street city background, detailed eyes, smile"
- ],
- "color": "#322",
- "bgcolor": "#533"
- },
- {
- "id": 7,
- "type": "PreviewImage",
- "pos": [
- 1580,
- 290
- ],
- "size": {
- "0": 283,
- "1": 314
- },
- "flags": {},
- "order": 14,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 22
- }
- ],
- "title": "1pass (rough fix)",
- "properties": {
- "Node name for S&R": "PreviewImage"
- },
- "color": "#223",
- "bgcolor": "#335"
- },
- {
- "id": 17,
- "type": "MaskToImage",
- "pos": [
- 1580,
- 650
- ],
- "size": {
- "0": 283,
- "1": 27
- },
- "flags": {},
- "order": 10,
- "mode": 0,
- "inputs": [
- {
- "name": "mask",
- "type": "MASK",
- "link": 53
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 33
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "MaskToImage"
- },
- "color": "#223",
- "bgcolor": "#335"
- },
- {
- "id": 24,
- "type": "PreviewImage",
- "pos": [
- 2270,
- 290
- ],
- "size": {
- "0": 281,
- "1": 310
- },
- "flags": {},
- "order": 17,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 43
- }
- ],
- "title": "2pass (detailed)",
- "properties": {
- "Node name for S&R": "PreviewImage"
- },
- "color": "#2a363b",
- "bgcolor": "#3f5159"
- },
- {
- "id": 25,
- "type": "MaskToImage",
- "pos": [
- 2270,
- 650
- ],
- "size": {
- "0": 281,
- "1": 27
- },
- "flags": {},
- "order": 18,
- "mode": 0,
- "inputs": [
- {
- "name": "mask",
- "type": "MASK",
- "link": 44
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 42
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "MaskToImage"
- },
- "color": "#2a363b",
- "bgcolor": "#3f5159"
- },
- {
- "id": 26,
- "type": "PreviewImage",
- "pos": [
- 2270,
- 724
- ],
- "size": {
- "0": 280,
- "1": 223
- },
- "flags": {},
- "order": 19,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 42
- }
- ],
- "title": "2pass - mask",
- "properties": {
- "Node name for S&R": "PreviewImage"
- },
- "color": "#2a363b",
- "bgcolor": "#3f5159"
- },
- {
- "id": 6,
- "type": "CLIPTextEncode",
- "pos": [
- 440,
- 754
- ],
- "size": {
- "0": 400,
- "1": 200
- },
- "flags": {},
- "order": 5,
- "mode": 0,
- "inputs": [
- {
- "name": "clip",
- "type": "CLIP",
- "link": 5
- }
- ],
- "outputs": [
- {
- "name": "CONDITIONING",
- "type": "CONDITIONING",
- "links": [
- 49
- ],
- "slot_index": 0
- }
- ],
- "title": "Negative",
- "properties": {
- "Node name for S&R": "CLIPTextEncode"
- },
- "widgets_values": [
- "low quality, worst quality, bad anatomy"
- ],
- "color": "#322",
- "bgcolor": "#533"
- },
- {
- "id": 1,
- "type": "LoadImage",
- "pos": [
- 1276,
- 293
- ],
- "size": [
- 270,
- 660
- ],
- "flags": {},
- "order": 2,
- "mode": 0,
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 12
- ],
- "slot_index": 0
- },
- {
- "name": "MASK",
- "type": "MASK",
- "links": null
- }
- ],
- "title": "Prompt",
- "properties": {
- "Node name for S&R": "LoadImage"
- },
- "widgets_values": [
- "2pass-original.png",
- "image"
- ],
- "color": "#322",
- "bgcolor": "#533"
- },
- {
- "id": 18,
- "type": "PreviewImage",
- "pos": [
- 1580,
- 727
- ],
- "size": {
- "0": 282,
- "1": 223
- },
- "flags": {},
- "order": 13,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 33
- }
- ],
- "title": "1pass - mask",
- "properties": {
- "Node name for S&R": "PreviewImage"
- },
- "color": "#223",
- "bgcolor": "#335"
- },
- {
- "id": 16,
- "type": "SAMLoader",
- "pos": [
- 20,
- 580
- ],
- "size": {
- "0": 314,
- "1": 66
- },
- "flags": {},
- "order": 3,
- "mode": 0,
- "outputs": [
- {
- "name": "SAM_MODEL",
- "type": "SAM_MODEL",
- "links": [
- 55
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "SAMLoader"
- },
- "widgets_values": [
- "sam_vit_b_01ec64.pth"
- ],
- "color": "#223",
- "bgcolor": "#335"
- },
- {
- "id": 27,
- "type": "FaceDetailer",
- "pos": [
- 901,
- 295
- ],
- "size": {
- "0": 342.5999755859375,
- "1": 658
- },
- "flags": {},
- "order": 8,
- "mode": 0,
- "inputs": [
- {
- "name": "image",
- "type": "IMAGE",
- "link": 45
- },
- {
- "name": "model",
- "type": "MODEL",
- "link": 46
- },
- {
- "name": "vae",
- "type": "VAE",
- "link": 47
- },
- {
- "name": "positive",
- "type": "CONDITIONING",
- "link": 48
- },
- {
- "name": "negative",
- "type": "CONDITIONING",
- "link": 49
- },
- {
- "name": "bbox_model",
- "type": "BBOX_MODEL",
- "link": 50
- },
- {
- "name": "sam_model_opt",
- "type": "SAM_MODEL",
- "link": 55
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 52
- ],
- "slot_index": 0
- },
- {
- "name": "MASK",
- "type": "MASK",
- "links": [
- 53
- ],
- "slot_index": 1
- },
- {
- "name": "DETAILER_PIPE",
- "type": "DETAILER_PIPE",
- "links": [
- 54
- ],
- "slot_index": 2
- }
- ],
- "properties": {
- "Node name for S&R": "FaceDetailer"
- },
- "widgets_values": [
- 256,
- "bbox",
- 267026622830019,
- "fixed",
- 20,
- 8,
- "euler",
- "karras",
- 0.6,
- 5,
- "disabled",
- "disabled",
- 0.5,
- 20,
- 4,
- "center-1",
- 20,
- 0.93,
- 0,
- 0.7,
- "False"
- ],
- "color": "#223",
- "bgcolor": "#335"
- },
- {
- "id": 20,
- "type": "FaceDetailerPipe",
- "pos": [
- 1890,
- 290
- ],
- "size": {
- "0": 343,
- "1": 658
- },
- "flags": {},
- "order": 16,
- "mode": 0,
- "inputs": [
- {
- "name": "image",
- "type": "IMAGE",
- "link": 39
- },
- {
- "name": "detailer_pipe",
- "type": "DETAILER_PIPE",
- "link": 36
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 43
- ],
- "slot_index": 0
- },
- {
- "name": "MASK",
- "type": "MASK",
- "links": [
- 44
- ],
- "slot_index": 1
- },
- {
- "name": "DETAILER_PIPE",
- "type": "DETAILER_PIPE",
- "links": null
- }
- ],
- "properties": {
- "Node name for S&R": "FaceDetailerPipe"
- },
- "widgets_values": [
- 320,
- "bbox",
- 659563220039187,
- "fixed",
- 20,
- 8,
- "euler",
- "karras",
- 0.5,
- 5,
- "enabled",
- "disabled",
- 0.5,
- 10,
- 4,
- "center-1",
- 5,
- 0.93,
- 0,
- 0.7,
- "False"
- ],
- "color": "#2a363b",
- "bgcolor": "#3f5159"
- }
- ],
- "links": [
- [
- 4,
- 4,
- 1,
- 5,
- 0,
- "CLIP"
- ],
- [
- 5,
- 4,
- 1,
- 6,
- 0,
- "CLIP"
- ],
- [
- 11,
- 10,
- 0,
- 9,
- 0,
- "*"
- ],
- [
- 12,
- 1,
- 0,
- 10,
- 0,
- "*"
- ],
- [
- 21,
- 12,
- 0,
- 13,
- 0,
- "*"
- ],
- [
- 22,
- 13,
- 0,
- 7,
- 0,
- "IMAGE"
- ],
- [
- 33,
- 17,
- 0,
- 18,
- 0,
- "IMAGE"
- ],
- [
- 36,
- 21,
- 0,
- 20,
- 1,
- "DETAILER_PIPE"
- ],
- [
- 38,
- 13,
- 0,
- 22,
- 0,
- "*"
- ],
- [
- 39,
- 22,
- 0,
- 20,
- 0,
- "IMAGE"
- ],
- [
- 42,
- 25,
- 0,
- 26,
- 0,
- "IMAGE"
- ],
- [
- 43,
- 20,
- 0,
- 24,
- 0,
- "IMAGE"
- ],
- [
- 44,
- 20,
- 1,
- 25,
- 0,
- "MASK"
- ],
- [
- 45,
- 9,
- 0,
- 27,
- 0,
- "IMAGE"
- ],
- [
- 46,
- 4,
- 0,
- 27,
- 1,
- "MODEL"
- ],
- [
- 47,
- 4,
- 2,
- 27,
- 2,
- "VAE"
- ],
- [
- 48,
- 5,
- 0,
- 27,
- 3,
- "CONDITIONING"
- ],
- [
- 49,
- 6,
- 0,
- 27,
- 4,
- "CONDITIONING"
- ],
- [
- 50,
- 15,
- 0,
- 27,
- 5,
- "BBOX_MODEL"
- ],
- [
- 52,
- 27,
- 0,
- 12,
- 0,
- "*"
- ],
- [
- 53,
- 27,
- 1,
- 17,
- 0,
- "MASK"
- ],
- [
- 54,
- 27,
- 2,
- 21,
- 0,
- "*"
- ],
- [
- 55,
- 16,
- 0,
- 27,
- 6,
- "SAM_MODEL"
- ]
- ],
- "groups": [],
- "config": {},
- "extra": {},
- "version": 0.4
-}
\ No newline at end of file
diff --git a/misc/2pass-simple.png b/misc/2pass-simple.png
deleted file mode 100644
index 480c141b..00000000
Binary files a/misc/2pass-simple.png and /dev/null differ
diff --git a/misc/advanced-simple.json b/misc/advanced-simple.json
deleted file mode 100644
index 78ec22f6..00000000
--- a/misc/advanced-simple.json
+++ /dev/null
@@ -1,658 +0,0 @@
-{
- "last_node_id": 77,
- "last_link_id": 179,
- "nodes": [
- {
- "id": 30,
- "type": "CheckpointLoader",
- "pos": [
- 50,
- 230
- ],
- "size": {
- "0": 289.5052795410156,
- "1": 122
- },
- "flags": {},
- "order": 0,
- "mode": 0,
- "outputs": [
- {
- "name": "MODEL",
- "type": "MODEL",
- "links": [
- 72,
- 153
- ],
- "slot_index": 0
- },
- {
- "name": "CLIP",
- "type": "CLIP",
- "links": [
- 49,
- 62
- ],
- "slot_index": 1
- },
- {
- "name": "VAE",
- "type": "VAE",
- "links": [
- 137,
- 156
- ],
- "slot_index": 2
- }
- ],
- "properties": {
- "Node name for S&R": "CheckpointLoader"
- },
- "widgets_values": [
- "anything_v3.yaml",
- "V07_v07.safetensors"
- ],
- "color": "#233",
- "bgcolor": "#355"
- },
- {
- "id": 67,
- "type": "BboxDetectorForEach",
- "pos": [
- 1440,
- 180
- ],
- "size": {
- "0": 290.3233947753906,
- "1": 126.13687896728516
- },
- "flags": {},
- "order": 8,
- "mode": 0,
- "inputs": [
- {
- "name": "bbox_model",
- "type": "BBOX_MODEL",
- "link": 179
- },
- {
- "name": "image",
- "type": "IMAGE",
- "link": 140
- }
- ],
- "outputs": [
- {
- "name": "SEGS",
- "type": "SEGS",
- "links": [
- 152
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "BboxDetectorForEach"
- },
- "widgets_values": [
- 0.5,
- 10,
- 4
- ],
- "color": "#232",
- "bgcolor": "#353"
- },
- {
- "id": 40,
- "type": "VAEDecode",
- "pos": [
- 570,
- 180
- ],
- "size": {
- "0": 311,
- "1": 46
- },
- "flags": {
- "collapsed": true
- },
- "order": 6,
- "mode": 0,
- "inputs": [
- {
- "name": "samples",
- "type": "LATENT",
- "link": 74
- },
- {
- "name": "vae",
- "type": "VAE",
- "link": 137
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 110,
- 140,
- 155
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "VAEDecode"
- },
- "color": "#322",
- "bgcolor": "#533"
- },
- {
- "id": 45,
- "type": "MMDetLoader",
- "pos": [
- 1030,
- 60
- ],
- "size": {
- "0": 361.56317138671875,
- "1": 93.23355865478516
- },
- "flags": {},
- "order": 1,
- "mode": 0,
- "outputs": [
- {
- "name": "BBOX_MODEL",
- "type": "BBOX_MODEL",
- "links": [
- 179
- ],
- "slot_index": 0
- },
- {
- "name": "SEGM_MODEL",
- "type": "SEGM_MODEL",
- "links": null
- }
- ],
- "properties": {
- "Node name for S&R": "MMDetLoader"
- },
- "widgets_values": [
- "bbox/mmdet_anime-face_yolov3.pth"
- ],
- "color": "#222",
- "bgcolor": "#000"
- },
- {
- "id": 71,
- "type": "SaveImage",
- "pos": [
- 1090,
- 360
- ],
- "size": {
- "0": 302.8558654785156,
- "1": 394.98974609375
- },
- "flags": {},
- "order": 10,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 161
- }
- ],
- "title": "Refined Image",
- "properties": {},
- "widgets_values": [
- "refined"
- ],
- "color": "#232",
- "bgcolor": "#353"
- },
- {
- "id": 42,
- "type": "KSampler",
- "pos": [
- 400,
- 410
- ],
- "size": {
- "0": 295.9467468261719,
- "1": 347.53521728515625
- },
- "flags": {},
- "order": 5,
- "mode": 0,
- "inputs": [
- {
- "name": "model",
- "type": "MODEL",
- "link": 72
- },
- {
- "name": "positive",
- "type": "CONDITIONING",
- "link": 70
- },
- {
- "name": "negative",
- "type": "CONDITIONING",
- "link": 71
- },
- {
- "name": "latent_image",
- "type": "LATENT",
- "link": 73
- }
- ],
- "outputs": [
- {
- "name": "LATENT",
- "type": "LATENT",
- "links": [
- 74
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "KSampler"
- },
- "widgets_values": [
- 805157917915455,
- "fixed",
- 20,
- 8,
- "euler",
- "karras",
- 1
- ],
- "color": "#322",
- "bgcolor": "#533"
- },
- {
- "id": 41,
- "type": "PreviewImage",
- "pos": [
- 760,
- 360
- ],
- "size": {
- "0": 297.5831298828125,
- "1": 395.7170104980469
- },
- "flags": {},
- "order": 7,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 110
- }
- ],
- "title": "Prompt Image",
- "properties": {
- "Node name for S&R": "PreviewImage"
- },
- "color": "#322",
- "bgcolor": "#533"
- },
- {
- "id": 44,
- "type": "EmptyLatentImage",
- "pos": [
- 400,
- 230
- ],
- "size": {
- "0": 297.0506896972656,
- "1": 124.40960693359375
- },
- "flags": {
- "collapsed": false
- },
- "order": 2,
- "mode": 0,
- "outputs": [
- {
- "name": "LATENT",
- "type": "LATENT",
- "links": [
- 73
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "EmptyLatentImage"
- },
- "widgets_values": [
- 256,
- 320,
- 1
- ],
- "color": "#322",
- "bgcolor": "#533"
- },
- {
- "id": 37,
- "type": "CLIPTextEncode",
- "pos": [
- 50,
- 620
- ],
- "size": [
- 288.77154541015625,
- 139.74398040771484
- ],
- "flags": {},
- "order": 4,
- "mode": 0,
- "inputs": [
- {
- "name": "clip",
- "type": "CLIP",
- "link": 62
- }
- ],
- "outputs": [
- {
- "name": "CONDITIONING",
- "type": "CONDITIONING",
- "links": [
- 71,
- 158,
- 160
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "CLIPTextEncode"
- },
- "widgets_values": [
- "low quality, worst quality, bad anatomy"
- ],
- "color": "#233",
- "bgcolor": "#355"
- },
- {
- "id": 31,
- "type": "CLIPTextEncode",
- "pos": [
- 50,
- 420
- ],
- "size": {
- "0": 290.0508117675781,
- "1": 136.4095916748047
- },
- "flags": {},
- "order": 3,
- "mode": 0,
- "inputs": [
- {
- "name": "clip",
- "type": "CLIP",
- "link": 49
- }
- ],
- "outputs": [
- {
- "name": "CONDITIONING",
- "type": "CONDITIONING",
- "links": [
- 70
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "CLIPTextEncode"
- },
- "widgets_values": [
- "1girl, photorealistic:1.4, masterpiece, holding book, full shot, black suit, perfect anatomy, office, detailed eyes, smile"
- ],
- "color": "#233",
- "bgcolor": "#355"
- },
- {
- "id": 70,
- "type": "DetailerForEach",
- "pos": [
- 1440,
- 360
- ],
- "size": {
- "0": 293.2631530761719,
- "1": 442
- },
- "flags": {},
- "order": 9,
- "mode": 0,
- "inputs": [
- {
- "name": "image",
- "type": "IMAGE",
- "link": 155
- },
- {
- "name": "segs",
- "type": "SEGS",
- "link": 152
- },
- {
- "name": "model",
- "type": "MODEL",
- "link": 153
- },
- {
- "name": "vae",
- "type": "VAE",
- "link": 156
- },
- {
- "name": "positive",
- "type": "CONDITIONING",
- "link": 158
- },
- {
- "name": "negative",
- "type": "CONDITIONING",
- "link": 160
- },
- {
- "name": "external_seed",
- "type": "SEED",
- "link": null
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 161
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "DetailerForEach"
- },
- "widgets_values": [
- 192,
- "bbox",
- true,
- "fixed",
- 20,
- 8,
- "euler",
- "karras",
- 0.4,
- 5,
- "enabled",
- "disabled"
- ],
- "color": "#232",
- "bgcolor": "#353"
- }
- ],
- "links": [
- [
- 49,
- 30,
- 1,
- 31,
- 0,
- "CLIP"
- ],
- [
- 62,
- 30,
- 1,
- 37,
- 0,
- "CLIP"
- ],
- [
- 70,
- 31,
- 0,
- 42,
- 1,
- "CONDITIONING"
- ],
- [
- 71,
- 37,
- 0,
- 42,
- 2,
- "CONDITIONING"
- ],
- [
- 72,
- 30,
- 0,
- 42,
- 0,
- "MODEL"
- ],
- [
- 73,
- 44,
- 0,
- 42,
- 3,
- "LATENT"
- ],
- [
- 74,
- 42,
- 0,
- 40,
- 0,
- "LATENT"
- ],
- [
- 110,
- 40,
- 0,
- 41,
- 0,
- "IMAGE"
- ],
- [
- 137,
- 30,
- 2,
- 40,
- 1,
- "VAE"
- ],
- [
- 140,
- 40,
- 0,
- 67,
- 1,
- "IMAGE"
- ],
- [
- 152,
- 67,
- 0,
- 70,
- 1,
- "SEGS"
- ],
- [
- 153,
- 30,
- 0,
- 70,
- 2,
- "MODEL"
- ],
- [
- 155,
- 40,
- 0,
- 70,
- 0,
- "IMAGE"
- ],
- [
- 156,
- 30,
- 2,
- 70,
- 3,
- "VAE"
- ],
- [
- 158,
- 37,
- 0,
- 70,
- 4,
- "CONDITIONING"
- ],
- [
- 160,
- 37,
- 0,
- 70,
- 5,
- "CONDITIONING"
- ],
- [
- 161,
- 70,
- 0,
- 71,
- 0,
- "IMAGE"
- ],
- [
- 179,
- 45,
- 0,
- 67,
- 0,
- "BBOX_MODEL"
- ]
- ],
- "groups": [],
- "config": {},
- "extra": {},
- "version": 0.4
-}
\ No newline at end of file
diff --git a/misc/combination-2pass-middle.png b/misc/combination-2pass-middle.png
deleted file mode 100644
index 57820046..00000000
Binary files a/misc/combination-2pass-middle.png and /dev/null differ
diff --git a/misc/combination-2pass-original.png b/misc/combination-2pass-original.png
deleted file mode 100644
index f8c2c2f1..00000000
Binary files a/misc/combination-2pass-original.png and /dev/null differ
diff --git a/misc/combination-2pass-result.png b/misc/combination-2pass-result.png
deleted file mode 100644
index a76d8605..00000000
Binary files a/misc/combination-2pass-result.png and /dev/null differ
diff --git a/misc/combination-2pass.json b/misc/combination-2pass.json
deleted file mode 100644
index 5f50674b..00000000
--- a/misc/combination-2pass.json
+++ /dev/null
@@ -1,2137 +0,0 @@
-{
- "last_node_id": 143,
- "last_link_id": 384,
- "nodes": [
- {
- "id": 109,
- "type": "CLIPTextEncode",
- "pos": [
- 359,
- 620
- ],
- "size": {
- "0": 382,
- "1": 204
- },
- "flags": {},
- "order": 7,
- "mode": 0,
- "inputs": [
- {
- "name": "clip",
- "type": "CLIP",
- "link": 303
- }
- ],
- "outputs": [
- {
- "name": "CONDITIONING",
- "type": "CONDITIONING",
- "links": [
- 264
- ],
- "slot_index": 0
- }
- ],
- "title": "Positive Prompt",
- "properties": {
- "Node name for S&R": "CLIPTextEncode"
- },
- "widgets_values": [
- "(black pantyhose:1.28), red high heels, footwear, 1girl, (open white trench coat:1.1), (white unbuttoned y-shirt:1.1), (micro short jean pants:1.1), choker, small earrings, (very short hair:1.1), (light white hair:1.1), side braid, swept bangs, rounded eyes, detailed-eyes, long eyelashes, swept bangs, side braid, beautiful eyes, shiny eyes, brown eyes, pink lips, glossy lips, parted lips, smile, (small breasts:1.05), thigh gap, short thigh, long calf, slender thigh, medium pelvis, (dynamic pose:1.22), (various poses:1.1), indoor, looking at viewer, (perfect face:1.1), (golden ratio face:1.1), a face of perfect proportion, perfect anatomy, perfect hands, (perfect fingers:1.1), (four fingers and one thumb:1.1), perfect body, golden ratio body, (detailed skin:1.1), healthy skin, realistic skin, smooth and radiant skin, (masterpiece:1.1), (best quality:1.1), (high quality:1.1), (highres:1.1), (distinct:1.1), (photorealistic:1.4), (realistic:1.4), real picture, intricate details, Hyper detail, Finely detailed, Extremely detail, physically based rendering, radiosity, photon mapping, (cinematic light:1.1), RAW, 8k, uhd, unity, ((from below)), full body, spread legs, looking side"
- ]
- },
- {
- "id": 103,
- "type": "Reroute",
- "pos": [
- 1201,
- 242
- ],
- "size": [
- 75,
- 26
- ],
- "flags": {},
- "order": 20,
- "mode": 0,
- "inputs": [
- {
- "name": "",
- "type": "*",
- "link": 239
- }
- ],
- "outputs": [
- {
- "name": "SEGS",
- "type": "SEGS",
- "links": [
- 246
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "showOutputText": true,
- "horizontal": false
- }
- },
- {
- "id": 118,
- "type": "PreviewImage",
- "pos": [
- 2260,
- 113
- ],
- "size": {
- "0": 227.76901245117188,
- "1": 252.140380859375
- },
- "flags": {},
- "order": 28,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 293
- }
- ],
- "title": "Enhanced",
- "properties": {
- "Node name for S&R": "PreviewImage"
- }
- },
- {
- "id": 117,
- "type": "PreviewImage",
- "pos": [
- 1967,
- 119
- ],
- "size": {
- "0": 210,
- "1": 250
- },
- "flags": {},
- "order": 27,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 292
- }
- ],
- "title": "Cropped",
- "properties": {
- "Node name for S&R": "PreviewImage"
- }
- },
- {
- "id": 120,
- "type": "Reroute",
- "pos": [
- 416,
- -140
- ],
- "size": [
- 82,
- 26
- ],
- "flags": {},
- "order": 4,
- "mode": 0,
- "inputs": [
- {
- "name": "",
- "type": "*",
- "link": 327
- }
- ],
- "outputs": [
- {
- "name": "MODEL",
- "type": "MODEL",
- "links": [
- 315,
- 330
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "showOutputText": true,
- "horizontal": false
- }
- },
- {
- "id": 121,
- "type": "Reroute",
- "pos": [
- 419,
- -75
- ],
- "size": [
- 75,
- 26
- ],
- "flags": {},
- "order": 5,
- "mode": 0,
- "inputs": [
- {
- "name": "",
- "type": "*",
- "link": 333
- }
- ],
- "outputs": [
- {
- "name": "CLIP",
- "type": "CLIP",
- "links": [
- 303,
- 304,
- 328
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "showOutputText": true,
- "horizontal": false
- }
- },
- {
- "id": 82,
- "type": "MMDetLoader",
- "pos": [
- 712.5367020996093,
- 135.30448647521965
- ],
- "size": {
- "0": 374.412109375,
- "1": 93.55003356933594
- },
- "flags": {},
- "order": 0,
- "mode": 0,
- "outputs": [
- {
- "name": "BBOX_MODEL",
- "type": "BBOX_MODEL",
- "links": [
- 204,
- 362
- ],
- "slot_index": 0
- },
- {
- "name": "SEGM_MODEL",
- "type": "SEGM_MODEL",
- "links": [],
- "slot_index": 1
- }
- ],
- "properties": {
- "Node name for S&R": "MMDetLoader"
- },
- "widgets_values": [
- "bbox/mmdet_anime-face_yolov3.pth"
- ],
- "color": "#432",
- "bgcolor": "#653"
- },
- {
- "id": 87,
- "type": "SAMLoader",
- "pos": [
- 1109.9366837890623,
- 134.3044807531738
- ],
- "size": {
- "0": 327.3000183105469,
- "1": 96.49998474121094
- },
- "flags": {},
- "order": 1,
- "mode": 0,
- "outputs": [
- {
- "name": "SAM_MODEL",
- "type": "SAM_MODEL",
- "links": [
- 336,
- 364
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "SAMLoader"
- },
- "widgets_values": [
- "sam_vit_b_01ec64.pth"
- ],
- "color": "#232",
- "bgcolor": "#353"
- },
- {
- "id": 119,
- "type": "LoraLoader",
- "pos": [
- 1483,
- 39
- ],
- "size": {
- "0": 408.50341796875,
- "1": 126
- },
- "flags": {},
- "order": 12,
- "mode": 0,
- "inputs": [
- {
- "name": "model",
- "type": "MODEL",
- "link": 329
- },
- {
- "name": "clip",
- "type": "CLIP",
- "link": 331
- }
- ],
- "outputs": [
- {
- "name": "MODEL",
- "type": "MODEL",
- "links": [],
- "slot_index": 0
- },
- {
- "name": "CLIP",
- "type": "CLIP",
- "links": [],
- "slot_index": 1
- }
- ],
- "properties": {
- "Node name for S&R": "LoraLoader"
- },
- "widgets_values": [
- "koreanDollLikeness_v10.safetensors",
- 1,
- 1
- ]
- },
- {
- "id": 133,
- "type": "Reroute",
- "pos": [
- 1935,
- 1298
- ],
- "size": [
- 82,
- 26
- ],
- "flags": {},
- "order": 26,
- "mode": 0,
- "inputs": [
- {
- "name": "",
- "type": "*",
- "link": 359,
- "pos": [
- 41,
- 0
- ]
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 360,
- 361,
- 368
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "showOutputText": true,
- "horizontal": true
- }
- },
- {
- "id": 134,
- "type": "Segs & Mask",
- "pos": [
- 1870,
- 1470
- ],
- "size": {
- "0": 210,
- "1": 46
- },
- "flags": {},
- "order": 34,
- "mode": 0,
- "inputs": [
- {
- "name": "segs",
- "type": "SEGS",
- "link": 366
- },
- {
- "name": "mask",
- "type": "MASK",
- "link": 365
- }
- ],
- "outputs": [
- {
- "name": "SEGS",
- "type": "SEGS",
- "links": [
- 367
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "Segs & Mask"
- },
- "color": "#323",
- "bgcolor": "#535"
- },
- {
- "id": 130,
- "type": "Reroute",
- "pos": [
- 2112,
- 29
- ],
- "size": [
- 75,
- 26
- ],
- "flags": {},
- "order": 13,
- "mode": 0,
- "inputs": [
- {
- "name": "",
- "type": "*",
- "link": 356
- }
- ],
- "outputs": [
- {
- "name": "CLIP",
- "type": "CLIP",
- "links": [
- 357,
- 376
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "showOutputText": true,
- "horizontal": false
- }
- },
- {
- "id": 125,
- "type": "Reroute",
- "pos": [
- 2109,
- -52
- ],
- "size": [
- 82,
- 26
- ],
- "flags": {},
- "order": 11,
- "mode": 0,
- "inputs": [
- {
- "name": "",
- "type": "*",
- "link": 355
- }
- ],
- "outputs": [
- {
- "name": "MODEL",
- "type": "MODEL",
- "links": [
- 348,
- 369
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "showOutputText": true,
- "horizontal": false
- }
- },
- {
- "id": 107,
- "type": "SaveImage",
- "pos": [
- 753,
- 620
- ],
- "size": {
- "0": 700.088623046875,
- "1": 588.4502563476562
- },
- "flags": {},
- "order": 17,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 273
- }
- ],
- "title": "Prompt",
- "properties": {},
- "widgets_values": [
- "original"
- ]
- },
- {
- "id": 108,
- "type": "VAEDecode",
- "pos": [
- 361,
- 1155
- ],
- "size": {
- "0": 381.7952880859375,
- "1": 46.58692932128906
- },
- "flags": {},
- "order": 14,
- "mode": 0,
- "inputs": [
- {
- "name": "samples",
- "type": "LATENT",
- "link": 272
- },
- {
- "name": "vae",
- "type": "VAE",
- "link": 267
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 273,
- 274,
- 346
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "VAEDecode"
- }
- },
- {
- "id": 110,
- "type": "CLIPTextEncode",
- "pos": [
- 359,
- 881
- ],
- "size": {
- "0": 381.7952880859375,
- "1": 213.58692932128906
- },
- "flags": {},
- "order": 8,
- "mode": 0,
- "inputs": [
- {
- "name": "clip",
- "type": "CLIP",
- "link": 304
- }
- ],
- "outputs": [
- {
- "name": "CONDITIONING",
- "type": "CONDITIONING",
- "links": [
- 265,
- 351,
- 371
- ],
- "slot_index": 0
- }
- ],
- "title": "Negative Prompt",
- "properties": {
- "Node name for S&R": "CLIPTextEncode"
- },
- "widgets_values": [
- "nsfw, (worst quality:1.4), (low quality:1.4), (blurry:1.22), (greyscale:1.1), (monochrome:1.1), cropped, lowres, text, jpeg artifacts, signature, watermark, username, blurry, artist name, trademark, title, (tan:1.1), muscular, petite, infant, toddlers, (sd character:1.1), Reference sheet, bad_prompt, comic, lowres low resolution, (bad anatomy:1.1), low quality anatomy, (bad hands:1.22), bad nails, bad legs, (bad fingers:1.22), bad toes, extra digit, (extra hands:1.22), (extra fingers:1.22), extra arms, extra legs, fewer digit, low quality face, low quality eyes, (cropped hands:1.22), cropped legs, cropped arms, (cropped fingers:1.22), (fused fingers:1.22), (too many fingers:1.22), tattoo, (missing fingers:1.22), ugly, text, (thai:1.1), thai girl, thai style, thai face, thai makeup), (american girl:1.1), american, american style, american face, american makeup), (chinese girl:1.1), chinese, chinese style, chinese face, chinese makeup), more than one person in focus, (more than two arm per body:1.48), (more than two leg per body:1.41), (more than five fingers on one hand:1.41), multi arms, multi legs, bad arm anatomy, bad leg anatomy, (bad hand anatomy:1.1), (bad finger anatomy:1.1), bad detailed background, unclear architectural outline, elf-ears, obesity, fat, (mutated hands and fingers:1.1), disfigured, fused, cloned, duplicate, flag, mole, strabismus, (highleg panties:1.1), hat, fishnet, (no pants), topless, bottomless, low-cut_armhole, high-waist_sideboob, sideless_outfit, breast_slip, cleavage_cutout, center_opening, breastless_clothes, sideboob, backboob, underboob, underboob_cutout, nipple_slip, areola_slip, revealing_clothes, see-through clothes, crotch_cutout, hip_vent, ass_cutout, side_slit, zettai_ryouiki, butt_crack, naked, nude, clothes_grab, untying, open_clothes, untied, undressing, unzipped, clothes_down, bikini, pink hair, letters, characters, wing, sunglasses, nipple"
- ]
- },
- {
- "id": 112,
- "type": "EmptyLatentImage",
- "pos": [
- 23,
- 1095
- ],
- "size": {
- "0": 315,
- "1": 106
- },
- "flags": {},
- "order": 2,
- "mode": 0,
- "outputs": [
- {
- "name": "LATENT",
- "type": "LATENT",
- "links": [
- 266
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "EmptyLatentImage"
- },
- "widgets_values": [
- 512,
- 832,
- 1
- ]
- },
- {
- "id": 111,
- "type": "KSampler",
- "pos": [
- 21,
- 771
- ],
- "size": {
- "0": 315,
- "1": 262
- },
- "flags": {},
- "order": 10,
- "mode": 0,
- "inputs": [
- {
- "name": "model",
- "type": "MODEL",
- "link": 315
- },
- {
- "name": "positive",
- "type": "CONDITIONING",
- "link": 264
- },
- {
- "name": "negative",
- "type": "CONDITIONING",
- "link": 265
- },
- {
- "name": "latent_image",
- "type": "LATENT",
- "link": 266
- }
- ],
- "outputs": [
- {
- "name": "LATENT",
- "type": "LATENT",
- "links": [
- 272
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "KSampler"
- },
- "widgets_values": [
- 762773680021613,
- false,
- 30,
- 7,
- "euler",
- "karras",
- 1
- ]
- },
- {
- "id": 136,
- "type": "SaveImage",
- "pos": [
- 756,
- 1341
- ],
- "size": {
- "0": 702.1994018554688,
- "1": 706.2926025390625
- },
- "flags": {},
- "order": 36,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 372
- }
- ],
- "title": "Refine - 2pass",
- "properties": {},
- "widgets_values": [
- "refined-2pass"
- ]
- },
- {
- "id": 124,
- "type": "CLIPTextEncode",
- "pos": [
- 2232,
- 592
- ],
- "size": {
- "0": 313.7494201660156,
- "1": 156.86895751953125
- },
- "flags": {},
- "order": 15,
- "mode": 0,
- "inputs": [
- {
- "name": "clip",
- "type": "CLIP",
- "link": 357
- }
- ],
- "outputs": [
- {
- "name": "CONDITIONING",
- "type": "CONDITIONING",
- "links": [
- 374
- ],
- "slot_index": 0
- }
- ],
- "title": "Face Prompt",
- "properties": {
- "Node name for S&R": "CLIPTextEncode"
- },
- "widgets_values": [
- "adorable face, widening eyes, disgust, closeup portrait, looking away, detailed eyes"
- ]
- },
- {
- "id": 115,
- "type": "SaveImage",
- "pos": [
- 1498,
- 594
- ],
- "size": {
- "0": 710.8572998046875,
- "1": 629.0338134765625
- },
- "flags": {},
- "order": 25,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 352
- }
- ],
- "title": "Refined",
- "properties": {},
- "widgets_values": [
- "refined"
- ]
- },
- {
- "id": 126,
- "type": "LoraLoader",
- "pos": [
- 898,
- -129
- ],
- "size": {
- "0": 410.2594299316406,
- "1": 126
- },
- "flags": {},
- "order": 9,
- "mode": 0,
- "inputs": [
- {
- "name": "model",
- "type": "MODEL",
- "link": 330
- },
- {
- "name": "clip",
- "type": "CLIP",
- "link": 328
- }
- ],
- "outputs": [
- {
- "name": "MODEL",
- "type": "MODEL",
- "links": [
- 329,
- 355
- ],
- "slot_index": 0
- },
- {
- "name": "CLIP",
- "type": "CLIP",
- "links": [
- 331,
- 356
- ],
- "slot_index": 1
- }
- ],
- "properties": {
- "Node name for S&R": "LoraLoader"
- },
- "widgets_values": [
- "emotionPuppeteerLora_v2Lora.safetensors",
- 1,
- 1
- ]
- },
- {
- "id": 105,
- "type": "CheckpointLoaderSimple",
- "pos": [
- 7,
- 38
- ],
- "size": {
- "0": 315,
- "1": 98
- },
- "flags": {},
- "order": 3,
- "mode": 0,
- "outputs": [
- {
- "name": "MODEL",
- "type": "MODEL",
- "links": [
- 327
- ],
- "slot_index": 0
- },
- {
- "name": "CLIP",
- "type": "CLIP",
- "links": [
- 333
- ],
- "slot_index": 1
- },
- {
- "name": "VAE",
- "type": "VAE",
- "links": [
- 252,
- 267
- ],
- "slot_index": 2
- }
- ],
- "properties": {
- "Node name for S&R": "CheckpointLoaderSimple"
- },
- "widgets_values": [
- "V07_v07.safetensors"
- ]
- },
- {
- "id": 138,
- "type": "CLIPTextEncode",
- "pos": [
- 1502,
- 1806
- ],
- "size": {
- "0": 954.989501953125,
- "1": 243.09625244140625
- },
- "flags": {},
- "order": 16,
- "mode": 0,
- "inputs": [
- {
- "name": "clip",
- "type": "CLIP",
- "link": 376
- }
- ],
- "outputs": [
- {
- "name": "CONDITIONING",
- "type": "CONDITIONING",
- "links": [
- 375
- ],
- "slot_index": 0
- }
- ],
- "title": "Face Prompt",
- "properties": {
- "Node name for S&R": "CLIPTextEncode"
- },
- "widgets_values": [
- "adorable face, widening eyes, disgust, closeup portrait, looking away, detailed eyes"
- ]
- },
- {
- "id": 131,
- "type": "SAMDetectorCombined",
- "pos": [
- 2192,
- 1353
- ],
- "size": {
- "0": 259.5433349609375,
- "1": 148.83053588867188
- },
- "flags": {},
- "order": 32,
- "mode": 0,
- "inputs": [
- {
- "name": "sam_model",
- "type": "SAM_MODEL",
- "link": 364
- },
- {
- "name": "segs",
- "type": "SEGS",
- "link": 363
- },
- {
- "name": "image",
- "type": "IMAGE",
- "link": 360
- }
- ],
- "outputs": [
- {
- "name": "MASK",
- "type": "MASK",
- "links": [
- 365
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "SAMDetectorCombined"
- },
- "widgets_values": [
- "horizontal-2",
- 0.93,
- 0.93
- ],
- "color": "#232",
- "bgcolor": "#353"
- },
- {
- "id": 104,
- "type": "Segs & Mask",
- "pos": [
- 1529.9366837890627,
- 285.3044807531738
- ],
- "size": {
- "0": 210,
- "1": 46
- },
- "flags": {},
- "order": 22,
- "mode": 0,
- "inputs": [
- {
- "name": "segs",
- "type": "SEGS",
- "link": 246
- },
- {
- "name": "mask",
- "type": "MASK",
- "link": 337
- }
- ],
- "outputs": [
- {
- "name": "SEGS",
- "type": "SEGS",
- "links": [
- 347,
- 377
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "Segs & Mask"
- },
- "color": "#323",
- "bgcolor": "#535"
- },
- {
- "id": 94,
- "type": "Reroute",
- "pos": [
- 559,
- 445
- ],
- "size": [
- 82,
- 26
- ],
- "flags": {},
- "order": 18,
- "mode": 0,
- "inputs": [
- {
- "name": "",
- "type": "*",
- "link": 274
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 218,
- 335,
- 378,
- 381
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "showOutputText": true,
- "horizontal": false
- }
- },
- {
- "id": 106,
- "type": "Reroute",
- "pos": [
- 2110,
- -129
- ],
- "size": [
- 75,
- 26
- ],
- "flags": {},
- "order": 6,
- "mode": 0,
- "inputs": [
- {
- "name": "",
- "type": "*",
- "link": 252
- }
- ],
- "outputs": [
- {
- "name": "VAE",
- "type": "VAE",
- "links": [
- 349,
- 370,
- 380,
- 383
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "showOutputText": true,
- "horizontal": false
- }
- },
- {
- "id": 127,
- "type": "SAMDetectorCombined",
- "pos": [
- 1112,
- 306
- ],
- "size": {
- "0": 243.7554168701172,
- "1": 146
- },
- "flags": {},
- "order": 21,
- "mode": 0,
- "inputs": [
- {
- "name": "sam_model",
- "type": "SAM_MODEL",
- "link": 336
- },
- {
- "name": "segs",
- "type": "SEGS",
- "link": 334
- },
- {
- "name": "image",
- "type": "IMAGE",
- "link": 335
- }
- ],
- "outputs": [
- {
- "name": "MASK",
- "type": "MASK",
- "links": [
- 337
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "SAMDetectorCombined"
- },
- "widgets_values": [
- "horizontal-2",
- 1,
- 0.93
- ],
- "color": "#232",
- "bgcolor": "#353"
- },
- {
- "id": 90,
- "type": "BboxDetectorForEach",
- "pos": [
- 716,
- 313
- ],
- "size": {
- "0": 260.3999938964844,
- "1": 126
- },
- "flags": {},
- "order": 19,
- "mode": 0,
- "inputs": [
- {
- "name": "bbox_model",
- "type": "BBOX_MODEL",
- "link": 204
- },
- {
- "name": "image",
- "type": "IMAGE",
- "link": 218
- }
- ],
- "outputs": [
- {
- "name": "SEGS",
- "type": "SEGS",
- "links": [
- 239,
- 334
- ],
- "slot_index": 0
- }
- ],
- "title": "BboxDetectorFE !! DON'T MUTE !!",
- "properties": {
- "Node name for S&R": "BboxDetectorForEach"
- },
- "widgets_values": [
- 0.5,
- 10,
- 3.9999999999999996
- ],
- "color": "#432",
- "bgcolor": "#653"
- },
- {
- "id": 143,
- "type": "PreviewImage",
- "pos": [
- 2820,
- -943
- ],
- "size": [
- 562,
- 699
- ],
- "flags": {},
- "order": 33,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 384
- }
- ],
- "properties": {
- "Node name for S&R": "PreviewImage"
- },
- "color": "#2a363b",
- "bgcolor": "#3f5159"
- },
- {
- "id": 142,
- "type": "VAEDecode",
- "pos": [
- 2447,
- -941
- ],
- "size": {
- "0": 210,
- "1": 46
- },
- "flags": {},
- "order": 31,
- "mode": 0,
- "inputs": [
- {
- "name": "samples",
- "type": "LATENT",
- "link": 382
- },
- {
- "name": "vae",
- "type": "VAE",
- "link": 383
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 384
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "VAEDecode"
- },
- "color": "#2a363b",
- "bgcolor": "#3f5159"
- },
- {
- "id": 141,
- "type": "VAEEncodeForInpaint",
- "pos": [
- 2142,
- -939
- ],
- "size": {
- "0": 210,
- "1": 66
- },
- "flags": {},
- "order": 29,
- "mode": 0,
- "inputs": [
- {
- "name": "pixels",
- "type": "IMAGE",
- "link": 381
- },
- {
- "name": "vae",
- "type": "VAE",
- "link": 380
- },
- {
- "name": "mask",
- "type": "MASK",
- "link": 379
- }
- ],
- "outputs": [
- {
- "name": "LATENT",
- "type": "LATENT",
- "links": [
- 382
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "VAEEncodeForInpaint"
- },
- "color": "#2a363b",
- "bgcolor": "#3f5159"
- },
- {
- "id": 140,
- "type": "SegsMaskCombine",
- "pos": [
- 1761,
- -898
- ],
- "size": {
- "0": 210,
- "1": 46
- },
- "flags": {},
- "order": 24,
- "mode": 0,
- "inputs": [
- {
- "name": "segs",
- "type": "SEGS",
- "link": 377
- },
- {
- "name": "image",
- "type": "IMAGE",
- "link": 378
- }
- ],
- "outputs": [
- {
- "name": "MASK",
- "type": "MASK",
- "links": [
- 379
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "SegsMaskCombine"
- },
- "color": "#2a363b",
- "bgcolor": "#3f5159"
- },
- {
- "id": 135,
- "type": "DetailerForEach",
- "pos": [
- 1499,
- 1343
- ],
- "size": {
- "0": 315,
- "1": 418
- },
- "flags": {},
- "order": 35,
- "mode": 0,
- "inputs": [
- {
- "name": "image",
- "type": "IMAGE",
- "link": 368
- },
- {
- "name": "segs",
- "type": "SEGS",
- "link": 367
- },
- {
- "name": "model",
- "type": "MODEL",
- "link": 369
- },
- {
- "name": "vae",
- "type": "VAE",
- "link": 370
- },
- {
- "name": "positive",
- "type": "CONDITIONING",
- "link": 375,
- "slot_index": 4
- },
- {
- "name": "negative",
- "type": "CONDITIONING",
- "link": 371,
- "slot_index": 5
- },
- {
- "name": "external_seed",
- "type": "SEED",
- "link": null
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 372
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "DetailerForEach"
- },
- "widgets_values": [
- 320,
- "bbox",
- 557701735627255,
- "fixed",
- 20,
- 10,
- "euler",
- "karras",
- 0.5,
- 5,
- "disabled"
- ]
- },
- {
- "id": 116,
- "type": "DetailerForEachDebug",
- "pos": [
- 2235,
- 800
- ],
- "size": {
- "0": 315,
- "1": 418
- },
- "flags": {},
- "order": 23,
- "mode": 0,
- "inputs": [
- {
- "name": "image",
- "type": "IMAGE",
- "link": 346
- },
- {
- "name": "segs",
- "type": "SEGS",
- "link": 347
- },
- {
- "name": "model",
- "type": "MODEL",
- "link": 348
- },
- {
- "name": "vae",
- "type": "VAE",
- "link": 349
- },
- {
- "name": "positive",
- "type": "CONDITIONING",
- "link": 374
- },
- {
- "name": "negative",
- "type": "CONDITIONING",
- "link": 351
- },
- {
- "name": "external_seed",
- "type": "SEED",
- "link": null
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 352,
- 359
- ],
- "slot_index": 0
- },
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 292
- ],
- "slot_index": 1
- },
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 293
- ],
- "slot_index": 2
- }
- ],
- "properties": {
- "Node name for S&R": "DetailerForEachDebug"
- },
- "widgets_values": [
- 256,
- "bbox",
- 525638383782973,
- "fixed",
- 10,
- 7,
- "euler",
- "karras",
- 0.6,
- 5,
- "disabled"
- ]
- },
- {
- "id": 132,
- "type": "BboxDetectorForEach",
- "pos": [
- 2195,
- 1554
- ],
- "size": {
- "0": 260.3999938964844,
- "1": 126
- },
- "flags": {},
- "order": 30,
- "mode": 0,
- "inputs": [
- {
- "name": "bbox_model",
- "type": "BBOX_MODEL",
- "link": 362
- },
- {
- "name": "image",
- "type": "IMAGE",
- "link": 361
- }
- ],
- "outputs": [
- {
- "name": "SEGS",
- "type": "SEGS",
- "links": [
- 363,
- 366
- ],
- "slot_index": 0
- }
- ],
- "title": "BboxDetectorFE !! DON'T MUTE !!",
- "properties": {
- "Node name for S&R": "BboxDetectorForEach"
- },
- "widgets_values": [
- 0.5,
- 20,
- 3.9999999999999996
- ],
- "color": "#432",
- "bgcolor": "#653"
- }
- ],
- "links": [
- [
- 204,
- 82,
- 0,
- 90,
- 0,
- "BBOX_MODEL"
- ],
- [
- 218,
- 94,
- 0,
- 90,
- 1,
- "IMAGE"
- ],
- [
- 239,
- 90,
- 0,
- 103,
- 0,
- "*"
- ],
- [
- 246,
- 103,
- 0,
- 104,
- 0,
- "SEGS"
- ],
- [
- 252,
- 105,
- 2,
- 106,
- 0,
- "*"
- ],
- [
- 264,
- 109,
- 0,
- 111,
- 1,
- "CONDITIONING"
- ],
- [
- 265,
- 110,
- 0,
- 111,
- 2,
- "CONDITIONING"
- ],
- [
- 266,
- 112,
- 0,
- 111,
- 3,
- "LATENT"
- ],
- [
- 267,
- 105,
- 2,
- 108,
- 1,
- "VAE"
- ],
- [
- 272,
- 111,
- 0,
- 108,
- 0,
- "LATENT"
- ],
- [
- 273,
- 108,
- 0,
- 107,
- 0,
- "IMAGE"
- ],
- [
- 274,
- 108,
- 0,
- 94,
- 0,
- "*"
- ],
- [
- 292,
- 116,
- 1,
- 117,
- 0,
- "IMAGE"
- ],
- [
- 293,
- 116,
- 2,
- 118,
- 0,
- "IMAGE"
- ],
- [
- 303,
- 121,
- 0,
- 109,
- 0,
- "CLIP"
- ],
- [
- 304,
- 121,
- 0,
- 110,
- 0,
- "CLIP"
- ],
- [
- 315,
- 120,
- 0,
- 111,
- 0,
- "MODEL"
- ],
- [
- 327,
- 105,
- 0,
- 120,
- 0,
- "*"
- ],
- [
- 328,
- 121,
- 0,
- 126,
- 1,
- "CLIP"
- ],
- [
- 329,
- 126,
- 0,
- 119,
- 0,
- "MODEL"
- ],
- [
- 330,
- 120,
- 0,
- 126,
- 0,
- "MODEL"
- ],
- [
- 331,
- 126,
- 1,
- 119,
- 1,
- "CLIP"
- ],
- [
- 333,
- 105,
- 1,
- 121,
- 0,
- "*"
- ],
- [
- 334,
- 90,
- 0,
- 127,
- 1,
- "SEGS"
- ],
- [
- 335,
- 94,
- 0,
- 127,
- 2,
- "IMAGE"
- ],
- [
- 336,
- 87,
- 0,
- 127,
- 0,
- "SAM_MODEL"
- ],
- [
- 337,
- 127,
- 0,
- 104,
- 1,
- "MASK"
- ],
- [
- 346,
- 108,
- 0,
- 116,
- 0,
- "IMAGE"
- ],
- [
- 347,
- 104,
- 0,
- 116,
- 1,
- "SEGS"
- ],
- [
- 348,
- 125,
- 0,
- 116,
- 2,
- "MODEL"
- ],
- [
- 349,
- 106,
- 0,
- 116,
- 3,
- "VAE"
- ],
- [
- 351,
- 110,
- 0,
- 116,
- 5,
- "CONDITIONING"
- ],
- [
- 352,
- 116,
- 0,
- 115,
- 0,
- "IMAGE"
- ],
- [
- 355,
- 126,
- 0,
- 125,
- 0,
- "*"
- ],
- [
- 356,
- 126,
- 1,
- 130,
- 0,
- "*"
- ],
- [
- 357,
- 130,
- 0,
- 124,
- 0,
- "CLIP"
- ],
- [
- 359,
- 116,
- 0,
- 133,
- 0,
- "*"
- ],
- [
- 360,
- 133,
- 0,
- 131,
- 2,
- "IMAGE"
- ],
- [
- 361,
- 133,
- 0,
- 132,
- 1,
- "IMAGE"
- ],
- [
- 362,
- 82,
- 0,
- 132,
- 0,
- "BBOX_MODEL"
- ],
- [
- 363,
- 132,
- 0,
- 131,
- 1,
- "SEGS"
- ],
- [
- 364,
- 87,
- 0,
- 131,
- 0,
- "SAM_MODEL"
- ],
- [
- 365,
- 131,
- 0,
- 134,
- 1,
- "MASK"
- ],
- [
- 366,
- 132,
- 0,
- 134,
- 0,
- "SEGS"
- ],
- [
- 367,
- 134,
- 0,
- 135,
- 1,
- "SEGS"
- ],
- [
- 368,
- 133,
- 0,
- 135,
- 0,
- "IMAGE"
- ],
- [
- 369,
- 125,
- 0,
- 135,
- 2,
- "MODEL"
- ],
- [
- 370,
- 106,
- 0,
- 135,
- 3,
- "VAE"
- ],
- [
- 371,
- 110,
- 0,
- 135,
- 5,
- "CONDITIONING"
- ],
- [
- 372,
- 135,
- 0,
- 136,
- 0,
- "IMAGE"
- ],
- [
- 374,
- 124,
- 0,
- 116,
- 4,
- "CONDITIONING"
- ],
- [
- 375,
- 138,
- 0,
- 135,
- 4,
- "CONDITIONING"
- ],
- [
- 376,
- 130,
- 0,
- 138,
- 0,
- "CLIP"
- ],
- [
- 377,
- 104,
- 0,
- 140,
- 0,
- "SEGS"
- ],
- [
- 378,
- 94,
- 0,
- 140,
- 1,
- "IMAGE"
- ],
- [
- 379,
- 140,
- 0,
- 141,
- 2,
- "MASK"
- ],
- [
- 380,
- 106,
- 0,
- 141,
- 1,
- "VAE"
- ],
- [
- 381,
- 94,
- 0,
- 141,
- 0,
- "IMAGE"
- ],
- [
- 382,
- 141,
- 0,
- 142,
- 0,
- "LATENT"
- ],
- [
- 383,
- 106,
- 0,
- 142,
- 1,
- "VAE"
- ],
- [
- 384,
- 142,
- 0,
- 143,
- 0,
- "IMAGE"
- ]
- ],
- "groups": [
- {
- "title": "Detection & Mask Generation",
- "bounding": [
- 664,
- 13,
- 1190,
- 447
- ],
- "color": "#3f789e"
- },
- {
- "title": "Group",
- "bounding": [
- 11,
- 496,
- 1462,
- 753
- ],
- "color": "#3f789e"
- },
- {
- "title": "Refine and Render (Fast Repair)",
- "bounding": [
- 1479,
- 495,
- 1088,
- 753
- ],
- "color": "#3f789e"
- },
- {
- "title": "Detailer Preview",
- "bounding": [
- 1905,
- -4,
- 659,
- 462
- ],
- "color": "#a1309b"
- },
- {
- "title": "2nd Refine (Detailer)",
- "bounding": [
- 732,
- 1265,
- 1832,
- 803
- ],
- "color": "#3f789e"
- },
- {
- "title": "Mask Preview",
- "bounding": [
- 1698,
- -1104,
- 1745,
- 909
- ],
- "color": "#a1309b"
- }
- ],
- "config": {},
- "extra": {},
- "version": 0.4
-}
\ No newline at end of file
diff --git a/misc/combination-original.png b/misc/combination-original.png
deleted file mode 100644
index a2f5e91f..00000000
Binary files a/misc/combination-original.png and /dev/null differ
diff --git a/misc/combination-refined.png b/misc/combination-refined.png
deleted file mode 100644
index e70ec3a3..00000000
Binary files a/misc/combination-refined.png and /dev/null differ
diff --git a/misc/combination.json b/misc/combination.json
deleted file mode 100644
index 67db4564..00000000
--- a/misc/combination.json
+++ /dev/null
@@ -1,968 +0,0 @@
-{
- "last_node_id": 115,
- "last_link_id": 282,
- "nodes": [
- {
- "id": 82,
- "type": "MMDetLoader",
- "pos": [
- 712.5367020996093,
- 135.30448647521965
- ],
- "size": {
- "0": 374.412109375,
- "1": 93.55003356933594
- },
- "flags": {},
- "order": 0,
- "mode": 0,
- "outputs": [
- {
- "name": "BBOX_MODEL",
- "type": "BBOX_MODEL",
- "links": [
- 204
- ],
- "slot_index": 0
- },
- {
- "name": "SEGM_MODEL",
- "type": "SEGM_MODEL",
- "links": [],
- "slot_index": 1
- }
- ],
- "properties": {
- "Node name for S&R": "MMDetLoader"
- },
- "widgets_values": [
- "bbox/mmdet_anime-face_yolov3.pth"
- ],
- "color": "#432",
- "bgcolor": "#653"
- },
- {
- "id": 87,
- "type": "SAMLoader",
- "pos": [
- 1109.9366837890623,
- 134.3044807531738
- ],
- "size": {
- "0": 327.3000183105469,
- "1": 96.49998474121094
- },
- "flags": {},
- "order": 1,
- "mode": 0,
- "outputs": [
- {
- "name": "SAM_MODEL",
- "type": "SAM_MODEL",
- "links": [
- 282
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "SAMLoader"
- },
- "widgets_values": [
- "sam_vit_b_01ec64.pth"
- ],
- "color": "#232",
- "bgcolor": "#353"
- },
- {
- "id": 94,
- "type": "Reroute",
- "pos": [
- 62,
- 456
- ],
- "size": [
- 82,
- 26
- ],
- "flags": {},
- "order": 10,
- "mode": 0,
- "inputs": [
- {
- "name": "",
- "type": "*",
- "link": 274
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 218,
- 219
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "showOutputText": true,
- "horizontal": false
- }
- },
- {
- "id": 103,
- "type": "Reroute",
- "pos": [
- 1409.5367020996096,
- 263.3044864752197
- ],
- "size": [
- 75,
- 26
- ],
- "flags": {},
- "order": 13,
- "mode": 0,
- "inputs": [
- {
- "name": "",
- "type": "*",
- "link": 239
- }
- ],
- "outputs": [
- {
- "name": "SEGS",
- "type": "SEGS",
- "links": [
- 246
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "showOutputText": true,
- "horizontal": false
- }
- },
- {
- "id": 104,
- "type": "Segs & Mask",
- "pos": [
- 1529.9366837890627,
- 285.3044807531738
- ],
- "size": {
- "0": 210,
- "1": 46
- },
- "flags": {},
- "order": 14,
- "mode": 0,
- "inputs": [
- {
- "name": "segs",
- "type": "SEGS",
- "link": 246
- },
- {
- "name": "mask",
- "type": "MASK",
- "link": 247
- }
- ],
- "outputs": [
- {
- "name": "SEGS",
- "type": "SEGS",
- "links": [
- 275
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "Segs & Mask"
- },
- "color": "#323",
- "bgcolor": "#535"
- },
- {
- "id": 106,
- "type": "Reroute",
- "pos": [
- 872.6135858068355,
- 491.7605277234375
- ],
- "size": [
- 75,
- 26
- ],
- "flags": {},
- "order": 6,
- "mode": 0,
- "inputs": [
- {
- "name": "",
- "type": "*",
- "link": 252
- }
- ],
- "outputs": [
- {
- "name": "VAE",
- "type": "VAE",
- "links": [
- 278
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "showOutputText": true,
- "horizontal": false
- }
- },
- {
- "id": 105,
- "type": "CheckpointLoaderSimple",
- "pos": [
- 21,
- 619
- ],
- "size": {
- "0": 315,
- "1": 98
- },
- "flags": {},
- "order": 2,
- "mode": 0,
- "outputs": [
- {
- "name": "MODEL",
- "type": "MODEL",
- "links": [
- 268,
- 276
- ],
- "slot_index": 0
- },
- {
- "name": "CLIP",
- "type": "CLIP",
- "links": [
- 260,
- 261
- ],
- "slot_index": 1
- },
- {
- "name": "VAE",
- "type": "VAE",
- "links": [
- 252,
- 267
- ],
- "slot_index": 2
- }
- ],
- "properties": {
- "Node name for S&R": "CheckpointLoaderSimple"
- },
- "widgets_values": [
- "V07_v07.safetensors"
- ]
- },
- {
- "id": 112,
- "type": "EmptyLatentImage",
- "pos": [
- 21,
- 1065
- ],
- "size": {
- "0": 315,
- "1": 106
- },
- "flags": {},
- "order": 3,
- "mode": 0,
- "outputs": [
- {
- "name": "LATENT",
- "type": "LATENT",
- "links": [
- 266
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "EmptyLatentImage"
- },
- "widgets_values": [
- 768,
- 512,
- 1
- ]
- },
- {
- "id": 108,
- "type": "VAEDecode",
- "pos": [
- 360,
- 1123
- ],
- "size": {
- "0": 381.7952880859375,
- "1": 46.58692932128906
- },
- "flags": {},
- "order": 8,
- "mode": 0,
- "inputs": [
- {
- "name": "samples",
- "type": "LATENT",
- "link": 272
- },
- {
- "name": "vae",
- "type": "VAE",
- "link": 267
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 273,
- 274,
- 277
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "VAEDecode"
- }
- },
- {
- "id": 110,
- "type": "CLIPTextEncode",
- "pos": [
- 362,
- 866
- ],
- "size": {
- "0": 381.7952880859375,
- "1": 213.58692932128906
- },
- "flags": {},
- "order": 5,
- "mode": 0,
- "inputs": [
- {
- "name": "clip",
- "type": "CLIP",
- "link": 261
- }
- ],
- "outputs": [
- {
- "name": "CONDITIONING",
- "type": "CONDITIONING",
- "links": [
- 265,
- 280
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "CLIPTextEncode"
- },
- "widgets_values": [
- "nsfw, paintings, sketches, (worst quality:2), (low quality:2), (normal quality:2), lowres, ((monochrome)), ((grayscale)), bad anatomy, Deep Negative, (fat:1.2), facing away, looking away, tilted head, lowres, bad anatomy, bad hands, text, error, missing fingers, extra digit, fewer digits, cropped, username, blurry, bad feet, cropped, poorly drawn hands, poorly drawn face, mutation, deformed, jpeg artifacts, signature, watermark, extra fingers, fewer digits, extra limbs, extra arms, extra legs, malformed limbs, fused fingers, too many fingers, long neck, cross-eyed, mutated hands, bad body, bad proportions, missing fingers, missing arms, missing legs, extra digit, badhandv4, EasyNegative, NG_DeepNegative_V1_75T, leather, ((solo))"
- ]
- },
- {
- "id": 109,
- "type": "CLIPTextEncode",
- "pos": [
- 359,
- 620
- ],
- "size": {
- "0": 382,
- "1": 204
- },
- "flags": {},
- "order": 4,
- "mode": 0,
- "inputs": [
- {
- "name": "clip",
- "type": "CLIP",
- "link": 260
- }
- ],
- "outputs": [
- {
- "name": "CONDITIONING",
- "type": "CONDITIONING",
- "links": [
- 264,
- 279
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "CLIPTextEncode"
- },
- "widgets_values": [
- "masterpiece, photorealistic:1.4, short break hair, (yellow check short jacket), white shirts, light pink necktie, (pink school check skirt), cute girl, sneakers, detailed eyes, realistic, 2girls, ultra detailed, beautiful girl, beautiful-detailed eyes, slender, small breast, smile, from top, luminous skin, stocking,"
- ]
- },
- {
- "id": 107,
- "type": "SaveImage",
- "pos": [
- 752,
- 620
- ],
- "size": {
- "0": 703.5068359375,
- "1": 549.9654541015625
- },
- "flags": {},
- "order": 9,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 273
- }
- ],
- "title": "Prompt",
- "properties": {},
- "widgets_values": [
- "original"
- ]
- },
- {
- "id": 115,
- "type": "SaveImage",
- "pos": [
- 1484,
- 615
- ],
- "size": {
- "0": 708.5068359375,
- "1": 555.9654541015625
- },
- "flags": {},
- "order": 16,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 281
- }
- ],
- "title": "Refined",
- "properties": {},
- "widgets_values": [
- "refined"
- ]
- },
- {
- "id": 111,
- "type": "KSampler",
- "pos": [
- 20,
- 762
- ],
- "size": {
- "0": 315,
- "1": 262
- },
- "flags": {},
- "order": 7,
- "mode": 0,
- "inputs": [
- {
- "name": "model",
- "type": "MODEL",
- "link": 268
- },
- {
- "name": "positive",
- "type": "CONDITIONING",
- "link": 264
- },
- {
- "name": "negative",
- "type": "CONDITIONING",
- "link": 265
- },
- {
- "name": "latent_image",
- "type": "LATENT",
- "link": 266
- }
- ],
- "outputs": [
- {
- "name": "LATENT",
- "type": "LATENT",
- "links": [
- 272
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "KSampler"
- },
- "widgets_values": [
- 832707305495685,
- "fixed",
- 20,
- 7,
- "euler",
- "karras",
- 1
- ]
- },
- {
- "id": 90,
- "type": "BboxDetectorForEach",
- "pos": [
- 712.9366837890625,
- 293.3044807531738
- ],
- "size": {
- "0": 251.412109375,
- "1": 126
- },
- "flags": {},
- "order": 11,
- "mode": 0,
- "inputs": [
- {
- "name": "bbox_model",
- "type": "BBOX_MODEL",
- "link": 204
- },
- {
- "name": "image",
- "type": "IMAGE",
- "link": 218
- }
- ],
- "outputs": [
- {
- "name": "SEGS",
- "type": "SEGS",
- "links": [
- 208,
- 239
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "BboxDetectorForEach"
- },
- "widgets_values": [
- 0.5,
- 20,
- 3
- ],
- "color": "#432",
- "bgcolor": "#653"
- },
- {
- "id": 114,
- "type": "DetailerForEach",
- "pos": [
- 2203,
- 614
- ],
- "size": {
- "0": 315,
- "1": 418
- },
- "flags": {},
- "order": 15,
- "mode": 0,
- "inputs": [
- {
- "name": "image",
- "type": "IMAGE",
- "link": 277
- },
- {
- "name": "segs",
- "type": "SEGS",
- "link": 275
- },
- {
- "name": "model",
- "type": "MODEL",
- "link": 276
- },
- {
- "name": "vae",
- "type": "VAE",
- "link": 278
- },
- {
- "name": "positive",
- "type": "CONDITIONING",
- "link": 279
- },
- {
- "name": "negative",
- "type": "CONDITIONING",
- "link": 280
- },
- {
- "name": "external_seed",
- "type": "SEED",
- "link": null
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 281
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "DetailerForEach"
- },
- "widgets_values": [
- 256,
- "bbox",
- 1041366330963730,
- "randomize",
- 20,
- 7,
- "euler",
- "karras",
- 0.6,
- 5,
- "disabled"
- ]
- },
- {
- "id": 91,
- "type": "SAMDetectorCombined",
- "pos": [
- 1112.0510126953125,
- 289
- ],
- "size": {
- "0": 234.59999084472656,
- "1": 146
- },
- "flags": {},
- "order": 12,
- "mode": 0,
- "inputs": [
- {
- "name": "sam_model",
- "type": "SAM_MODEL",
- "link": 282
- },
- {
- "name": "segs",
- "type": "SEGS",
- "link": 208
- },
- {
- "name": "image",
- "type": "IMAGE",
- "link": 219
- }
- ],
- "outputs": [
- {
- "name": "MASK",
- "type": "MASK",
- "links": [
- 247
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "SAMDetectorCombined"
- },
- "widgets_values": [
- "rect-4",
- 10,
- 0.9
- ],
- "color": "#232",
- "bgcolor": "#353"
- }
- ],
- "links": [
- [
- 204,
- 82,
- 0,
- 90,
- 0,
- "BBOX_MODEL"
- ],
- [
- 208,
- 90,
- 0,
- 91,
- 1,
- "SEGS"
- ],
- [
- 218,
- 94,
- 0,
- 90,
- 1,
- "IMAGE"
- ],
- [
- 219,
- 94,
- 0,
- 91,
- 2,
- "IMAGE"
- ],
- [
- 239,
- 90,
- 0,
- 103,
- 0,
- "*"
- ],
- [
- 246,
- 103,
- 0,
- 104,
- 0,
- "SEGS"
- ],
- [
- 247,
- 91,
- 0,
- 104,
- 1,
- "MASK"
- ],
- [
- 252,
- 105,
- 2,
- 106,
- 0,
- "*"
- ],
- [
- 260,
- 105,
- 1,
- 109,
- 0,
- "CLIP"
- ],
- [
- 261,
- 105,
- 1,
- 110,
- 0,
- "CLIP"
- ],
- [
- 264,
- 109,
- 0,
- 111,
- 1,
- "CONDITIONING"
- ],
- [
- 265,
- 110,
- 0,
- 111,
- 2,
- "CONDITIONING"
- ],
- [
- 266,
- 112,
- 0,
- 111,
- 3,
- "LATENT"
- ],
- [
- 267,
- 105,
- 2,
- 108,
- 1,
- "VAE"
- ],
- [
- 268,
- 105,
- 0,
- 111,
- 0,
- "MODEL"
- ],
- [
- 272,
- 111,
- 0,
- 108,
- 0,
- "LATENT"
- ],
- [
- 273,
- 108,
- 0,
- 107,
- 0,
- "IMAGE"
- ],
- [
- 274,
- 108,
- 0,
- 94,
- 0,
- "*"
- ],
- [
- 275,
- 104,
- 0,
- 114,
- 1,
- "SEGS"
- ],
- [
- 276,
- 105,
- 0,
- 114,
- 2,
- "MODEL"
- ],
- [
- 277,
- 108,
- 0,
- 114,
- 0,
- "IMAGE"
- ],
- [
- 278,
- 106,
- 0,
- 114,
- 3,
- "VAE"
- ],
- [
- 279,
- 109,
- 0,
- 114,
- 4,
- "CONDITIONING"
- ],
- [
- 280,
- 110,
- 0,
- 114,
- 5,
- "CONDITIONING"
- ],
- [
- 281,
- 114,
- 0,
- 115,
- 0,
- "IMAGE"
- ],
- [
- 282,
- 87,
- 0,
- 91,
- 0,
- "SAM_MODEL"
- ]
- ],
- "groups": [
- {
- "title": "Detection & Mask Generation",
- "bounding": [
- 664,
- 13,
- 1190,
- 447
- ],
- "color": "#3f789e"
- },
- {
- "title": "Group",
- "bounding": [
- 11,
- 496,
- 1462,
- 753
- ],
- "color": "#3f789e"
- },
- {
- "title": "Refine and Render",
- "bounding": [
- 1476,
- 495,
- 1057,
- 753
- ],
- "color": "#3f789e"
- }
- ],
- "config": {},
- "extra": {},
- "version": 0.4
-}
\ No newline at end of file
diff --git a/misc/combination.png b/misc/combination.png
deleted file mode 100644
index 2eb5ace0..00000000
Binary files a/misc/combination.png and /dev/null differ
diff --git a/misc/face-off-original.png b/misc/face-off-original.png
deleted file mode 100644
index c8fc2978..00000000
Binary files a/misc/face-off-original.png and /dev/null differ
diff --git a/misc/face-off-result.png b/misc/face-off-result.png
deleted file mode 100644
index 02eefbb8..00000000
Binary files a/misc/face-off-result.png and /dev/null differ
diff --git a/misc/face-off.json b/misc/face-off.json
deleted file mode 100644
index dc68a122..00000000
--- a/misc/face-off.json
+++ /dev/null
@@ -1,1424 +0,0 @@
-{
- "last_node_id": 130,
- "last_link_id": 355,
- "nodes": [
- {
- "id": 104,
- "type": "Segs & Mask",
- "pos": [
- 1529.9366837890627,
- 285.3044807531738
- ],
- "size": {
- "0": 210,
- "1": 46
- },
- "flags": {},
- "order": 21,
- "mode": 0,
- "inputs": [
- {
- "name": "segs",
- "type": "SEGS",
- "link": 246
- },
- {
- "name": "mask",
- "type": "MASK",
- "link": 337
- }
- ],
- "outputs": [
- {
- "name": "SEGS",
- "type": "SEGS",
- "links": [
- 347
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "Segs & Mask"
- },
- "color": "#323",
- "bgcolor": "#535"
- },
- {
- "id": 107,
- "type": "SaveImage",
- "pos": [
- 752,
- 620
- ],
- "size": {
- "0": 703.5068359375,
- "1": 549.9654541015625
- },
- "flags": {},
- "order": 16,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 273
- }
- ],
- "title": "Prompt",
- "properties": {},
- "widgets_values": [
- "original"
- ]
- },
- {
- "id": 108,
- "type": "VAEDecode",
- "pos": [
- 360,
- 1123
- ],
- "size": {
- "0": 381.7952880859375,
- "1": 46.58692932128906
- },
- "flags": {},
- "order": 14,
- "mode": 0,
- "inputs": [
- {
- "name": "samples",
- "type": "LATENT",
- "link": 272
- },
- {
- "name": "vae",
- "type": "VAE",
- "link": 267
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 273,
- 274,
- 346
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "VAEDecode"
- }
- },
- {
- "id": 110,
- "type": "CLIPTextEncode",
- "pos": [
- 362,
- 866
- ],
- "size": {
- "0": 381.7952880859375,
- "1": 213.58692932128906
- },
- "flags": {},
- "order": 8,
- "mode": 0,
- "inputs": [
- {
- "name": "clip",
- "type": "CLIP",
- "link": 304
- }
- ],
- "outputs": [
- {
- "name": "CONDITIONING",
- "type": "CONDITIONING",
- "links": [
- 265,
- 351
- ],
- "slot_index": 0
- }
- ],
- "title": "Negative Prompt",
- "properties": {
- "Node name for S&R": "CLIPTextEncode"
- },
- "widgets_values": [
- "easynegative, ng_deepnegative_v1_75t, (low quality:1.5), (worst quality:1.5), strabismus, pen, pencil, text, watermark, artist name, signature, letterboxed, bag, shoulder bag, briefcase, outerwears, jacket, coat, cardigan, suit, tire, 3d, perfect hand, perfect fingers, straw hat, wings, animal ears, crowd, badhandv4, animal tail, car, "
- ]
- },
- {
- "id": 109,
- "type": "CLIPTextEncode",
- "pos": [
- 359,
- 620
- ],
- "size": {
- "0": 382,
- "1": 204
- },
- "flags": {},
- "order": 7,
- "mode": 0,
- "inputs": [
- {
- "name": "clip",
- "type": "CLIP",
- "link": 303
- }
- ],
- "outputs": [
- {
- "name": "CONDITIONING",
- "type": "CONDITIONING",
- "links": [
- 264
- ],
- "slot_index": 0
- }
- ],
- "title": "Positive Prompt",
- "properties": {
- "Node name for S&R": "CLIPTextEncode"
- },
- "widgets_values": [
- "(Masterpiece, high quality), (best quality), (intricate details), (blurry background), 1girl, gunman, short red hair, freckles, western sheriff hat, scarf, duster coat over long sleeves shirt under brown vest, duster, jeans, bullet belt, western holster, (colt single action army revolver), full body, old west, wild west, american western town, outdoors, cowboy_western, unpaved road, Tumbleweed on road, 21 korean age girl, korean idol style, ulzzang, "
- ]
- },
- {
- "id": 124,
- "type": "CLIPTextEncode",
- "pos": [
- 2234,
- 617
- ],
- "size": {
- "0": 313.7494201660156,
- "1": 156.86895751953125
- },
- "flags": {},
- "order": 15,
- "mode": 0,
- "inputs": [
- {
- "name": "clip",
- "type": "CLIP",
- "link": 355
- }
- ],
- "outputs": [
- {
- "name": "CONDITIONING",
- "type": "CONDITIONING",
- "links": [
- 350
- ],
- "slot_index": 0
- }
- ],
- "title": "Face Prompt",
- "properties": {
- "Node name for S&R": "CLIPTextEncode"
- },
- "widgets_values": [
- "adorable face, wink, joyful, closeup portrait, looking away, "
- ]
- },
- {
- "id": 118,
- "type": "PreviewImage",
- "pos": [
- 2256.7401171875,
- 127.03999950408932
- ],
- "size": {
- "0": 227.76901245117188,
- "1": 252.140380859375
- },
- "flags": {},
- "order": 25,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 293
- }
- ],
- "title": "Enhanced",
- "properties": {
- "Node name for S&R": "PreviewImage"
- }
- },
- {
- "id": 117,
- "type": "PreviewImage",
- "pos": [
- 1963.7401171875,
- 133.03999950408937
- ],
- "size": {
- "0": 210,
- "1": 250
- },
- "flags": {},
- "order": 24,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 292
- }
- ],
- "title": "Cropped",
- "properties": {
- "Node name for S&R": "PreviewImage"
- }
- },
- {
- "id": 94,
- "type": "Reroute",
- "pos": [
- 559,
- 445
- ],
- "size": [
- 82,
- 26
- ],
- "flags": {},
- "order": 17,
- "mode": 0,
- "inputs": [
- {
- "name": "",
- "type": "*",
- "link": 274
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 218,
- 335
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "showOutputText": true,
- "horizontal": false
- }
- },
- {
- "id": 120,
- "type": "Reroute",
- "pos": [
- 416,
- -140
- ],
- "size": [
- 82,
- 26
- ],
- "flags": {},
- "order": 4,
- "mode": 0,
- "inputs": [
- {
- "name": "",
- "type": "*",
- "link": 327
- }
- ],
- "outputs": [
- {
- "name": "MODEL",
- "type": "MODEL",
- "links": [
- 315,
- 330
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "showOutputText": true,
- "horizontal": false
- }
- },
- {
- "id": 121,
- "type": "Reroute",
- "pos": [
- 419,
- -75
- ],
- "size": [
- 75,
- 26
- ],
- "flags": {},
- "order": 5,
- "mode": 0,
- "inputs": [
- {
- "name": "",
- "type": "*",
- "link": 333
- }
- ],
- "outputs": [
- {
- "name": "CLIP",
- "type": "CLIP",
- "links": [
- 303,
- 304,
- 328
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "showOutputText": true,
- "horizontal": false
- }
- },
- {
- "id": 105,
- "type": "CheckpointLoaderSimple",
- "pos": [
- 5,
- -10
- ],
- "size": {
- "0": 315,
- "1": 98
- },
- "flags": {},
- "order": 0,
- "mode": 0,
- "outputs": [
- {
- "name": "MODEL",
- "type": "MODEL",
- "links": [
- 327
- ],
- "slot_index": 0
- },
- {
- "name": "CLIP",
- "type": "CLIP",
- "links": [
- 333
- ],
- "slot_index": 1
- },
- {
- "name": "VAE",
- "type": "VAE",
- "links": [
- 252,
- 267
- ],
- "slot_index": 2
- }
- ],
- "properties": {
- "Node name for S&R": "CheckpointLoaderSimple"
- },
- "widgets_values": [
- "V07_v07.safetensors"
- ]
- },
- {
- "id": 125,
- "type": "Reroute",
- "pos": [
- 2122,
- -93
- ],
- "size": [
- 82,
- 26
- ],
- "flags": {},
- "order": 11,
- "mode": 0,
- "inputs": [
- {
- "name": "",
- "type": "*",
- "link": 353
- }
- ],
- "outputs": [
- {
- "name": "MODEL",
- "type": "MODEL",
- "links": [
- 348
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "showOutputText": true,
- "horizontal": false
- }
- },
- {
- "id": 106,
- "type": "Reroute",
- "pos": [
- 2124,
- -152
- ],
- "size": [
- 75,
- 26
- ],
- "flags": {},
- "order": 6,
- "mode": 0,
- "inputs": [
- {
- "name": "",
- "type": "*",
- "link": 252
- }
- ],
- "outputs": [
- {
- "name": "VAE",
- "type": "VAE",
- "links": [
- 349
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "showOutputText": true,
- "horizontal": false
- }
- },
- {
- "id": 130,
- "type": "Reroute",
- "pos": [
- 2120.9272289433748,
- -45.036994320749955
- ],
- "size": [
- 75,
- 26
- ],
- "flags": {},
- "order": 13,
- "mode": 0,
- "inputs": [
- {
- "name": "",
- "type": "*",
- "link": 354
- }
- ],
- "outputs": [
- {
- "name": "CLIP",
- "type": "CLIP",
- "links": [
- 355
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "showOutputText": true,
- "horizontal": false
- }
- },
- {
- "id": 87,
- "type": "SAMLoader",
- "pos": [
- 1105,
- 103
- ],
- "size": {
- "0": 327.3000183105469,
- "1": 96.49998474121094
- },
- "flags": {},
- "order": 1,
- "mode": 0,
- "outputs": [
- {
- "name": "SAM_MODEL",
- "type": "SAM_MODEL",
- "links": [
- 336
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "SAMLoader"
- },
- "widgets_values": [
- "sam_vit_b_01ec64.pth"
- ],
- "color": "#232",
- "bgcolor": "#353"
- },
- {
- "id": 82,
- "type": "MMDetLoader",
- "pos": [
- 713,
- 105
- ],
- "size": {
- "0": 374.412109375,
- "1": 93.55003356933594
- },
- "flags": {},
- "order": 2,
- "mode": 0,
- "outputs": [
- {
- "name": "BBOX_MODEL",
- "type": "BBOX_MODEL",
- "links": [
- 204
- ],
- "slot_index": 0
- },
- {
- "name": "SEGM_MODEL",
- "type": "SEGM_MODEL",
- "links": [],
- "slot_index": 1
- }
- ],
- "properties": {
- "Node name for S&R": "MMDetLoader"
- },
- "widgets_values": [
- "bbox/mmdet_anime-face_yolov3.pth"
- ],
- "color": "#432",
- "bgcolor": "#653"
- },
- {
- "id": 103,
- "type": "Reroute",
- "pos": [
- 1201,
- 224
- ],
- "size": [
- 75,
- 26
- ],
- "flags": {},
- "order": 19,
- "mode": 0,
- "inputs": [
- {
- "name": "",
- "type": "*",
- "link": 239
- }
- ],
- "outputs": [
- {
- "name": "SEGS",
- "type": "SEGS",
- "links": [
- 246
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "showOutputText": true,
- "horizontal": false
- }
- },
- {
- "id": 126,
- "type": "LoraLoader",
- "pos": [
- 996,
- -131
- ],
- "size": {
- "0": 410.2594299316406,
- "1": 126
- },
- "flags": {},
- "order": 9,
- "mode": 0,
- "inputs": [
- {
- "name": "model",
- "type": "MODEL",
- "link": 330
- },
- {
- "name": "clip",
- "type": "CLIP",
- "link": 328
- }
- ],
- "outputs": [
- {
- "name": "MODEL",
- "type": "MODEL",
- "links": [
- 329,
- 353
- ],
- "slot_index": 0
- },
- {
- "name": "CLIP",
- "type": "CLIP",
- "links": [
- 331,
- 354
- ],
- "slot_index": 1
- }
- ],
- "properties": {
- "Node name for S&R": "LoraLoader"
- },
- "widgets_values": [
- "emotionPuppeteerLora_v2Lora.safetensors",
- 1,
- 1
- ]
- },
- {
- "id": 119,
- "type": "LoraLoader",
- "pos": [
- 1444,
- -130
- ],
- "size": {
- "0": 408.50341796875,
- "1": 126
- },
- "flags": {},
- "order": 12,
- "mode": 0,
- "inputs": [
- {
- "name": "model",
- "type": "MODEL",
- "link": 329
- },
- {
- "name": "clip",
- "type": "CLIP",
- "link": 331
- }
- ],
- "outputs": [
- {
- "name": "MODEL",
- "type": "MODEL",
- "links": [],
- "slot_index": 0
- },
- {
- "name": "CLIP",
- "type": "CLIP",
- "links": [],
- "slot_index": 1
- }
- ],
- "properties": {
- "Node name for S&R": "LoraLoader"
- },
- "widgets_values": [
- "koreanDollLikeness_v10.safetensors",
- 1,
- 1
- ]
- },
- {
- "id": 90,
- "type": "BboxDetectorForEach",
- "pos": [
- 716,
- 311
- ],
- "size": {
- "0": 260.3999938964844,
- "1": 126
- },
- "flags": {},
- "order": 18,
- "mode": 0,
- "inputs": [
- {
- "name": "bbox_model",
- "type": "BBOX_MODEL",
- "link": 204
- },
- {
- "name": "image",
- "type": "IMAGE",
- "link": 218
- }
- ],
- "outputs": [
- {
- "name": "SEGS",
- "type": "SEGS",
- "links": [
- 239,
- 334
- ],
- "slot_index": 0
- }
- ],
- "title": "BboxDetectorFE !! DON'T MUTE !!",
- "properties": {
- "Node name for S&R": "BboxDetectorForEach"
- },
- "widgets_values": [
- 0.5,
- 10,
- 4.3
- ],
- "color": "#432",
- "bgcolor": "#653"
- },
- {
- "id": 116,
- "type": "DetailerForEachDebug",
- "pos": [
- 2234,
- 819
- ],
- "size": {
- "0": 315,
- "1": 418
- },
- "flags": {},
- "order": 22,
- "mode": 0,
- "inputs": [
- {
- "name": "image",
- "type": "IMAGE",
- "link": 346
- },
- {
- "name": "segs",
- "type": "SEGS",
- "link": 347
- },
- {
- "name": "model",
- "type": "MODEL",
- "link": 348
- },
- {
- "name": "vae",
- "type": "VAE",
- "link": 349
- },
- {
- "name": "positive",
- "type": "CONDITIONING",
- "link": 350
- },
- {
- "name": "negative",
- "type": "CONDITIONING",
- "link": 351
- },
- {
- "name": "external_seed",
- "type": "SEED",
- "link": null
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 352
- ],
- "slot_index": 0
- },
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 292
- ],
- "slot_index": 1
- },
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 293
- ],
- "slot_index": 2
- }
- ],
- "properties": {
- "Node name for S&R": "DetailerForEachDebug"
- },
- "widgets_values": [
- 320,
- "bbox",
- 281767597455979,
- "randomize",
- 20,
- 10,
- "euler",
- "karras",
- 0.5,
- 5,
- "disabled"
- ]
- },
- {
- "id": 112,
- "type": "EmptyLatentImage",
- "pos": [
- 21,
- 1065
- ],
- "size": {
- "0": 315,
- "1": 106
- },
- "flags": {},
- "order": 3,
- "mode": 0,
- "outputs": [
- {
- "name": "LATENT",
- "type": "LATENT",
- "links": [
- 266
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "EmptyLatentImage"
- },
- "widgets_values": [
- 768,
- 1152,
- 1
- ]
- },
- {
- "id": 115,
- "type": "SaveImage",
- "pos": [
- 1499,
- 619
- ],
- "size": {
- "0": 708.5068359375,
- "1": 555.9654541015625
- },
- "flags": {},
- "order": 23,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 352
- }
- ],
- "title": "Refined",
- "properties": {},
- "widgets_values": [
- "refined"
- ]
- },
- {
- "id": 111,
- "type": "KSampler",
- "pos": [
- 20,
- 762
- ],
- "size": {
- "0": 315,
- "1": 262
- },
- "flags": {},
- "order": 10,
- "mode": 0,
- "inputs": [
- {
- "name": "model",
- "type": "MODEL",
- "link": 315
- },
- {
- "name": "positive",
- "type": "CONDITIONING",
- "link": 264
- },
- {
- "name": "negative",
- "type": "CONDITIONING",
- "link": 265
- },
- {
- "name": "latent_image",
- "type": "LATENT",
- "link": 266
- }
- ],
- "outputs": [
- {
- "name": "LATENT",
- "type": "LATENT",
- "links": [
- 272
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "KSampler"
- },
- "widgets_values": [
- 98323244225723,
- "fixed",
- 30,
- 10,
- "euler",
- "karras",
- 1
- ]
- },
- {
- "id": 127,
- "type": "SAMDetectorCombined",
- "pos": [
- 1110,
- 295
- ],
- "size": {
- "0": 243.7554168701172,
- "1": 146
- },
- "flags": {},
- "order": 20,
- "mode": 0,
- "inputs": [
- {
- "name": "sam_model",
- "type": "SAM_MODEL",
- "link": 336
- },
- {
- "name": "segs",
- "type": "SEGS",
- "link": 334
- },
- {
- "name": "image",
- "type": "IMAGE",
- "link": 335
- }
- ],
- "outputs": [
- {
- "name": "MASK",
- "type": "MASK",
- "links": [
- 337
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "SAMDetectorCombined"
- },
- "widgets_values": [
- "center-1",
- 0.93,
- 0.93
- ],
- "color": "#232",
- "bgcolor": "#353"
- }
- ],
- "links": [
- [
- 204,
- 82,
- 0,
- 90,
- 0,
- "BBOX_MODEL"
- ],
- [
- 218,
- 94,
- 0,
- 90,
- 1,
- "IMAGE"
- ],
- [
- 239,
- 90,
- 0,
- 103,
- 0,
- "*"
- ],
- [
- 246,
- 103,
- 0,
- 104,
- 0,
- "SEGS"
- ],
- [
- 252,
- 105,
- 2,
- 106,
- 0,
- "*"
- ],
- [
- 264,
- 109,
- 0,
- 111,
- 1,
- "CONDITIONING"
- ],
- [
- 265,
- 110,
- 0,
- 111,
- 2,
- "CONDITIONING"
- ],
- [
- 266,
- 112,
- 0,
- 111,
- 3,
- "LATENT"
- ],
- [
- 267,
- 105,
- 2,
- 108,
- 1,
- "VAE"
- ],
- [
- 272,
- 111,
- 0,
- 108,
- 0,
- "LATENT"
- ],
- [
- 273,
- 108,
- 0,
- 107,
- 0,
- "IMAGE"
- ],
- [
- 274,
- 108,
- 0,
- 94,
- 0,
- "*"
- ],
- [
- 292,
- 116,
- 1,
- 117,
- 0,
- "IMAGE"
- ],
- [
- 293,
- 116,
- 2,
- 118,
- 0,
- "IMAGE"
- ],
- [
- 303,
- 121,
- 0,
- 109,
- 0,
- "CLIP"
- ],
- [
- 304,
- 121,
- 0,
- 110,
- 0,
- "CLIP"
- ],
- [
- 315,
- 120,
- 0,
- 111,
- 0,
- "MODEL"
- ],
- [
- 327,
- 105,
- 0,
- 120,
- 0,
- "*"
- ],
- [
- 328,
- 121,
- 0,
- 126,
- 1,
- "CLIP"
- ],
- [
- 329,
- 126,
- 0,
- 119,
- 0,
- "MODEL"
- ],
- [
- 330,
- 120,
- 0,
- 126,
- 0,
- "MODEL"
- ],
- [
- 331,
- 126,
- 1,
- 119,
- 1,
- "CLIP"
- ],
- [
- 333,
- 105,
- 1,
- 121,
- 0,
- "*"
- ],
- [
- 334,
- 90,
- 0,
- 127,
- 1,
- "SEGS"
- ],
- [
- 335,
- 94,
- 0,
- 127,
- 2,
- "IMAGE"
- ],
- [
- 336,
- 87,
- 0,
- 127,
- 0,
- "SAM_MODEL"
- ],
- [
- 337,
- 127,
- 0,
- 104,
- 1,
- "MASK"
- ],
- [
- 346,
- 108,
- 0,
- 116,
- 0,
- "IMAGE"
- ],
- [
- 347,
- 104,
- 0,
- 116,
- 1,
- "SEGS"
- ],
- [
- 348,
- 125,
- 0,
- 116,
- 2,
- "MODEL"
- ],
- [
- 349,
- 106,
- 0,
- 116,
- 3,
- "VAE"
- ],
- [
- 350,
- 124,
- 0,
- 116,
- 4,
- "CONDITIONING"
- ],
- [
- 351,
- 110,
- 0,
- 116,
- 5,
- "CONDITIONING"
- ],
- [
- 352,
- 116,
- 0,
- 115,
- 0,
- "IMAGE"
- ],
- [
- 353,
- 126,
- 0,
- 125,
- 0,
- "*"
- ],
- [
- 354,
- 126,
- 1,
- 130,
- 0,
- "*"
- ],
- [
- 355,
- 130,
- 0,
- 124,
- 0,
- "CLIP"
- ]
- ],
- "groups": [
- {
- "title": "Detection & Mask Generation",
- "bounding": [
- 664,
- 13,
- 1190,
- 447
- ],
- "color": "#3f789e"
- },
- {
- "title": "Prompt",
- "bounding": [
- 11,
- 496,
- 1462,
- 753
- ],
- "color": "#3f789e"
- },
- {
- "title": "Face-off",
- "bounding": [
- 1479,
- 495,
- 1088,
- 753
- ],
- "color": "#3f789e"
- },
- {
- "title": "Detailer Preview",
- "bounding": [
- 1902,
- 10,
- 664,
- 448
- ],
- "color": "#3f789e"
- }
- ],
- "config": {},
- "extra": {},
- "version": 0.4
-}
\ No newline at end of file
diff --git a/misc/mask-combined.png b/misc/mask-combined.png
deleted file mode 100644
index d833e49c..00000000
Binary files a/misc/mask-combined.png and /dev/null differ
diff --git a/misc/mask-original.png b/misc/mask-original.png
deleted file mode 100644
index a2f5e91f..00000000
Binary files a/misc/mask-original.png and /dev/null differ
diff --git a/misc/mask-sam.png b/misc/mask-sam.png
deleted file mode 100644
index 564d36d3..00000000
Binary files a/misc/mask-sam.png and /dev/null differ
diff --git a/misc/mask.png b/misc/mask.png
deleted file mode 100644
index b45d613b..00000000
Binary files a/misc/mask.png and /dev/null differ
diff --git a/misc/maskpainter-original.png b/misc/maskpainter-original.png
deleted file mode 100644
index 9d7acebb..00000000
Binary files a/misc/maskpainter-original.png and /dev/null differ
diff --git a/misc/maskpainter-result.png b/misc/maskpainter-result.png
deleted file mode 100644
index bc039d2e..00000000
Binary files a/misc/maskpainter-result.png and /dev/null differ
diff --git a/misc/maskpainter.json b/misc/maskpainter.json
deleted file mode 100644
index bba0707e..00000000
--- a/misc/maskpainter.json
+++ /dev/null
@@ -1,1452 +0,0 @@
-{
- "last_node_id": 40,
- "last_link_id": 126,
- "nodes": [
- {
- "id": 38,
- "type": "CLIPTextEncode",
- "pos": [
- 296.87999910354637,
- 470.43994018554685
- ],
- "size": [
- 310.2266245367921,
- 119.74945866398821
- ],
- "flags": {},
- "order": 5,
- "mode": 0,
- "inputs": [
- {
- "name": "clip",
- "type": "CLIP",
- "link": 103
- }
- ],
- "outputs": [
- {
- "name": "CONDITIONING",
- "type": "CONDITIONING",
- "links": [
- 104
- ],
- "slot_index": 0
- }
- ],
- "title": "Inpaint (Positive)",
- "properties": {
- "Node name for S&R": "CLIPTextEncode"
- },
- "widgets_values": [
- "1girl, cropped, jean skirt"
- ],
- "color": "#223",
- "bgcolor": "#335"
- },
- {
- "id": 20,
- "type": "CLIPTextEncode",
- "pos": [
- 300.87999910354637,
- 56.43994018554691
- ],
- "size": [
- 316.0668257715445,
- 154.45109583255095
- ],
- "flags": {},
- "order": 3,
- "mode": 0,
- "inputs": [
- {
- "name": "clip",
- "type": "CLIP",
- "link": 24
- }
- ],
- "outputs": [
- {
- "name": "CONDITIONING",
- "type": "CONDITIONING",
- "links": [
- 73
- ],
- "slot_index": 0
- }
- ],
- "title": "Positive",
- "properties": {
- "Node name for S&R": "CLIPTextEncode"
- },
- "widgets_values": [
- "photorealistic:1.4, masterpiece, ((best quality, high_resolution, distinct_image)), ultra detailed, disheveled hair, 1girl, (green long hair:1.3), yellow eyes, sunglasses on head, (small breasts:1.2), (miniskirt), (yellow t-shirt), black long coat), Star earrings, night, city background, perfect anatomy"
- ],
- "color": "#322",
- "bgcolor": "#533"
- },
- {
- "id": 35,
- "type": "SaveImage",
- "pos": [
- 850.8799991035456,
- 56.43994018554691
- ],
- "size": [
- 218.98424258069917,
- 347.54985128179237
- ],
- "flags": {},
- "order": 8,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 60
- }
- ],
- "title": "Original",
- "properties": {},
- "widgets_values": [
- "original"
- ],
- "color": "#322",
- "bgcolor": "#533"
- },
- {
- "id": 19,
- "type": "CLIPTextEncode",
- "pos": [
- 299.87999910354637,
- 262.43994018554685
- ],
- "size": [
- 316.2931386108992,
- 142.7274927502973
- ],
- "flags": {},
- "order": 4,
- "mode": 0,
- "inputs": [
- {
- "name": "clip",
- "type": "CLIP",
- "link": 25
- }
- ],
- "outputs": [
- {
- "name": "CONDITIONING",
- "type": "CONDITIONING",
- "links": [
- 26,
- 74
- ],
- "slot_index": 0
- }
- ],
- "title": "Negative",
- "properties": {
- "Node name for S&R": "CLIPTextEncode"
- },
- "widgets_values": [
- "(nsfw), (worst quality, low quality:1.3), (depth of field, blurry:1.2), (greyscale, monochrome:1.1), 3D face, nose, cropped, lowres, text, jpeg artifacts, signature, watermark, username, blurry, artist name, trademark, watermark, title, (tan, muscular, loli, petite, child, infant, toddlers, chibi, sd character:1.1), multiple view, Reference sheet, nipple"
- ],
- "color": "#322",
- "bgcolor": "#533"
- },
- {
- "id": 4,
- "type": "VAEEncodeForInpaint",
- "pos": [
- 1083.879999103546,
- 219.43994018554685
- ],
- "size": {
- "0": 226.8000030517578,
- "1": 66
- },
- "flags": {},
- "order": 12,
- "mode": 0,
- "inputs": [
- {
- "name": "pixels",
- "type": "IMAGE",
- "link": 108
- },
- {
- "name": "vae",
- "type": "VAE",
- "link": 47
- },
- {
- "name": "mask",
- "type": "MASK",
- "link": 62
- }
- ],
- "outputs": [
- {
- "name": "LATENT",
- "type": "LATENT",
- "links": [
- 111
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "VAEEncodeForInpaint"
- },
- "color": "#432",
- "bgcolor": "#653"
- },
- {
- "id": 7,
- "type": "PreviewImage",
- "pos": [
- 1323.879999103546,
- 187.43994018554685
- ],
- "size": [
- 140,
- 215.94338580383703
- ],
- "flags": {},
- "order": 16,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 110
- }
- ],
- "title": "Masked",
- "properties": {
- "Node name for S&R": "PreviewImage"
- },
- "color": "#432",
- "bgcolor": "#653"
- },
- {
- "id": 16,
- "type": "Segs & Mask",
- "pos": [
- 1621.8799991035464,
- 241.43994018554687
- ],
- "size": {
- "0": 226.6055908203125,
- "1": 46
- },
- "flags": {},
- "order": 17,
- "mode": 0,
- "inputs": [
- {
- "name": "segs",
- "type": "SEGS",
- "link": 101
- },
- {
- "name": "mask",
- "type": "MASK",
- "link": 100
- }
- ],
- "outputs": [
- {
- "name": "SEGS",
- "type": "SEGS",
- "links": [
- 77,
- 123
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "Segs & Mask"
- },
- "color": "#232",
- "bgcolor": "#353"
- },
- {
- "id": 10,
- "type": "SAMLoader",
- "pos": [
- 37.879999103546176,
- 54.439940185546895
- ],
- "size": [
- 239,
- 62
- ],
- "flags": {},
- "order": 0,
- "mode": 0,
- "outputs": [
- {
- "name": "SAM_MODEL",
- "type": "SAM_MODEL",
- "links": [
- 10
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "SAMLoader"
- },
- "widgets_values": [
- "sam_vit_b_01ec64.pth"
- ],
- "color": "#222",
- "bgcolor": "#000"
- },
- {
- "id": 33,
- "type": "EmptyLatentImage",
- "pos": [
- 35.87999910354617,
- 297.43994018554673
- ],
- "size": [
- 248,
- 106
- ],
- "flags": {},
- "order": 1,
- "mode": 0,
- "outputs": [
- {
- "name": "LATENT",
- "type": "LATENT",
- "links": [
- 72
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "EmptyLatentImage"
- },
- "widgets_values": [
- 704,
- 1024,
- 1
- ],
- "color": "#222",
- "bgcolor": "#000"
- },
- {
- "id": 18,
- "type": "CheckpointLoaderSimple",
- "pos": [
- 34.87999910354617,
- 153.43994018554685
- ],
- "size": {
- "0": 248,
- "1": 98
- },
- "flags": {},
- "order": 2,
- "mode": 0,
- "outputs": [
- {
- "name": "MODEL",
- "type": "MODEL",
- "links": [
- 22,
- 75
- ],
- "slot_index": 0
- },
- {
- "name": "CLIP",
- "type": "CLIP",
- "links": [
- 24,
- 25,
- 103
- ],
- "slot_index": 1
- },
- {
- "name": "VAE",
- "type": "VAE",
- "links": [
- 45,
- 47,
- 48,
- 49,
- 59,
- 102
- ],
- "slot_index": 2
- }
- ],
- "properties": {
- "Node name for S&R": "CheckpointLoaderSimple"
- },
- "widgets_values": [
- "V07_v07.safetensors"
- ],
- "color": "#222",
- "bgcolor": "#000"
- },
- {
- "id": 6,
- "type": "VAEDecode",
- "pos": [
- 1086,
- 357
- ],
- "size": {
- "0": 228,
- "1": 46
- },
- "flags": {},
- "order": 14,
- "mode": 0,
- "inputs": [
- {
- "name": "samples",
- "type": "LATENT",
- "link": 111
- },
- {
- "name": "vae",
- "type": "VAE",
- "link": 48
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 110
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "VAEDecode"
- },
- "color": "#432",
- "bgcolor": "#653"
- },
- {
- "id": 34,
- "type": "VAEDecode",
- "pos": [
- 631,
- 56
- ],
- "size": {
- "0": 210,
- "1": 46
- },
- "flags": {},
- "order": 7,
- "mode": 0,
- "inputs": [
- {
- "name": "samples",
- "type": "LATENT",
- "link": 76
- },
- {
- "name": "vae",
- "type": "VAE",
- "link": 59
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 60,
- 64,
- 105
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "VAEDecode"
- },
- "color": "#322",
- "bgcolor": "#533"
- },
- {
- "id": 37,
- "type": "KSampler",
- "pos": [
- 630,
- 142
- ],
- "size": [
- 210,
- 262
- ],
- "flags": {},
- "order": 6,
- "mode": 0,
- "inputs": [
- {
- "name": "model",
- "type": "MODEL",
- "link": 75
- },
- {
- "name": "positive",
- "type": "CONDITIONING",
- "link": 73
- },
- {
- "name": "negative",
- "type": "CONDITIONING",
- "link": 74
- },
- {
- "name": "latent_image",
- "type": "LATENT",
- "link": 72
- }
- ],
- "outputs": [
- {
- "name": "LATENT",
- "type": "LATENT",
- "links": [
- 76
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "KSampler"
- },
- "widgets_values": [
- 690630353676394,
- "fixed",
- 20,
- 8,
- "euler",
- "karras",
- 1
- ],
- "color": "#322",
- "bgcolor": "#533"
- },
- {
- "id": 30,
- "type": "VAEDecode",
- "pos": [
- 1622.856268763194,
- 503.96589322474875
- ],
- "size": {
- "0": 227.90530395507812,
- "1": 46
- },
- "flags": {},
- "order": 24,
- "mode": 0,
- "inputs": [
- {
- "name": "samples",
- "type": "LATENT",
- "link": 119
- },
- {
- "name": "vae",
- "type": "VAE",
- "link": 102
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 121
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "VAEDecode"
- },
- "color": "#232",
- "bgcolor": "#353"
- },
- {
- "id": 23,
- "type": "SaveImage",
- "pos": [
- 849,
- 471
- ],
- "size": {
- "0": 289,
- "1": 415
- },
- "flags": {},
- "order": 20,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 28
- }
- ],
- "title": "Result",
- "properties": {},
- "widgets_values": [
- "Result"
- ],
- "color": "#223",
- "bgcolor": "#335"
- },
- {
- "id": 25,
- "type": "PreviewImage",
- "pos": [
- 1473.8799991035464,
- 187.43994018554685
- ],
- "size": [
- 140,
- 215.40391144914486
- ],
- "flags": {},
- "order": 25,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 121
- }
- ],
- "title": "Refined Masked",
- "properties": {
- "Node name for S&R": "PreviewImage"
- },
- "color": "#432",
- "bgcolor": "#653"
- },
- {
- "id": 27,
- "type": "VAEEncodeForInpaint",
- "pos": [
- 1623,
- 402
- ],
- "size": {
- "0": 226.8000030517578,
- "1": 66
- },
- "flags": {},
- "order": 23,
- "mode": 0,
- "inputs": [
- {
- "name": "pixels",
- "type": "IMAGE",
- "link": 122
- },
- {
- "name": "vae",
- "type": "VAE",
- "link": 45
- },
- {
- "name": "mask",
- "type": "MASK",
- "link": 120
- }
- ],
- "outputs": [
- {
- "name": "LATENT",
- "type": "LATENT",
- "links": [
- 119
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "VAEEncodeForInpaint"
- },
- "color": "#232",
- "bgcolor": "#353"
- },
- {
- "id": 28,
- "type": "SegsMaskCombine",
- "pos": [
- 1623.856268763194,
- 321.96589322474875
- ],
- "size": {
- "0": 225.70559692382812,
- "1": 46
- },
- "flags": {},
- "order": 19,
- "mode": 0,
- "inputs": [
- {
- "name": "segs",
- "type": "SEGS",
- "link": 123
- },
- {
- "name": "image",
- "type": "IMAGE",
- "link": 112
- }
- ],
- "outputs": [
- {
- "name": "MASK",
- "type": "MASK",
- "links": [
- 120
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "SegsMaskCombine"
- },
- "color": "#232",
- "bgcolor": "#353"
- },
- {
- "id": 40,
- "type": "Reroute",
- "pos": [
- 987,
- -6
- ],
- "size": [
- 82,
- 26
- ],
- "flags": {},
- "order": 10,
- "mode": 0,
- "inputs": [
- {
- "name": "",
- "type": "*",
- "link": 126
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 107,
- 108,
- 112,
- 122,
- 124
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "showOutputText": true,
- "horizontal": false
- }
- },
- {
- "id": 39,
- "type": "Reroute",
- "pos": [
- 853,
- -6
- ],
- "size": [
- 82,
- 26
- ],
- "flags": {},
- "order": 9,
- "mode": 0,
- "inputs": [
- {
- "name": "",
- "type": "*",
- "link": 105
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 126
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "showOutputText": true,
- "horizontal": false
- }
- },
- {
- "id": 13,
- "type": "MaskToSEGS",
- "pos": [
- 1325,
- 54
- ],
- "size": [
- 289.19432375939186,
- 87.74590362440813
- ],
- "flags": {},
- "order": 13,
- "mode": 0,
- "inputs": [
- {
- "name": "mask",
- "type": "MASK",
- "link": 71
- }
- ],
- "outputs": [
- {
- "name": "SEGS",
- "type": "SEGS",
- "links": [
- 101,
- 125
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "MaskToSEGS"
- },
- "widgets_values": [
- "True",
- 2
- ],
- "color": "#432",
- "bgcolor": "#653"
- },
- {
- "id": 9,
- "type": "SAMDetectorCombined",
- "pos": [
- 1622.856268763194,
- 51.96589322474882
- ],
- "size": {
- "0": 225.6055908203125,
- "1": 150.59918212890625
- },
- "flags": {},
- "order": 15,
- "mode": 0,
- "inputs": [
- {
- "name": "sam_model",
- "type": "SAM_MODEL",
- "link": 10
- },
- {
- "name": "segs",
- "type": "SEGS",
- "link": 125
- },
- {
- "name": "image",
- "type": "IMAGE",
- "link": 124
- }
- ],
- "outputs": [
- {
- "name": "MASK",
- "type": "MASK",
- "links": [
- 100
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "SAMDetectorCombined"
- },
- "widgets_values": [
- "none",
- 0.93,
- 0.96
- ],
- "color": "#232",
- "bgcolor": "#353"
- },
- {
- "id": 36,
- "type": "MaskPainter",
- "pos": [
- 1081,
- 55
- ],
- "size": [
- 227.1449788475237,
- 102
- ],
- "flags": {},
- "order": 11,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 107
- },
- {
- "name": "mask_image",
- "type": "IMAGE_PATH",
- "link": null
- }
- ],
- "outputs": [
- {
- "name": "MASK",
- "type": "MASK",
- "links": [
- 62,
- 71
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "MaskPainter"
- },
- "widgets_values": [
- null,
- {
- "filename": "impact-mask-4073711.2.png",
- "subfolder": "",
- "type": "temp"
- }
- ],
- "color": "#432",
- "bgcolor": "#653"
- },
- {
- "id": 17,
- "type": "DetailerForEachDebug",
- "pos": [
- 633,
- 472
- ],
- "size": [
- 210,
- 418
- ],
- "flags": {},
- "order": 18,
- "mode": 0,
- "inputs": [
- {
- "name": "image",
- "type": "IMAGE",
- "link": 64
- },
- {
- "name": "segs",
- "type": "SEGS",
- "link": 77
- },
- {
- "name": "model",
- "type": "MODEL",
- "link": 22
- },
- {
- "name": "vae",
- "type": "VAE",
- "link": 49
- },
- {
- "name": "positive",
- "type": "CONDITIONING",
- "link": 104
- },
- {
- "name": "negative",
- "type": "CONDITIONING",
- "link": 26
- },
- {
- "name": "external_seed",
- "type": "SEED",
- "link": null
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 28
- ],
- "slot_index": 0
- },
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 29
- ],
- "slot_index": 1
- },
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 30
- ],
- "slot_index": 2
- }
- ],
- "properties": {
- "Node name for S&R": "DetailerForEachDebug"
- },
- "widgets_values": [
- 384,
- "bbox",
- 111413969982424,
- "fixed",
- 20,
- 10,
- "euler",
- "karras",
- 0.61,
- 3,
- "enabled"
- ],
- "color": "#223",
- "bgcolor": "#335"
- },
- {
- "id": 21,
- "type": "PreviewImage",
- "pos": [
- 1159,
- 472
- ],
- "size": {
- "0": 166.99998474121094,
- "1": 174.00001525878906
- },
- "flags": {},
- "order": 21,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 29
- }
- ],
- "title": "Cropped",
- "properties": {
- "Node name for S&R": "PreviewImage"
- },
- "color": "#223",
- "bgcolor": "#335"
- },
- {
- "id": 22,
- "type": "PreviewImage",
- "pos": [
- 1159,
- 689
- ],
- "size": [
- 169.68491607920532,
- 193.83173008736003
- ],
- "flags": {},
- "order": 22,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 30
- }
- ],
- "title": "Refined Crop",
- "properties": {
- "Node name for S&R": "PreviewImage"
- },
- "color": "#223",
- "bgcolor": "#335"
- }
- ],
- "links": [
- [
- 10,
- 10,
- 0,
- 9,
- 0,
- "SAM_MODEL"
- ],
- [
- 22,
- 18,
- 0,
- 17,
- 2,
- "MODEL"
- ],
- [
- 24,
- 18,
- 1,
- 20,
- 0,
- "CLIP"
- ],
- [
- 25,
- 18,
- 1,
- 19,
- 0,
- "CLIP"
- ],
- [
- 26,
- 19,
- 0,
- 17,
- 5,
- "CONDITIONING"
- ],
- [
- 28,
- 17,
- 0,
- 23,
- 0,
- "IMAGE"
- ],
- [
- 29,
- 17,
- 1,
- 21,
- 0,
- "IMAGE"
- ],
- [
- 30,
- 17,
- 2,
- 22,
- 0,
- "IMAGE"
- ],
- [
- 45,
- 18,
- 2,
- 27,
- 1,
- "VAE"
- ],
- [
- 47,
- 18,
- 2,
- 4,
- 1,
- "VAE"
- ],
- [
- 48,
- 18,
- 2,
- 6,
- 1,
- "VAE"
- ],
- [
- 49,
- 18,
- 2,
- 17,
- 3,
- "VAE"
- ],
- [
- 59,
- 18,
- 2,
- 34,
- 1,
- "VAE"
- ],
- [
- 60,
- 34,
- 0,
- 35,
- 0,
- "IMAGE"
- ],
- [
- 62,
- 36,
- 0,
- 4,
- 2,
- "MASK"
- ],
- [
- 64,
- 34,
- 0,
- 17,
- 0,
- "IMAGE"
- ],
- [
- 71,
- 36,
- 0,
- 13,
- 0,
- "MASK"
- ],
- [
- 72,
- 33,
- 0,
- 37,
- 3,
- "LATENT"
- ],
- [
- 73,
- 20,
- 0,
- 37,
- 1,
- "CONDITIONING"
- ],
- [
- 74,
- 19,
- 0,
- 37,
- 2,
- "CONDITIONING"
- ],
- [
- 75,
- 18,
- 0,
- 37,
- 0,
- "MODEL"
- ],
- [
- 76,
- 37,
- 0,
- 34,
- 0,
- "LATENT"
- ],
- [
- 77,
- 16,
- 0,
- 17,
- 1,
- "SEGS"
- ],
- [
- 100,
- 9,
- 0,
- 16,
- 1,
- "MASK"
- ],
- [
- 101,
- 13,
- 0,
- 16,
- 0,
- "SEGS"
- ],
- [
- 102,
- 18,
- 2,
- 30,
- 1,
- "VAE"
- ],
- [
- 103,
- 18,
- 1,
- 38,
- 0,
- "CLIP"
- ],
- [
- 104,
- 38,
- 0,
- 17,
- 4,
- "CONDITIONING"
- ],
- [
- 105,
- 34,
- 0,
- 39,
- 0,
- "*"
- ],
- [
- 107,
- 40,
- 0,
- 36,
- 0,
- "IMAGE"
- ],
- [
- 108,
- 40,
- 0,
- 4,
- 0,
- "IMAGE"
- ],
- [
- 110,
- 6,
- 0,
- 7,
- 0,
- "IMAGE"
- ],
- [
- 111,
- 4,
- 0,
- 6,
- 0,
- "LATENT"
- ],
- [
- 112,
- 40,
- 0,
- 28,
- 1,
- "IMAGE"
- ],
- [
- 119,
- 27,
- 0,
- 30,
- 0,
- "LATENT"
- ],
- [
- 120,
- 28,
- 0,
- 27,
- 2,
- "MASK"
- ],
- [
- 121,
- 30,
- 0,
- 25,
- 0,
- "IMAGE"
- ],
- [
- 122,
- 40,
- 0,
- 27,
- 0,
- "IMAGE"
- ],
- [
- 123,
- 16,
- 0,
- 28,
- 0,
- "SEGS"
- ],
- [
- 124,
- 40,
- 0,
- 9,
- 2,
- "IMAGE"
- ],
- [
- 125,
- 13,
- 0,
- 9,
- 1,
- "SEGS"
- ],
- [
- 126,
- 39,
- 0,
- 40,
- 0,
- "*"
- ]
- ],
- "groups": [],
- "config": {},
- "extra": {},
- "version": 0.4
-}
\ No newline at end of file
diff --git a/misc/maskpainter1.png b/misc/maskpainter1.png
deleted file mode 100644
index f4ed4797..00000000
Binary files a/misc/maskpainter1.png and /dev/null differ
diff --git a/misc/maskpainter2.png b/misc/maskpainter2.png
deleted file mode 100644
index 27a39692..00000000
Binary files a/misc/maskpainter2.png and /dev/null differ
diff --git a/misc/maskpointer.json b/misc/maskpointer.json
deleted file mode 100644
index a535d0da..00000000
--- a/misc/maskpointer.json
+++ /dev/null
@@ -1,1433 +0,0 @@
-{
- "last_node_id": 43,
- "last_link_id": 136,
- "nodes": [
- {
- "id": 38,
- "type": "CLIPTextEncode",
- "pos": [
- 296.87999910354637,
- 470.43994018554685
- ],
- "size": {
- "0": 310.22662353515625,
- "1": 119.74945831298828
- },
- "flags": {},
- "order": 5,
- "mode": 0,
- "inputs": [
- {
- "name": "clip",
- "type": "CLIP",
- "link": 103
- }
- ],
- "outputs": [
- {
- "name": "CONDITIONING",
- "type": "CONDITIONING",
- "links": [
- 104
- ],
- "slot_index": 0
- }
- ],
- "title": "Inpaint (Positive)",
- "properties": {
- "Node name for S&R": "CLIPTextEncode"
- },
- "widgets_values": [
- "1girl, photorealistic:1.4, masterpiece, silver, cropped, supergirl"
- ],
- "color": "#223",
- "bgcolor": "#335"
- },
- {
- "id": 20,
- "type": "CLIPTextEncode",
- "pos": [
- 300.87999910354637,
- 56.43994018554691
- ],
- "size": {
- "0": 316.06683349609375,
- "1": 154.4510955810547
- },
- "flags": {},
- "order": 3,
- "mode": 0,
- "inputs": [
- {
- "name": "clip",
- "type": "CLIP",
- "link": 24
- }
- ],
- "outputs": [
- {
- "name": "CONDITIONING",
- "type": "CONDITIONING",
- "links": [
- 73
- ],
- "slot_index": 0
- }
- ],
- "title": "Positive",
- "properties": {
- "Node name for S&R": "CLIPTextEncode"
- },
- "widgets_values": [
- "photorealistic:1.4, (masterpiece:1.2), (best quality:1.2), (intricate details:1.1), (detailed face:1.2), highres, cinematic light, A young Korean idol actress, 20 years old, skateboarding down a busy street, wearing a casual and edgy outfit with ripped jean skirt and a leather jacket, with a confident and carefree expression, surrounded by colorful street art and graffiti on the walls, captured in a dynamic and gritty urban art style with spray paints and markers on a large wall, (full body:0.8)"
- ],
- "color": "#322",
- "bgcolor": "#533"
- },
- {
- "id": 19,
- "type": "CLIPTextEncode",
- "pos": [
- 299.87999910354637,
- 262.43994018554685
- ],
- "size": {
- "0": 316.29315185546875,
- "1": 142.7274932861328
- },
- "flags": {},
- "order": 4,
- "mode": 0,
- "inputs": [
- {
- "name": "clip",
- "type": "CLIP",
- "link": 25
- }
- ],
- "outputs": [
- {
- "name": "CONDITIONING",
- "type": "CONDITIONING",
- "links": [
- 74
- ],
- "slot_index": 0
- }
- ],
- "title": "Negative",
- "properties": {
- "Node name for S&R": "CLIPTextEncode"
- },
- "widgets_values": [
- "nsfw, (worst quality, low quality:1.3), (depth of field, blurry:1.2), (greyscale, monochrome:1.1), 3D face, nose, cropped, lowres, text, jpeg artifacts, signature, watermark, username, blurry, artist name, trademark, watermark, title, (tan, muscular, loli, petite, child, infant, toddlers, chibi, sd character:1.1), multiple view, Reference sheet, "
- ],
- "color": "#322",
- "bgcolor": "#533"
- },
- {
- "id": 7,
- "type": "PreviewImage",
- "pos": [
- 1323.879999103546,
- 187.43994018554685
- ],
- "size": {
- "0": 140,
- "1": 215.94338989257812
- },
- "flags": {},
- "order": 17,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 110
- }
- ],
- "title": "Masked",
- "properties": {
- "Node name for S&R": "PreviewImage"
- },
- "color": "#432",
- "bgcolor": "#653"
- },
- {
- "id": 10,
- "type": "SAMLoader",
- "pos": [
- 37.879999103546176,
- 54.439940185546895
- ],
- "size": {
- "0": 239,
- "1": 62
- },
- "flags": {},
- "order": 0,
- "mode": 0,
- "outputs": [
- {
- "name": "SAM_MODEL",
- "type": "SAM_MODEL",
- "links": [
- 10
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "SAMLoader"
- },
- "widgets_values": [
- "sam_vit_b_01ec64.pth"
- ],
- "color": "#222",
- "bgcolor": "#000"
- },
- {
- "id": 33,
- "type": "EmptyLatentImage",
- "pos": [
- 35.87999910354617,
- 297.43994018554673
- ],
- "size": {
- "0": 248,
- "1": 106
- },
- "flags": {},
- "order": 1,
- "mode": 0,
- "outputs": [
- {
- "name": "LATENT",
- "type": "LATENT",
- "links": [
- 72
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "EmptyLatentImage"
- },
- "widgets_values": [
- 704,
- 1024,
- 1
- ],
- "color": "#222",
- "bgcolor": "#000"
- },
- {
- "id": 6,
- "type": "VAEDecode",
- "pos": [
- 1086,
- 357
- ],
- "size": {
- "0": 228,
- "1": 46
- },
- "flags": {},
- "order": 15,
- "mode": 0,
- "inputs": [
- {
- "name": "samples",
- "type": "LATENT",
- "link": 111
- },
- {
- "name": "vae",
- "type": "VAE",
- "link": 48
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 110
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "VAEDecode"
- },
- "color": "#432",
- "bgcolor": "#653"
- },
- {
- "id": 34,
- "type": "VAEDecode",
- "pos": [
- 631,
- 56
- ],
- "size": {
- "0": 210,
- "1": 46
- },
- "flags": {},
- "order": 8,
- "mode": 0,
- "inputs": [
- {
- "name": "samples",
- "type": "LATENT",
- "link": 76
- },
- {
- "name": "vae",
- "type": "VAE",
- "link": 59
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 60,
- 64,
- 105
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "VAEDecode"
- },
- "color": "#322",
- "bgcolor": "#533"
- },
- {
- "id": 25,
- "type": "PreviewImage",
- "pos": [
- 1473.8799991035464,
- 187.43994018554685
- ],
- "size": {
- "0": 140,
- "1": 215.40391540527344
- },
- "flags": {},
- "order": 22,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 121
- }
- ],
- "title": "Refined Masked",
- "properties": {
- "Node name for S&R": "PreviewImage"
- },
- "color": "#432",
- "bgcolor": "#653"
- },
- {
- "id": 40,
- "type": "Reroute",
- "pos": [
- 987,
- -6
- ],
- "size": [
- 82,
- 26
- ],
- "flags": {},
- "order": 11,
- "mode": 0,
- "inputs": [
- {
- "name": "",
- "type": "*",
- "link": 126
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 107,
- 108,
- 122,
- 124
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "showOutputText": true,
- "horizontal": false
- }
- },
- {
- "id": 39,
- "type": "Reroute",
- "pos": [
- 853,
- -6
- ],
- "size": [
- 82,
- 26
- ],
- "flags": {},
- "order": 10,
- "mode": 0,
- "inputs": [
- {
- "name": "",
- "type": "*",
- "link": 105
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 126
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "showOutputText": true,
- "horizontal": false
- }
- },
- {
- "id": 21,
- "type": "PreviewImage",
- "pos": [
- 1159,
- 472
- ],
- "size": {
- "0": 166.99998474121094,
- "1": 174.00001525878906
- },
- "flags": {},
- "order": 24,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 29
- }
- ],
- "title": "Cropped",
- "properties": {
- "Node name for S&R": "PreviewImage"
- },
- "color": "#223",
- "bgcolor": "#335"
- },
- {
- "id": 4,
- "type": "VAEEncodeForInpaint",
- "pos": [
- 1084,
- 246
- ],
- "size": {
- "0": 226.8000030517578,
- "1": 66
- },
- "flags": {},
- "order": 13,
- "mode": 0,
- "inputs": [
- {
- "name": "pixels",
- "type": "IMAGE",
- "link": 108
- },
- {
- "name": "vae",
- "type": "VAE",
- "link": 47
- },
- {
- "name": "mask",
- "type": "MASK",
- "link": 62
- }
- ],
- "outputs": [
- {
- "name": "LATENT",
- "type": "LATENT",
- "links": [
- 111
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "VAEEncodeForInpaint"
- },
- "color": "#432",
- "bgcolor": "#653"
- },
- {
- "id": 37,
- "type": "KSampler",
- "pos": [
- 630,
- 142
- ],
- "size": {
- "0": 210,
- "1": 262
- },
- "flags": {},
- "order": 7,
- "mode": 0,
- "inputs": [
- {
- "name": "model",
- "type": "MODEL",
- "link": 75
- },
- {
- "name": "positive",
- "type": "CONDITIONING",
- "link": 73
- },
- {
- "name": "negative",
- "type": "CONDITIONING",
- "link": 74
- },
- {
- "name": "latent_image",
- "type": "LATENT",
- "link": 72
- }
- ],
- "outputs": [
- {
- "name": "LATENT",
- "type": "LATENT",
- "links": [
- 76
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "KSampler"
- },
- "widgets_values": [
- 825529567532934,
- "fixed",
- 20,
- 8,
- "euler",
- "karras",
- 1
- ],
- "color": "#322",
- "bgcolor": "#533"
- },
- {
- "id": 35,
- "type": "SaveImage",
- "pos": [
- 851,
- 56
- ],
- "size": {
- "0": 218.98423767089844,
- "1": 347.54986572265625
- },
- "flags": {},
- "order": 9,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 60
- }
- ],
- "title": "Original",
- "properties": {},
- "widgets_values": [
- "original"
- ],
- "color": "#322",
- "bgcolor": "#533"
- },
- {
- "id": 27,
- "type": "VAEEncodeForInpaint",
- "pos": [
- 1629,
- 188
- ],
- "size": {
- "0": 256,
- "1": 66
- },
- "flags": {},
- "order": 18,
- "mode": 0,
- "inputs": [
- {
- "name": "pixels",
- "type": "IMAGE",
- "link": 122
- },
- {
- "name": "vae",
- "type": "VAE",
- "link": 45
- },
- {
- "name": "mask",
- "type": "MASK",
- "link": 128
- }
- ],
- "outputs": [
- {
- "name": "LATENT",
- "type": "LATENT",
- "links": [
- 119
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "VAEEncodeForInpaint"
- },
- "color": "#232",
- "bgcolor": "#353"
- },
- {
- "id": 30,
- "type": "VAEDecode",
- "pos": [
- 1628,
- 352
- ],
- "size": {
- "0": 256.14373779296875,
- "1": 46
- },
- "flags": {},
- "order": 20,
- "mode": 0,
- "inputs": [
- {
- "name": "samples",
- "type": "LATENT",
- "link": 119
- },
- {
- "name": "vae",
- "type": "VAE",
- "link": 102
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 121
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "VAEDecode"
- },
- "color": "#232",
- "bgcolor": "#353"
- },
- {
- "id": 13,
- "type": "MaskToSEGS",
- "pos": [
- 1325,
- 54
- ],
- "size": {
- "0": 289.1943359375,
- "1": 87.74590301513672
- },
- "flags": {},
- "order": 14,
- "mode": 0,
- "inputs": [
- {
- "name": "mask",
- "type": "MASK",
- "link": 71
- }
- ],
- "outputs": [
- {
- "name": "SEGS",
- "type": "SEGS",
- "links": [
- 125
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "MaskToSEGS"
- },
- "widgets_values": [
- "False",
- 1.5
- ],
- "color": "#323",
- "bgcolor": "#535"
- },
- {
- "id": 9,
- "type": "SAMDetectorCombined",
- "pos": [
- 1343,
- 470
- ],
- "size": {
- "0": 255,
- "1": 218
- },
- "flags": {},
- "order": 16,
- "mode": 0,
- "inputs": [
- {
- "name": "sam_model",
- "type": "SAM_MODEL",
- "link": 10
- },
- {
- "name": "segs",
- "type": "SEGS",
- "link": 125
- },
- {
- "name": "image",
- "type": "IMAGE",
- "link": 124
- }
- ],
- "outputs": [
- {
- "name": "MASK",
- "type": "MASK",
- "links": [
- 128,
- 130
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "SAMDetectorCombined"
- },
- "widgets_values": [
- "mask-points",
- 0,
- 0.95,
- 1,
- 0.9,
- "True"
- ],
- "color": "#323",
- "bgcolor": "#535"
- },
- {
- "id": 41,
- "type": "MaskToSEGS",
- "pos": [
- 1346,
- 800
- ],
- "size": [
- 257.02474824258957,
- 82
- ],
- "flags": {},
- "order": 19,
- "mode": 0,
- "inputs": [
- {
- "name": "mask",
- "type": "MASK",
- "link": 130
- }
- ],
- "outputs": [
- {
- "name": "SEGS",
- "type": "SEGS",
- "links": [
- 134
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "MaskToSEGS"
- },
- "widgets_values": [
- "True",
- 1.5
- ]
- },
- {
- "id": 18,
- "type": "CheckpointLoaderSimple",
- "pos": [
- 34.87999910354617,
- 153.43994018554685
- ],
- "size": {
- "0": 248,
- "1": 98
- },
- "flags": {},
- "order": 2,
- "mode": 0,
- "outputs": [
- {
- "name": "MODEL",
- "type": "MODEL",
- "links": [
- 22,
- 75
- ],
- "slot_index": 0
- },
- {
- "name": "CLIP",
- "type": "CLIP",
- "links": [
- 24,
- 25,
- 103,
- 136
- ],
- "slot_index": 1
- },
- {
- "name": "VAE",
- "type": "VAE",
- "links": [
- 45,
- 47,
- 48,
- 49,
- 59,
- 102
- ],
- "slot_index": 2
- }
- ],
- "properties": {
- "Node name for S&R": "CheckpointLoaderSimple"
- },
- "widgets_values": [
- "V07_v07.safetensors"
- ],
- "color": "#222",
- "bgcolor": "#000"
- },
- {
- "id": 43,
- "type": "CLIPTextEncode",
- "pos": [
- 298,
- 633
- ],
- "size": [
- 309.78613677862666,
- 107.79468760871396
- ],
- "flags": {},
- "order": 6,
- "mode": 0,
- "inputs": [
- {
- "name": "clip",
- "type": "CLIP",
- "link": 136
- }
- ],
- "outputs": [
- {
- "name": "CONDITIONING",
- "type": "CONDITIONING",
- "links": [
- 135
- ],
- "slot_index": 0
- }
- ],
- "title": "Inpaint (Negative)",
- "properties": {
- "Node name for S&R": "CLIPTextEncode"
- },
- "widgets_values": [
- "loose, worst quality, low quality, nsfw, ripped"
- ],
- "color": "#223",
- "bgcolor": "#335"
- },
- {
- "id": 17,
- "type": "DetailerForEachDebug",
- "pos": [
- 633,
- 472
- ],
- "size": {
- "0": 210,
- "1": 418
- },
- "flags": {},
- "order": 21,
- "mode": 0,
- "inputs": [
- {
- "name": "image",
- "type": "IMAGE",
- "link": 64
- },
- {
- "name": "segs",
- "type": "SEGS",
- "link": 134
- },
- {
- "name": "model",
- "type": "MODEL",
- "link": 22
- },
- {
- "name": "vae",
- "type": "VAE",
- "link": 49
- },
- {
- "name": "positive",
- "type": "CONDITIONING",
- "link": 104
- },
- {
- "name": "negative",
- "type": "CONDITIONING",
- "link": 135
- },
- {
- "name": "external_seed",
- "type": "SEED",
- "link": null
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 28
- ],
- "slot_index": 0
- },
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 29
- ],
- "slot_index": 1
- },
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 30
- ],
- "slot_index": 2
- }
- ],
- "properties": {
- "Node name for S&R": "DetailerForEachDebug"
- },
- "widgets_values": [
- 384,
- "bbox",
- 941020320887530,
- "fixed",
- 20,
- 10,
- "euler",
- "karras",
- 0.65,
- 2,
- "enabled"
- ],
- "color": "#223",
- "bgcolor": "#335"
- },
- {
- "id": 22,
- "type": "PreviewImage",
- "pos": [
- 1159,
- 694
- ],
- "size": {
- "0": 169.68492126464844,
- "1": 193.83172607421875
- },
- "flags": {},
- "order": 25,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 30
- }
- ],
- "title": "Refined Crop",
- "properties": {
- "Node name for S&R": "PreviewImage"
- },
- "color": "#223",
- "bgcolor": "#335"
- },
- {
- "id": 23,
- "type": "SaveImage",
- "pos": [
- 859,
- 472
- ],
- "size": [
- 288.1493981823646,
- 419.0925415333859
- ],
- "flags": {},
- "order": 23,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 28
- }
- ],
- "title": "Result",
- "properties": {},
- "widgets_values": [
- "Result"
- ],
- "color": "#223",
- "bgcolor": "#335"
- },
- {
- "id": 36,
- "type": "MaskPainter",
- "pos": [
- 1081,
- 55
- ],
- "size": {
- "0": 228.4941864013672,
- "1": 145.6903076171875
- },
- "flags": {},
- "order": 12,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 107
- },
- {
- "name": "mask_image",
- "type": "IMAGE_PATH",
- "link": null
- }
- ],
- "outputs": [
- {
- "name": "MASK",
- "type": "MASK",
- "links": [
- 62,
- 71
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "MaskPainter"
- },
- "widgets_values": [
- null,
- {
- "filename": "impact-mask-1413400.4000000004.png",
- "subfolder": "",
- "type": "temp"
- }
- ],
- "color": "#432",
- "bgcolor": "#653"
- }
- ],
- "links": [
- [
- 10,
- 10,
- 0,
- 9,
- 0,
- "SAM_MODEL"
- ],
- [
- 22,
- 18,
- 0,
- 17,
- 2,
- "MODEL"
- ],
- [
- 24,
- 18,
- 1,
- 20,
- 0,
- "CLIP"
- ],
- [
- 25,
- 18,
- 1,
- 19,
- 0,
- "CLIP"
- ],
- [
- 28,
- 17,
- 0,
- 23,
- 0,
- "IMAGE"
- ],
- [
- 29,
- 17,
- 1,
- 21,
- 0,
- "IMAGE"
- ],
- [
- 30,
- 17,
- 2,
- 22,
- 0,
- "IMAGE"
- ],
- [
- 45,
- 18,
- 2,
- 27,
- 1,
- "VAE"
- ],
- [
- 47,
- 18,
- 2,
- 4,
- 1,
- "VAE"
- ],
- [
- 48,
- 18,
- 2,
- 6,
- 1,
- "VAE"
- ],
- [
- 49,
- 18,
- 2,
- 17,
- 3,
- "VAE"
- ],
- [
- 59,
- 18,
- 2,
- 34,
- 1,
- "VAE"
- ],
- [
- 60,
- 34,
- 0,
- 35,
- 0,
- "IMAGE"
- ],
- [
- 62,
- 36,
- 0,
- 4,
- 2,
- "MASK"
- ],
- [
- 64,
- 34,
- 0,
- 17,
- 0,
- "IMAGE"
- ],
- [
- 71,
- 36,
- 0,
- 13,
- 0,
- "MASK"
- ],
- [
- 72,
- 33,
- 0,
- 37,
- 3,
- "LATENT"
- ],
- [
- 73,
- 20,
- 0,
- 37,
- 1,
- "CONDITIONING"
- ],
- [
- 74,
- 19,
- 0,
- 37,
- 2,
- "CONDITIONING"
- ],
- [
- 75,
- 18,
- 0,
- 37,
- 0,
- "MODEL"
- ],
- [
- 76,
- 37,
- 0,
- 34,
- 0,
- "LATENT"
- ],
- [
- 102,
- 18,
- 2,
- 30,
- 1,
- "VAE"
- ],
- [
- 103,
- 18,
- 1,
- 38,
- 0,
- "CLIP"
- ],
- [
- 104,
- 38,
- 0,
- 17,
- 4,
- "CONDITIONING"
- ],
- [
- 105,
- 34,
- 0,
- 39,
- 0,
- "*"
- ],
- [
- 107,
- 40,
- 0,
- 36,
- 0,
- "IMAGE"
- ],
- [
- 108,
- 40,
- 0,
- 4,
- 0,
- "IMAGE"
- ],
- [
- 110,
- 6,
- 0,
- 7,
- 0,
- "IMAGE"
- ],
- [
- 111,
- 4,
- 0,
- 6,
- 0,
- "LATENT"
- ],
- [
- 119,
- 27,
- 0,
- 30,
- 0,
- "LATENT"
- ],
- [
- 121,
- 30,
- 0,
- 25,
- 0,
- "IMAGE"
- ],
- [
- 122,
- 40,
- 0,
- 27,
- 0,
- "IMAGE"
- ],
- [
- 124,
- 40,
- 0,
- 9,
- 2,
- "IMAGE"
- ],
- [
- 125,
- 13,
- 0,
- 9,
- 1,
- "SEGS"
- ],
- [
- 126,
- 39,
- 0,
- 40,
- 0,
- "*"
- ],
- [
- 128,
- 9,
- 0,
- 27,
- 2,
- "MASK"
- ],
- [
- 130,
- 9,
- 0,
- 41,
- 0,
- "MASK"
- ],
- [
- 134,
- 41,
- 0,
- 17,
- 1,
- "SEGS"
- ],
- [
- 135,
- 43,
- 0,
- 17,
- 5,
- "CONDITIONING"
- ],
- [
- 136,
- 18,
- 1,
- 43,
- 0,
- "CLIP"
- ]
- ],
- "groups": [],
- "config": {},
- "extra": {},
- "version": 0.4
-}
\ No newline at end of file
diff --git a/misc/onnx.json b/misc/onnx.json
deleted file mode 100644
index ef681e5b..00000000
--- a/misc/onnx.json
+++ /dev/null
@@ -1,405 +0,0 @@
-{
- "last_node_id": 13,
- "last_link_id": 15,
- "nodes": [
- {
- "id": 8,
- "type": "VAEDecode",
- "pos": [
- 1191,
- 203
- ],
- "size": {
- "0": 210,
- "1": 46
- },
- "flags": {},
- "order": 6,
- "mode": 0,
- "inputs": [
- {
- "name": "samples",
- "type": "LATENT",
- "link": 9
- },
- {
- "name": "vae",
- "type": "VAE",
- "link": 10
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 11
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "VAE Decode"
- },
- "color": "#223",
- "bgcolor": "#335"
- },
- {
- "id": 2,
- "type": "LoadImage",
- "pos": [
- 57,
- 322
- ],
- "size": {
- "0": 314,
- "1": 102
- },
- "flags": {},
- "order": 0,
- "mode": 0,
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 4,
- 7,
- 14
- ],
- "slot_index": 0
- },
- {
- "name": "MASK",
- "type": "MASK",
- "links": null
- }
- ],
- "properties": {
- "Node name for S&R": "Load Image"
- },
- "widgets_values": [
- "rga6845.jpeg",
- "image"
- ],
- "color": "#222",
- "bgcolor": "#000"
- },
- {
- "id": 6,
- "type": "VAEEncodeForInpaint",
- "pos": [
- 942,
- 201
- ],
- "size": {
- "0": 226.8000030517578,
- "1": 66
- },
- "flags": {},
- "order": 5,
- "mode": 0,
- "inputs": [
- {
- "name": "pixels",
- "type": "IMAGE",
- "link": 7
- },
- {
- "name": "vae",
- "type": "VAE",
- "link": 8
- },
- {
- "name": "mask",
- "type": "MASK",
- "link": 6
- }
- ],
- "outputs": [
- {
- "name": "LATENT",
- "type": "LATENT",
- "links": [
- 9
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "VAE Encode (for Inpainting)"
- },
- "color": "#223",
- "bgcolor": "#335"
- },
- {
- "id": 7,
- "type": "VAELoader",
- "pos": [
- 56,
- 96
- ],
- "size": {
- "0": 315,
- "1": 58
- },
- "flags": {},
- "order": 1,
- "mode": 0,
- "outputs": [
- {
- "name": "VAE",
- "type": "VAE",
- "links": [
- 8,
- 10
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "Load VAE"
- },
- "widgets_values": [
- "vae-ft-mse-840000-ema-pruned.safetensors"
- ],
- "color": "#222",
- "bgcolor": "#000"
- },
- {
- "id": 5,
- "type": "SegsMaskCombine",
- "pos": [
- 681,
- 369
- ],
- "size": {
- "0": 210,
- "1": 46
- },
- "flags": {},
- "order": 4,
- "mode": 0,
- "inputs": [
- {
- "name": "segs",
- "type": "SEGS",
- "link": 15
- },
- {
- "name": "image",
- "type": "IMAGE",
- "link": 4
- }
- ],
- "outputs": [
- {
- "name": "MASK",
- "type": "MASK",
- "links": [
- 6
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "SegsMaskCombine"
- },
- "color": "#322",
- "bgcolor": "#533"
- },
- {
- "id": 9,
- "type": "SaveImage",
- "pos": [
- 1476,
- 205
- ],
- "size": {
- "0": 475,
- "1": 543
- },
- "flags": {},
- "order": 7,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 11
- }
- ],
- "properties": {},
- "widgets_values": [
- "ComfyUI"
- ],
- "color": "#223",
- "bgcolor": "#335"
- },
- {
- "id": 13,
- "type": "ONNXDetectorForEach",
- "pos": [
- 405,
- 209
- ],
- "size": {
- "0": 210,
- "1": 102
- },
- "flags": {},
- "order": 3,
- "mode": 0,
- "inputs": [
- {
- "name": "onnx_model",
- "type": "ONNX_MODEL",
- "link": 13
- },
- {
- "name": "image",
- "type": "IMAGE",
- "link": 14
- }
- ],
- "outputs": [
- {
- "name": "SEGS",
- "type": "SEGS",
- "links": [
- 15
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "ONNXDetectorForEach"
- },
- "widgets_values": [
- 0.5,
- 2
- ],
- "color": "#322",
- "bgcolor": "#533"
- },
- {
- "id": 1,
- "type": "ONNXLoader",
- "pos": [
- 55,
- 207
- ],
- "size": {
- "0": 315,
- "1": 58
- },
- "flags": {},
- "order": 2,
- "mode": 0,
- "outputs": [
- {
- "name": "ONNX_MODEL",
- "type": "ONNX_MODEL",
- "links": [
- 13
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "ONNXLoader"
- },
- "widgets_values": [
- "detector_v2_base_checkpoint.onnx"
- ],
- "color": "#222",
- "bgcolor": "#000"
- }
- ],
- "links": [
- [
- 4,
- 2,
- 0,
- 5,
- 1,
- "IMAGE"
- ],
- [
- 6,
- 5,
- 0,
- 6,
- 2,
- "MASK"
- ],
- [
- 7,
- 2,
- 0,
- 6,
- 0,
- "IMAGE"
- ],
- [
- 8,
- 7,
- 0,
- 6,
- 1,
- "VAE"
- ],
- [
- 9,
- 6,
- 0,
- 8,
- 0,
- "LATENT"
- ],
- [
- 10,
- 7,
- 0,
- 8,
- 1,
- "VAE"
- ],
- [
- 11,
- 8,
- 0,
- 9,
- 0,
- "IMAGE"
- ],
- [
- 13,
- 1,
- 0,
- 13,
- 0,
- "ONNX_MODEL"
- ],
- [
- 14,
- 2,
- 0,
- 13,
- 1,
- "IMAGE"
- ],
- [
- 15,
- 13,
- 0,
- 5,
- 0,
- "SEGS"
- ]
- ],
- "groups": [],
- "config": {},
- "extra": {},
- "version": 0.4
-}
\ No newline at end of file
diff --git a/misc/sam-masked.png b/misc/sam-masked.png
deleted file mode 100644
index 70389675..00000000
Binary files a/misc/sam-masked.png and /dev/null differ
diff --git a/misc/sam-original.png b/misc/sam-original.png
deleted file mode 100644
index e18db264..00000000
Binary files a/misc/sam-original.png and /dev/null differ
diff --git a/misc/sam-result.png b/misc/sam-result.png
deleted file mode 100644
index a7487552..00000000
Binary files a/misc/sam-result.png and /dev/null differ
diff --git a/misc/sam.json b/misc/sam.json
deleted file mode 100644
index 3f1eb7da..00000000
--- a/misc/sam.json
+++ /dev/null
@@ -1,1150 +0,0 @@
-{
- "last_node_id": 32,
- "last_link_id": 57,
- "nodes": [
- {
- "id": 7,
- "type": "PreviewImage",
- "pos": [
- 921,
- 431
- ],
- "size": {
- "0": 140,
- "1": 230
- },
- "flags": {},
- "order": 11,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 7
- }
- ],
- "title": "Masked",
- "properties": {
- "Node name for S&R": "PreviewImage"
- },
- "color": "#2a363b",
- "bgcolor": "#3f5159"
- },
- {
- "id": 10,
- "type": "SAMLoader",
- "pos": [
- 135,
- 335
- ],
- "size": {
- "0": 249,
- "1": 60
- },
- "flags": {},
- "order": 0,
- "mode": 0,
- "outputs": [
- {
- "name": "SAM_MODEL",
- "type": "SAM_MODEL",
- "links": [
- 10
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "SAMLoader"
- },
- "widgets_values": [
- "sam_vit_b_01ec64.pth"
- ],
- "color": "#222",
- "bgcolor": "#000"
- },
- {
- "id": 18,
- "type": "CheckpointLoaderSimple",
- "pos": [
- 136,
- 180
- ],
- "size": {
- "0": 248,
- "1": 98
- },
- "flags": {},
- "order": 1,
- "mode": 0,
- "outputs": [
- {
- "name": "MODEL",
- "type": "MODEL",
- "links": [
- 22
- ],
- "slot_index": 0
- },
- {
- "name": "CLIP",
- "type": "CLIP",
- "links": [
- 24,
- 25
- ],
- "slot_index": 1
- },
- {
- "name": "VAE",
- "type": "VAE",
- "links": [
- 45,
- 46,
- 47,
- 48,
- 49
- ],
- "slot_index": 2
- }
- ],
- "properties": {
- "Node name for S&R": "CheckpointLoaderSimple"
- },
- "widgets_values": [
- "V07_v07.safetensors"
- ],
- "color": "#222",
- "bgcolor": "#000"
- },
- {
- "id": 25,
- "type": "PreviewImage",
- "pos": [
- 1097,
- 365
- ],
- "size": {
- "0": 211,
- "1": 294
- },
- "flags": {},
- "order": 20,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 44
- }
- ],
- "title": "Refined Masked",
- "properties": {
- "Node name for S&R": "PreviewImage"
- },
- "color": "#232",
- "bgcolor": "#353"
- },
- {
- "id": 27,
- "type": "VAEEncodeForInpaint",
- "pos": [
- 1332,
- 515
- ],
- "size": {
- "0": 226.8000030517578,
- "1": 66
- },
- "flags": {},
- "order": 18,
- "mode": 0,
- "inputs": [
- {
- "name": "pixels",
- "type": "IMAGE",
- "link": 52
- },
- {
- "name": "vae",
- "type": "VAE",
- "link": 45
- },
- {
- "name": "mask",
- "type": "MASK",
- "link": 56
- }
- ],
- "outputs": [
- {
- "name": "LATENT",
- "type": "LATENT",
- "links": [
- 42
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "VAEEncodeForInpaint"
- },
- "color": "#232",
- "bgcolor": "#353"
- },
- {
- "id": 13,
- "type": "MaskToSEGS",
- "pos": [
- 1096,
- 245
- ],
- "size": {
- "0": 210,
- "1": 82
- },
- "flags": {},
- "order": 8,
- "mode": 0,
- "inputs": [
- {
- "name": "mask",
- "type": "MASK",
- "link": 57
- }
- ],
- "outputs": [
- {
- "name": "SEGS",
- "type": "SEGS",
- "links": [
- 12,
- 18
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "MaskToSEGS"
- },
- "widgets_values": [
- "True",
- 3
- ],
- "color": "#232",
- "bgcolor": "#353"
- },
- {
- "id": 2,
- "type": "LoadImage",
- "pos": [
- 401,
- 177
- ],
- "size": {
- "0": 254,
- "1": 480
- },
- "flags": {},
- "order": 2,
- "mode": 0,
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 1,
- 2,
- 38,
- 50,
- 51,
- 52
- ],
- "slot_index": 0
- },
- {
- "name": "MASK",
- "type": "MASK",
- "links": [
- 8
- ],
- "slot_index": 1
- }
- ],
- "properties": {
- "Node name for S&R": "LoadImage"
- },
- "widgets_values": [
- "alpha3.png",
- "image"
- ],
- "color": "#222",
- "bgcolor": "#000"
- },
- {
- "id": 4,
- "type": "VAEEncodeForInpaint",
- "pos": [
- 677,
- 438
- ],
- "size": {
- "0": 226.8000030517578,
- "1": 66
- },
- "flags": {},
- "order": 7,
- "mode": 0,
- "inputs": [
- {
- "name": "pixels",
- "type": "IMAGE",
- "link": 2
- },
- {
- "name": "vae",
- "type": "VAE",
- "link": 47
- },
- {
- "name": "mask",
- "type": "MASK",
- "link": 9
- }
- ],
- "outputs": [
- {
- "name": "LATENT",
- "type": "LATENT",
- "links": [
- 5
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "VAEEncodeForInpaint"
- },
- "color": "#2a363b",
- "bgcolor": "#3f5159"
- },
- {
- "id": 6,
- "type": "VAEDecode",
- "pos": [
- 677,
- 602
- ],
- "size": {
- "0": 228,
- "1": 46
- },
- "flags": {},
- "order": 9,
- "mode": 0,
- "inputs": [
- {
- "name": "samples",
- "type": "LATENT",
- "link": 5
- },
- {
- "name": "vae",
- "type": "VAE",
- "link": 48
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 7
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "VAEDecode"
- },
- "color": "#2a363b",
- "bgcolor": "#3f5159"
- },
- {
- "id": 3,
- "type": "PreviewImage",
- "pos": [
- 919,
- 176
- ],
- "size": {
- "0": 140,
- "1": 213
- },
- "flags": {},
- "order": 5,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 1
- }
- ],
- "title": "No Alpha",
- "properties": {
- "Node name for S&R": "PreviewImage"
- },
- "color": "#222",
- "bgcolor": "#000"
- },
- {
- "id": 30,
- "type": "VAEDecode",
- "pos": [
- 1333,
- 615
- ],
- "size": {
- "0": 227.90530395507812,
- "1": 46
- },
- "flags": {},
- "order": 19,
- "mode": 0,
- "inputs": [
- {
- "name": "samples",
- "type": "LATENT",
- "link": 42
- },
- {
- "name": "vae",
- "type": "VAE",
- "link": 46
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 44
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "VAEDecode"
- },
- "color": "#232",
- "bgcolor": "#353"
- },
- {
- "id": 28,
- "type": "SegsMaskCombine",
- "pos": [
- 1333,
- 435
- ],
- "size": {
- "0": 225.70559692382812,
- "1": 46
- },
- "flags": {},
- "order": 14,
- "mode": 0,
- "inputs": [
- {
- "name": "segs",
- "type": "SEGS",
- "link": 39
- },
- {
- "name": "image",
- "type": "IMAGE",
- "link": 38
- }
- ],
- "outputs": [
- {
- "name": "MASK",
- "type": "MASK",
- "links": [
- 56
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "SegsMaskCombine"
- },
- "color": "#232",
- "bgcolor": "#353"
- },
- {
- "id": 16,
- "type": "Segs & Mask",
- "pos": [
- 1331,
- 356
- ],
- "size": {
- "0": 226.6055908203125,
- "1": 46
- },
- "flags": {},
- "order": 12,
- "mode": 0,
- "inputs": [
- {
- "name": "segs",
- "type": "SEGS",
- "link": 18
- },
- {
- "name": "mask",
- "type": "MASK",
- "link": 19
- }
- ],
- "outputs": [
- {
- "name": "SEGS",
- "type": "SEGS",
- "links": [
- 20,
- 39
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "Segs & Mask"
- },
- "color": "#232",
- "bgcolor": "#353"
- },
- {
- "id": 9,
- "type": "SAMDetectorCombined",
- "pos": [
- 1332,
- 165
- ],
- "size": {
- "0": 225.6055908203125,
- "1": 150.59918212890625
- },
- "flags": {},
- "order": 10,
- "mode": 0,
- "inputs": [
- {
- "name": "sam_model",
- "type": "SAM_MODEL",
- "link": 10
- },
- {
- "name": "segs",
- "type": "SEGS",
- "link": 12
- },
- {
- "name": "image",
- "type": "IMAGE",
- "link": 51
- }
- ],
- "outputs": [
- {
- "name": "MASK",
- "type": "MASK",
- "links": [
- 19
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "SAMDetectorCombined"
- },
- "widgets_values": [
- "none",
- 0.93,
- 0.93
- ],
- "color": "#232",
- "bgcolor": "#353"
- },
- {
- "id": 8,
- "type": "ToBinaryMask",
- "pos": [
- 1093,
- 171
- ],
- "size": {
- "0": 214.5975799560547,
- "1": 26
- },
- "flags": {},
- "order": 6,
- "mode": 0,
- "inputs": [
- {
- "name": "mask",
- "type": "MASK",
- "link": 8
- }
- ],
- "outputs": [
- {
- "name": "MASK",
- "type": "MASK",
- "links": [
- 9,
- 57
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "ToBinaryMask"
- },
- "color": "#232",
- "bgcolor": "#353"
- },
- {
- "id": 20,
- "type": "CLIPTextEncode",
- "pos": [
- 134,
- 736
- ],
- "size": {
- "0": 239.99998474121094,
- "1": 192.00001525878906
- },
- "flags": {},
- "order": 3,
- "mode": 0,
- "inputs": [
- {
- "name": "clip",
- "type": "CLIP",
- "link": 24
- }
- ],
- "outputs": [
- {
- "name": "CONDITIONING",
- "type": "CONDITIONING",
- "links": [
- 27
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "CLIPTextEncode"
- },
- "widgets_values": [
- "1girl, (silver:1.4) short pants"
- ],
- "color": "#223",
- "bgcolor": "#335"
- },
- {
- "id": 21,
- "type": "PreviewImage",
- "pos": [
- 729,
- 741
- ],
- "size": {
- "0": 166.99998474121094,
- "1": 174.00001525878906
- },
- "flags": {},
- "order": 16,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 29
- }
- ],
- "title": "Cropped",
- "properties": {
- "Node name for S&R": "PreviewImage"
- },
- "color": "#223",
- "bgcolor": "#335"
- },
- {
- "id": 22,
- "type": "PreviewImage",
- "pos": [
- 729,
- 959
- ],
- "size": {
- "0": 164.99998474121094,
- "1": 197.00001525878906
- },
- "flags": {},
- "order": 17,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 30
- }
- ],
- "title": "Refined Crop",
- "properties": {
- "Node name for S&R": "PreviewImage"
- },
- "color": "#223",
- "bgcolor": "#335"
- },
- {
- "id": 23,
- "type": "SaveImage",
- "pos": [
- 911,
- 740
- ],
- "size": {
- "0": 289,
- "1": 415
- },
- "flags": {},
- "order": 15,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 28
- }
- ],
- "title": "Result",
- "properties": {},
- "widgets_values": [
- "ComfyUI"
- ],
- "color": "#223",
- "bgcolor": "#335"
- },
- {
- "id": 19,
- "type": "CLIPTextEncode",
- "pos": [
- 135,
- 971
- ],
- "size": {
- "0": 234.99998474121094,
- "1": 185.00001525878906
- },
- "flags": {},
- "order": 4,
- "mode": 0,
- "inputs": [
- {
- "name": "clip",
- "type": "CLIP",
- "link": 25
- }
- ],
- "outputs": [
- {
- "name": "CONDITIONING",
- "type": "CONDITIONING",
- "links": [
- 26
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "CLIPTextEncode"
- },
- "widgets_values": [
- "jeans, ((black)), ((blue))"
- ],
- "color": "#223",
- "bgcolor": "#335"
- },
- {
- "id": 17,
- "type": "DetailerForEachDebug",
- "pos": [
- 402,
- 739
- ],
- "size": {
- "0": 315,
- "1": 418
- },
- "flags": {},
- "order": 13,
- "mode": 0,
- "inputs": [
- {
- "name": "image",
- "type": "IMAGE",
- "link": 50
- },
- {
- "name": "segs",
- "type": "SEGS",
- "link": 20
- },
- {
- "name": "model",
- "type": "MODEL",
- "link": 22
- },
- {
- "name": "vae",
- "type": "VAE",
- "link": 49
- },
- {
- "name": "positive",
- "type": "CONDITIONING",
- "link": 27
- },
- {
- "name": "negative",
- "type": "CONDITIONING",
- "link": 26
- },
- {
- "name": "external_seed",
- "type": "SEED",
- "link": null
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 28
- ],
- "slot_index": 0
- },
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 29
- ],
- "slot_index": 1
- },
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 30
- ],
- "slot_index": 2
- }
- ],
- "properties": {
- "Node name for S&R": "DetailerForEachDebug"
- },
- "widgets_values": [
- 192,
- "bbox",
- 991944171351598,
- "randomize",
- 20,
- 10,
- "euler",
- "karras",
- 0.6,
- 3,
- "enabled"
- ],
- "color": "#223",
- "bgcolor": "#335"
- }
- ],
- "links": [
- [
- 1,
- 2,
- 0,
- 3,
- 0,
- "IMAGE"
- ],
- [
- 2,
- 2,
- 0,
- 4,
- 0,
- "IMAGE"
- ],
- [
- 5,
- 4,
- 0,
- 6,
- 0,
- "LATENT"
- ],
- [
- 7,
- 6,
- 0,
- 7,
- 0,
- "IMAGE"
- ],
- [
- 8,
- 2,
- 1,
- 8,
- 0,
- "MASK"
- ],
- [
- 9,
- 8,
- 0,
- 4,
- 2,
- "MASK"
- ],
- [
- 10,
- 10,
- 0,
- 9,
- 0,
- "SAM_MODEL"
- ],
- [
- 12,
- 13,
- 0,
- 9,
- 1,
- "SEGS"
- ],
- [
- 18,
- 13,
- 0,
- 16,
- 0,
- "SEGS"
- ],
- [
- 19,
- 9,
- 0,
- 16,
- 1,
- "MASK"
- ],
- [
- 20,
- 16,
- 0,
- 17,
- 1,
- "SEGS"
- ],
- [
- 22,
- 18,
- 0,
- 17,
- 2,
- "MODEL"
- ],
- [
- 24,
- 18,
- 1,
- 20,
- 0,
- "CLIP"
- ],
- [
- 25,
- 18,
- 1,
- 19,
- 0,
- "CLIP"
- ],
- [
- 26,
- 19,
- 0,
- 17,
- 5,
- "CONDITIONING"
- ],
- [
- 27,
- 20,
- 0,
- 17,
- 4,
- "CONDITIONING"
- ],
- [
- 28,
- 17,
- 0,
- 23,
- 0,
- "IMAGE"
- ],
- [
- 29,
- 17,
- 1,
- 21,
- 0,
- "IMAGE"
- ],
- [
- 30,
- 17,
- 2,
- 22,
- 0,
- "IMAGE"
- ],
- [
- 38,
- 2,
- 0,
- 28,
- 1,
- "IMAGE"
- ],
- [
- 39,
- 16,
- 0,
- 28,
- 0,
- "SEGS"
- ],
- [
- 42,
- 27,
- 0,
- 30,
- 0,
- "LATENT"
- ],
- [
- 44,
- 30,
- 0,
- 25,
- 0,
- "IMAGE"
- ],
- [
- 45,
- 18,
- 2,
- 27,
- 1,
- "VAE"
- ],
- [
- 46,
- 18,
- 2,
- 30,
- 1,
- "VAE"
- ],
- [
- 47,
- 18,
- 2,
- 4,
- 1,
- "VAE"
- ],
- [
- 48,
- 18,
- 2,
- 6,
- 1,
- "VAE"
- ],
- [
- 49,
- 18,
- 2,
- 17,
- 3,
- "VAE"
- ],
- [
- 50,
- 2,
- 0,
- 17,
- 0,
- "IMAGE"
- ],
- [
- 51,
- 2,
- 0,
- 9,
- 2,
- "IMAGE"
- ],
- [
- 52,
- 2,
- 0,
- 27,
- 0,
- "IMAGE"
- ],
- [
- 56,
- 28,
- 0,
- 27,
- 2,
- "MASK"
- ],
- [
- 57,
- 8,
- 0,
- 13,
- 0,
- "MASK"
- ]
- ],
- "groups": [],
- "config": {},
- "extra": {},
- "version": 0.4
-}
\ No newline at end of file
diff --git a/misc/sam.png b/misc/sam.png
deleted file mode 100644
index 0ab4d820..00000000
Binary files a/misc/sam.png and /dev/null differ
diff --git a/misc/simple-original.png b/misc/simple-original.png
deleted file mode 100644
index 535127a4..00000000
Binary files a/misc/simple-original.png and /dev/null differ
diff --git a/misc/simple-refined.png b/misc/simple-refined.png
deleted file mode 100644
index 5ab936c4..00000000
Binary files a/misc/simple-refined.png and /dev/null differ
diff --git a/misc/simple.json b/misc/simple.json
deleted file mode 100644
index a04497d7..00000000
--- a/misc/simple.json
+++ /dev/null
@@ -1,1089 +0,0 @@
-{
- "last_node_id": 40,
- "last_link_id": 94,
- "nodes": [
- {
- "id": 35,
- "type": "Reroute",
- "pos": [
- 1040,
- 30
- ],
- "size": [
- 75,
- 26
- ],
- "flags": {},
- "order": 10,
- "mode": 0,
- "inputs": [
- {
- "name": "",
- "type": "*",
- "link": 74
- }
- ],
- "outputs": [
- {
- "name": "VAE",
- "type": "VAE",
- "links": [
- 75
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "showOutputText": true,
- "horizontal": false
- }
- },
- {
- "id": 6,
- "type": "CLIPTextEncode",
- "pos": [
- 150,
- 630
- ],
- "size": [
- 314.69028226994214,
- 84.15735061897692
- ],
- "flags": {},
- "order": 9,
- "mode": 0,
- "inputs": [
- {
- "name": "clip",
- "type": "CLIP",
- "link": 92
- }
- ],
- "outputs": [
- {
- "name": "CONDITIONING",
- "type": "CONDITIONING",
- "links": [
- 49,
- 58
- ],
- "slot_index": 0
- }
- ],
- "title": "Negative",
- "properties": {
- "Node name for S&R": "CLIPTextEncode"
- },
- "widgets_values": [
- "low quality, worst quality, bad anatomy"
- ],
- "color": "#322",
- "bgcolor": "#533"
- },
- {
- "id": 31,
- "type": "Reroute",
- "pos": [
- 430,
- 80
- ],
- "size": [
- 82,
- 26
- ],
- "flags": {},
- "order": 4,
- "mode": 0,
- "inputs": [
- {
- "name": "",
- "type": "*",
- "link": 64
- }
- ],
- "outputs": [
- {
- "name": "MODEL",
- "type": "MODEL",
- "links": [
- 65,
- 69
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "showOutputText": true,
- "horizontal": false
- }
- },
- {
- "id": 16,
- "type": "SAMLoader",
- "pos": [
- 500,
- 350
- ],
- "size": {
- "0": 314,
- "1": 66
- },
- "flags": {},
- "order": 0,
- "mode": 0,
- "outputs": [
- {
- "name": "SAM_MODEL",
- "type": "SAM_MODEL",
- "links": [
- 55
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "SAMLoader"
- },
- "widgets_values": [
- "sam_vit_b_01ec64.pth"
- ],
- "color": "#223",
- "bgcolor": "#335"
- },
- {
- "id": 28,
- "type": "KSampler",
- "pos": [
- 500,
- 620
- ],
- "size": {
- "0": 315,
- "1": 262
- },
- "flags": {},
- "order": 11,
- "mode": 0,
- "inputs": [
- {
- "name": "model",
- "type": "MODEL",
- "link": 65
- },
- {
- "name": "positive",
- "type": "CONDITIONING",
- "link": 57
- },
- {
- "name": "negative",
- "type": "CONDITIONING",
- "link": 58
- },
- {
- "name": "latent_image",
- "type": "LATENT",
- "link": 59,
- "slot_index": 3
- }
- ],
- "outputs": [
- {
- "name": "LATENT",
- "type": "LATENT",
- "links": [
- 60
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "KSampler"
- },
- "widgets_values": [
- 431433362471132,
- "fixed",
- 20,
- 8,
- "euler",
- "karras",
- 1
- ],
- "color": "#322",
- "bgcolor": "#533"
- },
- {
- "id": 5,
- "type": "CLIPTextEncode",
- "pos": [
- 150,
- 470
- ],
- "size": [
- 315.996067393909,
- 97.04991260244805
- ],
- "flags": {},
- "order": 8,
- "mode": 0,
- "inputs": [
- {
- "name": "clip",
- "type": "CLIP",
- "link": 91
- }
- ],
- "outputs": [
- {
- "name": "CONDITIONING",
- "type": "CONDITIONING",
- "links": [
- 48,
- 57
- ],
- "slot_index": 0
- }
- ],
- "title": "Positive",
- "properties": {
- "Node name for S&R": "CLIPTextEncode"
- },
- "widgets_values": [
- "1girl, photorealistic:1.4, best quality, masterpiece, walk, full shot, white uniform, perfect anatomy, short skirt"
- ],
- "color": "#322",
- "bgcolor": "#533"
- },
- {
- "id": 29,
- "type": "EmptyLatentImage",
- "pos": [
- 150,
- 770
- ],
- "size": [
- 315.5925459428262,
- 114.21137861771979
- ],
- "flags": {},
- "order": 1,
- "mode": 0,
- "outputs": [
- {
- "name": "LATENT",
- "type": "LATENT",
- "links": [
- 59
- ]
- }
- ],
- "properties": {
- "Node name for S&R": "EmptyLatentImage"
- },
- "widgets_values": [
- 256,
- 512,
- 1
- ],
- "color": "#322",
- "bgcolor": "#533"
- },
- {
- "id": 30,
- "type": "VAEDecode",
- "pos": [
- 500,
- 470
- ],
- "size": [
- 316.20267896415703,
- 49.008590288398295
- ],
- "flags": {},
- "order": 12,
- "mode": 0,
- "inputs": [
- {
- "name": "samples",
- "type": "LATENT",
- "link": 60
- },
- {
- "name": "vae",
- "type": "VAE",
- "link": 83
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 78,
- 79
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "VAEDecode"
- },
- "color": "#322",
- "bgcolor": "#533"
- },
- {
- "id": 32,
- "type": "Reroute",
- "pos": [
- 1040,
- 80
- ],
- "size": [
- 82,
- 26
- ],
- "flags": {},
- "order": 7,
- "mode": 0,
- "inputs": [
- {
- "name": "",
- "type": "*",
- "link": 69
- }
- ],
- "outputs": [
- {
- "name": "MODEL",
- "type": "MODEL",
- "links": [
- 68
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "showOutputText": true,
- "horizontal": false
- }
- },
- {
- "id": 37,
- "type": "Reroute",
- "pos": [
- 1040,
- 120
- ],
- "size": [
- 82,
- 26
- ],
- "flags": {},
- "order": 15,
- "mode": 0,
- "inputs": [
- {
- "name": "",
- "type": "*",
- "link": 81
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 82
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "showOutputText": true,
- "horizontal": false
- }
- },
- {
- "id": 36,
- "type": "Reroute",
- "pos": [
- 800,
- 120
- ],
- "size": [
- 82,
- 26
- ],
- "flags": {},
- "order": 14,
- "mode": 0,
- "inputs": [
- {
- "name": "",
- "type": "*",
- "link": 79
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 81
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "showOutputText": true,
- "horizontal": false
- }
- },
- {
- "id": 34,
- "type": "Reroute",
- "pos": [
- 430,
- 30
- ],
- "size": [
- 75,
- 26
- ],
- "flags": {},
- "order": 6,
- "mode": 0,
- "inputs": [
- {
- "name": "",
- "type": "*",
- "link": 73
- }
- ],
- "outputs": [
- {
- "name": "VAE",
- "type": "VAE",
- "links": [
- 74,
- 83
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "showOutputText": true,
- "horizontal": false
- }
- },
- {
- "id": 15,
- "type": "MMDetLoader",
- "pos": [
- 500,
- 230
- ],
- "size": {
- "0": 315,
- "1": 78
- },
- "flags": {},
- "order": 2,
- "mode": 0,
- "outputs": [
- {
- "name": "BBOX_MODEL",
- "type": "BBOX_MODEL",
- "links": [
- 50
- ]
- },
- {
- "name": "SEGM_MODEL",
- "type": "SEGM_MODEL",
- "links": null
- }
- ],
- "properties": {
- "Node name for S&R": "MMDetLoader"
- },
- "widgets_values": [
- "bbox/mmdet_anime-face_yolov3.pth"
- ],
- "color": "#223",
- "bgcolor": "#335"
- },
- {
- "id": 4,
- "type": "CheckpointLoaderSimple",
- "pos": [
- 160,
- 230
- ],
- "size": [
- 312.08852985476653,
- 98
- ],
- "flags": {},
- "order": 3,
- "mode": 0,
- "outputs": [
- {
- "name": "MODEL",
- "type": "MODEL",
- "links": [
- 64
- ],
- "slot_index": 0
- },
- {
- "name": "CLIP",
- "type": "CLIP",
- "links": [
- 90
- ],
- "slot_index": 1
- },
- {
- "name": "VAE",
- "type": "VAE",
- "links": [
- 73
- ],
- "slot_index": 2
- }
- ],
- "properties": {
- "Node name for S&R": "CheckpointLoaderSimple"
- },
- "widgets_values": [
- "V07_v07.safetensors"
- ],
- "color": "#222",
- "bgcolor": "#000"
- },
- {
- "id": 39,
- "type": "Reroute",
- "pos": [
- 30,
- 150
- ],
- "size": [
- 75,
- 26
- ],
- "flags": {},
- "order": 5,
- "mode": 0,
- "inputs": [
- {
- "name": "",
- "type": "*",
- "link": 90,
- "pos": [
- 37.5,
- 0
- ]
- }
- ],
- "outputs": [
- {
- "name": "CLIP",
- "type": "CLIP",
- "links": [
- 91,
- 92
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "showOutputText": true,
- "horizontal": true
- }
- },
- {
- "id": 33,
- "type": "PreviewImage",
- "pos": [
- 840,
- 230
- ],
- "size": [
- 270,
- 660
- ],
- "flags": {},
- "order": 13,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 78
- }
- ],
- "properties": {
- "Node name for S&R": "PreviewImage"
- },
- "color": "#322",
- "bgcolor": "#533"
- },
- {
- "id": 17,
- "type": "MaskToImage",
- "pos": [
- 1830,
- 230
- ],
- "size": {
- "0": 283,
- "1": 27
- },
- "flags": {},
- "order": 19,
- "mode": 0,
- "inputs": [
- {
- "name": "mask",
- "type": "MASK",
- "link": 94
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 33
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "Node name for S&R": "MaskToImage"
- },
- "color": "#223",
- "bgcolor": "#335"
- },
- {
- "id": 40,
- "type": "Reroute",
- "pos": [
- 1610,
- 130
- ],
- "size": [
- 75,
- 26
- ],
- "flags": {},
- "order": 18,
- "mode": 0,
- "inputs": [
- {
- "name": "",
- "type": "*",
- "link": 93
- }
- ],
- "outputs": [
- {
- "name": "MASK",
- "type": "MASK",
- "links": [
- 94
- ],
- "slot_index": 0
- }
- ],
- "properties": {
- "showOutputText": true,
- "horizontal": false
- }
- },
- {
- "id": 18,
- "type": "PreviewImage",
- "pos": [
- 1830,
- 310
- ],
- "size": {
- "0": 282,
- "1": 223
- },
- "flags": {},
- "order": 20,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 33
- }
- ],
- "title": "1pass - mask",
- "properties": {
- "Node name for S&R": "PreviewImage"
- },
- "color": "#223",
- "bgcolor": "#335"
- },
- {
- "id": 7,
- "type": "PreviewImage",
- "pos": [
- 1510,
- 230
- ],
- "size": [
- 300,
- 660
- ],
- "flags": {},
- "order": 17,
- "mode": 0,
- "inputs": [
- {
- "name": "images",
- "type": "IMAGE",
- "link": 77
- }
- ],
- "title": "1pass (rough fix)",
- "properties": {
- "Node name for S&R": "PreviewImage"
- },
- "color": "#223",
- "bgcolor": "#335"
- },
- {
- "id": 27,
- "type": "FaceDetailer",
- "pos": [
- 1140,
- 230
- ],
- "size": {
- "0": 342.5999755859375,
- "1": 658
- },
- "flags": {},
- "order": 16,
- "mode": 0,
- "inputs": [
- {
- "name": "image",
- "type": "IMAGE",
- "link": 82
- },
- {
- "name": "model",
- "type": "MODEL",
- "link": 68
- },
- {
- "name": "vae",
- "type": "VAE",
- "link": 75
- },
- {
- "name": "positive",
- "type": "CONDITIONING",
- "link": 48
- },
- {
- "name": "negative",
- "type": "CONDITIONING",
- "link": 49
- },
- {
- "name": "bbox_model",
- "type": "BBOX_MODEL",
- "link": 50
- },
- {
- "name": "sam_model_opt",
- "type": "SAM_MODEL",
- "link": 55
- }
- ],
- "outputs": [
- {
- "name": "IMAGE",
- "type": "IMAGE",
- "links": [
- 77
- ],
- "slot_index": 0
- },
- {
- "name": "MASK",
- "type": "MASK",
- "links": [
- 93
- ],
- "slot_index": 1
- },
- {
- "name": "DETAILER_PIPE",
- "type": "DETAILER_PIPE",
- "links": [],
- "slot_index": 2
- }
- ],
- "properties": {
- "Node name for S&R": "FaceDetailer"
- },
- "widgets_values": [
- 256,
- "bbox",
- 267026622830019,
- "fixed",
- 20,
- 8,
- "euler",
- "karras",
- 0.5,
- 5,
- "disabled",
- "disabled",
- 0.5,
- 10,
- 3.5,
- "center-1",
- 20,
- 0.93,
- 0,
- 0.7,
- "False"
- ],
- "color": "#223",
- "bgcolor": "#335"
- }
- ],
- "links": [
- [
- 33,
- 17,
- 0,
- 18,
- 0,
- "IMAGE"
- ],
- [
- 48,
- 5,
- 0,
- 27,
- 3,
- "CONDITIONING"
- ],
- [
- 49,
- 6,
- 0,
- 27,
- 4,
- "CONDITIONING"
- ],
- [
- 50,
- 15,
- 0,
- 27,
- 5,
- "BBOX_MODEL"
- ],
- [
- 55,
- 16,
- 0,
- 27,
- 6,
- "SAM_MODEL"
- ],
- [
- 57,
- 5,
- 0,
- 28,
- 1,
- "CONDITIONING"
- ],
- [
- 58,
- 6,
- 0,
- 28,
- 2,
- "CONDITIONING"
- ],
- [
- 59,
- 29,
- 0,
- 28,
- 3,
- "LATENT"
- ],
- [
- 60,
- 28,
- 0,
- 30,
- 0,
- "LATENT"
- ],
- [
- 64,
- 4,
- 0,
- 31,
- 0,
- "*"
- ],
- [
- 65,
- 31,
- 0,
- 28,
- 0,
- "MODEL"
- ],
- [
- 68,
- 32,
- 0,
- 27,
- 1,
- "MODEL"
- ],
- [
- 69,
- 31,
- 0,
- 32,
- 0,
- "*"
- ],
- [
- 73,
- 4,
- 2,
- 34,
- 0,
- "*"
- ],
- [
- 74,
- 34,
- 0,
- 35,
- 0,
- "*"
- ],
- [
- 75,
- 35,
- 0,
- 27,
- 2,
- "VAE"
- ],
- [
- 77,
- 27,
- 0,
- 7,
- 0,
- "IMAGE"
- ],
- [
- 78,
- 30,
- 0,
- 33,
- 0,
- "IMAGE"
- ],
- [
- 79,
- 30,
- 0,
- 36,
- 0,
- "*"
- ],
- [
- 81,
- 36,
- 0,
- 37,
- 0,
- "*"
- ],
- [
- 82,
- 37,
- 0,
- 27,
- 0,
- "IMAGE"
- ],
- [
- 83,
- 34,
- 0,
- 30,
- 1,
- "VAE"
- ],
- [
- 90,
- 4,
- 1,
- 39,
- 0,
- "*"
- ],
- [
- 91,
- 39,
- 0,
- 5,
- 0,
- "CLIP"
- ],
- [
- 92,
- 39,
- 0,
- 6,
- 0,
- "CLIP"
- ],
- [
- 93,
- 27,
- 1,
- 40,
- 0,
- "*"
- ],
- [
- 94,
- 40,
- 0,
- 17,
- 0,
- "MASK"
- ]
- ],
- "groups": [],
- "config": {},
- "extra": {},
- "version": 0.4
-}
\ No newline at end of file
diff --git a/misc/simple.png b/misc/simple.png
deleted file mode 100644
index 853a6c13..00000000
Binary files a/misc/simple.png and /dev/null differ
diff --git a/notebook/comfyui_colab_impact_pack.ipynb b/notebook/comfyui_colab_impact_pack.ipynb
index a7512ac0..6435059c 100644
--- a/notebook/comfyui_colab_impact_pack.ipynb
+++ b/notebook/comfyui_colab_impact_pack.ipynb
@@ -1,6 +1,7 @@
{
"cells": [
{
+ "attachments": {},
"cell_type": "markdown",
"metadata": {
"id": "aaaaaaaaaa"
@@ -48,13 +49,17 @@
" !echo \"-= Updating ComfyUI =-\"\n",
" !git pull\n",
" !rm \"/content/drive/MyDrive/ComfyUI/custom_nodes/comfyui-impact-pack.py\"\n",
- " !wget -O \"/content/drive/MyDrive/ComfyUI/custom_nodes/comfyui-impact-pack.py\" https://raw.githubusercontent.com/ltdrdata/ComfyUI-Impact-Pack/Main/comfyui-impact-pack.py\n",
+ "\n",
+ "%cd custom_nodes\n",
+ "!git clone https://github.com/ltdrdata/ComfyUI-Impact-Pack\n",
+ "%cd $WORKSPACE\n",
"\n",
"!echo -= Install dependencies =-\n",
"!pip -q install xformers -r requirements.txt\n"
]
},
{
+ "attachments": {},
"cell_type": "markdown",
"metadata": {
"id": "kkkkkkkkkkkkkk"
@@ -103,6 +108,7 @@
]
},
{
+ "attachments": {},
"cell_type": "markdown",
"metadata": {
"id": "gggggggggg"
diff --git a/onnx.py b/onnx.py
new file mode 100644
index 00000000..ce4903cc
--- /dev/null
+++ b/onnx.py
@@ -0,0 +1,31 @@
+import onnxruntime
+from impact_utils import *
+
+
+def onnx_inference(image, onnx_model):
+ # prepare image
+ pil = tensor2pil(image)
+ image = np.ascontiguousarray(pil)
+ image = image[:, :, ::-1] # to BGR image
+ image = image.astype(np.float32)
+ image -= [103.939, 116.779, 123.68] # 'caffe' mode image preprocessing
+
+ # do detection
+ onnx_model = onnxruntime.InferenceSession(onnx_model)
+ outputs = onnx_model.run(
+ [s_i.name for s_i in onnx_model.get_outputs()],
+ {onnx_model.get_inputs()[0].name: np.expand_dims(image, axis=0)},
+ )
+
+ labels = [op for op in outputs if op.dtype == "int32"][0]
+ scores = [op for op in outputs if isinstance(op[0][0], np.float32)][0]
+ boxes = [op for op in outputs if isinstance(op[0][0], np.ndarray)][0]
+
+ # filter-out useless item
+ idx = np.where(labels[0] == -1)[0][0]
+
+ labels = labels[0][:idx]
+ scores = scores[0][:idx]
+ boxes = boxes[0][:idx].astype(np.uint32)
+
+ return labels, scores, boxes
\ No newline at end of file
diff --git a/server.py b/server.py
new file mode 100644
index 00000000..672b8b2e
--- /dev/null
+++ b/server.py
@@ -0,0 +1,37 @@
+main_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
+sys.path.append(os.path.dirname(__file__))
+sys.path.append(main_dir)
+
+import server
+from aiohttp import web
+
+
+@server.PromptServer.instance.routes.post("/upload/temp")
+async def upload_image(request):
+ upload_dir = folder_paths.get_temp_directory()
+
+ if not os.path.exists(upload_dir):
+ os.makedirs(upload_dir)
+
+ post = await request.post()
+ image = post.get("image")
+
+ if image and image.file:
+ filename = image.filename
+ if not filename:
+ return web.Response(status=400)
+
+ split = os.path.splitext(filename)
+ i = 1
+ while os.path.exists(os.path.join(upload_dir, filename)):
+ filename = f"{split[0]} ({i}){split[1]}"
+ i += 1
+
+ filepath = os.path.join(upload_dir, filename)
+
+ with open(filepath, "wb") as f:
+ f.write(image.file.read())
+
+ return web.json_response({"name": filename})
+ else:
+ return web.Response(status=400)
diff --git a/tutorial/ONNX.md b/tutorial/ONNX.md
deleted file mode 100644
index 45c168ca..00000000
--- a/tutorial/ONNX.md
+++ /dev/null
@@ -1,13 +0,0 @@
-
-# NudeNet
-Nudenet uses an ONNX model to detect NSFW content. This example is an application of [NudeNet](https://github.com/notAI-tech/NudeNet)'s capabilities, which detects NSFW elements in images and applies a mask as a post-processing step. This technique demonstrates the use of nudenet to detect potentially inappropriate content in order to ensure the safety of minors on certain websites
-
-* [detector_v2_base_checkpoint.onnx](https://github.com/notAI-tech/NudeNet/releases/download/v0/detector_v2_base_checkpoint.onnx) is a model for nudenet. Download and placed into **ComfyUI/models/onnx**
-
-* [onnx.json](../misc/onnx.json) is a workflow of this example.
-
-
-
-
-# ONNX Models
-* You can download various ONNX models from [here](https://github.com/PINTO0309/PINTO_model_zoo).
\ No newline at end of file
diff --git a/tutorial/advanced-simple-original.png b/tutorial/advanced-simple-original.png
deleted file mode 100644
index b641133a..00000000
Binary files a/tutorial/advanced-simple-original.png and /dev/null differ
diff --git a/tutorial/advanced-simple-refined-noisemask-disabled.png b/tutorial/advanced-simple-refined-noisemask-disabled.png
deleted file mode 100644
index 0269c88c..00000000
Binary files a/tutorial/advanced-simple-refined-noisemask-disabled.png and /dev/null differ
diff --git a/tutorial/advanced-simple-refined-noisemask-enabled.png b/tutorial/advanced-simple-refined-noisemask-enabled.png
deleted file mode 100644
index 9663ac03..00000000
Binary files a/tutorial/advanced-simple-refined-noisemask-enabled.png and /dev/null differ
diff --git a/tutorial/advanced-simple-refined.png b/tutorial/advanced-simple-refined.png
deleted file mode 100644
index 4a92580d..00000000
Binary files a/tutorial/advanced-simple-refined.png and /dev/null differ
diff --git a/tutorial/advanced-simple.png b/tutorial/advanced-simple.png
deleted file mode 100644
index bee1d762..00000000
Binary files a/tutorial/advanced-simple.png and /dev/null differ
diff --git a/tutorial/advanced.md b/tutorial/advanced.md
deleted file mode 100644
index b575425d..00000000
--- a/tutorial/advanced.md
+++ /dev/null
@@ -1,22 +0,0 @@
-#### 1. Basic auto face detection and refine exapmle.
-
-   
-* You can load models for bbox or segm using MMDetLoader. If you load a bbox model, only **BBOX_MODEL** is valid in the output, and if you load a segm model, only **SEGM_MODEL** is valid.
- * Currently, Impact Pack is providing the more sophisticated SAM model instead of the SEGM_MODEL for silhouette extraction.
-
-* The default downloaded bbox model currently only detects the face area as a rectangle, and the segm model detects the silhouette of a person.
-* The difference between BboxDetectorCombine and BboxDetectorForEach is that the former outputs a single mask by combining all detected bboxes, and the latter outputs SEGS consisting of various information, including the cropped image, mask pattern, crop position, and confidence, for each detection. SEGS can be used in other ...ForEach nodes.
-
-* The "noise_mask" option determines whether to add noise only to the masked area when generating an image using "KSampler". If enabled, denoising will not be applied outside the masked area, which can result in a safer generation with stronger denoising, but it may not always produce good results. The middle image shows the result when the "noise_mask" option is disabled, and the image on the right shows the result when the "noise_mask" option is enabled.
-
-* Detector Node
- * threshold: Detect only those object whose recognized confidence is above this set value.
- * dilation: Expand the detected mask area.
- * crop_factor: Determine how many times the surrounding area should be included in the detail recovery process based on the detected mask area. If this value is small, the restoration may not work well because the surrounding context cannot be known.
-
-* Detailer Node
- * guide_size: This feature attempt detail recovery only when the size of the detected mask is smaller than this value. If the size is larger, this feature increase the resolution and attempt detail recovery.
- * guide_size_for: This parameter determines whether guide_size is used based on the size of the detected face (bbox) or the size of the crop area that includes the face and is broadly cropped by crop_factor.
- * feather: When compositing the recovered details onto the original image, this feature use a gradient to composite it so that the boundaries are not visible. The thickness of this gradient is determined.
- * force_inpaint: force_inpaint will try to force regeneration even if it is smaller than guide_size . This function is useful when you simply want to change to another type of prompt other than the function to save details. However, in this case, upscale is forcibly fixed to 1.
- * This feature adopt the properties of KSampler because this feature use it to recover details.
\ No newline at end of file
diff --git a/tutorial/maskpointer-hair.png b/tutorial/maskpointer-hair.png
deleted file mode 100644
index b0e84feb..00000000
Binary files a/tutorial/maskpointer-hair.png and /dev/null differ
diff --git a/tutorial/maskpointer-original.png b/tutorial/maskpointer-original.png
deleted file mode 100644
index de005452..00000000
Binary files a/tutorial/maskpointer-original.png and /dev/null differ
diff --git a/tutorial/maskpointer-shirt.png b/tutorial/maskpointer-shirt.png
deleted file mode 100644
index aa5e70bd..00000000
Binary files a/tutorial/maskpointer-shirt.png and /dev/null differ
diff --git a/tutorial/maskpointer.md b/tutorial/maskpointer.md
deleted file mode 100644
index 1b5d1be8..00000000
--- a/tutorial/maskpointer.md
+++ /dev/null
@@ -1,13 +0,0 @@
-
-# Mask Pointer
-
-* When setting the detection-hint as **mask-points** in SAMDetector, multiple mask fragments are provided as SAM prompts. If using **mask-area**, only some of the points within the float mask's inner area are provided as SAM prompts. When detection_hint_use_negative is set to True, very small dots are interpreted as negative prompts in mask-points, and some areas with a mask value of 0 are interpreted as negative prompts in **mask-area**. The **detection_hint_threshold** interprets cases where the mask value in **mask-area** is equal to or higher than the threshold as positive prompts. However, values greater than 0 but less than the **detection_hint_threshold** are not used as negative prompts.
-* When using **mask-points**, please note that you should set "combined" parameter as **False** in MaskToSegs.
-
-
-* When you adjust the mouse wheel up and down, you can adjust the size of the brush. When you hold down the left mouse button and drag, it will draw, and when you hold down the right mouse button and drag, it will erase.
-* When using the mask_hint_use_negative as true in conjunction with the mask-points mode, large dots are interpreted as positive prompts and small dots are interpreted as negative prompts.
-
-
-
-* By using **mask-points** or **mask-area**, you can select only certain parts, such as shirts or hair, to regenerate.
\ No newline at end of file
diff --git a/tutorial/maskpointer.png b/tutorial/maskpointer.png
deleted file mode 100644
index 10c3de66..00000000
Binary files a/tutorial/maskpointer.png and /dev/null differ
diff --git a/tutorial/nudenet.png b/tutorial/nudenet.png
deleted file mode 100644
index d2db26dc..00000000
Binary files a/tutorial/nudenet.png and /dev/null differ
diff --git a/tutorial/pointer.png b/tutorial/pointer.png
deleted file mode 100644
index d3139d6f..00000000
Binary files a/tutorial/pointer.png and /dev/null differ