Skip to content

Commit

Permalink
commit MaskByColor node
Browse files Browse the repository at this point in the history
  • Loading branch information
chflame163 committed May 29, 2024
1 parent d09eeb3 commit 690ea3d
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 1 deletion.
15 changes: 15 additions & 0 deletions README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ When this error has occurred, please check the network environment.
## Update
<font size="4">**If the dependency package error after updating, please reinstall the relevant dependency packages. </font><br />

* Commit [MaskByColor](#MaskByColor) node, Generate a mask based on the selected color.
* Commit [LoadPSD](#LoadPSD) node, It read the psd format, and output layer images.
* Commit [SegformerB2ClothesUltra](#SegformerB2ClothesUltra) node, it used to segment character clothing. The model segmentation code is from[StartHua](https://github.com/StartHua/Comfyui_segformer_b2_clothes), thanks to the original author.
* [SaveImagePlus](#SaveImagePlus) node adds the output workflow to the json function, supports ```%date``` and ```%time``` to embeddint date or time to path and filename, and adds the preview switch.
Expand Down Expand Up @@ -1374,6 +1375,20 @@ Outputs:
* yolo_masks: For all masks identified by yolo, each individual mask is output as a mask.


### <a id="table1">MaskByColor</a>
Generate a mask based on the selected color.
![image](image/mask_by_color_example.jpg)

Node Options:
![image](image/mask_by_color_node.jpg)
* image: Input image.
* color: Color selector. Click on the color block to select a color, and you can use the straws on the color picker panel to pick up the screen color. Note: When using straws, maximize the browser window.
* color_in_HEX<sup>4</sup>: Enter color values. If this item has input, it will be used first, ignoring the color selected by the ```color``` .
* threshold: Mask range threshold, the larger the value, the larger the mask range.
* fix_gap: Repair the gaps in the mask. If there are obvious gaps in the mask, increase this value appropriately.
* fix_threshold: The threshold for repairing masks.
* invert_mask: Whether to reverse the mask.

### <a id="table1">Shadow</a> & Highlight Mask
Generate masks for the dark and bright parts of the image.
![image](image/shadow_and_highlight_mask_example.jpg)
Expand Down
16 changes: 16 additions & 0 deletions README_CN.MD
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ git clone https://github.com/chflame163/ComfyUI_LayerStyle.git
## 更新说明
<font size="4">**如果本插件更新后出现依赖包错误,请重新安装相关依赖包。

* 添加 [MaskByColor](#MaskByColor) 节点, 根据选择的颜色生成遮罩。
* 添加 [LoadPSD](#LoadPSD) 节点, 读取psd格式并输出图层图片。
* 添加 [SegformerB2ClothesUltra](#SegformerB2ClothesUltra)节点,用于分割人物服装。模型分割代码来自[StartHua](https://github.com/StartHua/Comfyui_segformer_b2_clothes),感谢原作者。
* [SaveImagePlus](#SaveImagePlus)节点增加输出工作流为json功能,支持使用```%date``````%time```在路径和文件名嵌入时间,增加预览开关。
Expand Down Expand Up @@ -1360,6 +1361,21 @@ PersonMaskUltra的V2升级版,增加了VITMatte边缘处理方法。(注意:
* yolo_masks: yolo识别出来的所有遮罩,每个单独的遮罩输出为一个mask。


### <a id="table1">MaskByColor</a>
根据颜色生成遮罩。
![image](image/mask_by_color_example.jpg)

节点选项说明:
![image](image/mask_by_color_node.jpg)
* image: 图像输入。
* color: 颜色选择器。点击色块选择颜色,可以使用选色器面板上的吸管拾取屏幕颜色。注意:使用吸管时,需将浏览器窗口最大化。
* color_in_HEX<sup>4</sup>: 输入色值。如果此项有输入,则优先使用,忽略```color```选取的颜色。
* threshold: 遮罩范围阈值,数值越大,遮罩范围越大。
* fix_gap: 修补遮罩中的空隙。如果遮罩中有比较明显的空隙,适当调高此数值。
* fix_threshold: 修补遮罩的阈值。
* invert_mask: 是否反转遮罩。


### <a id="table1">Shadow</a> & Highlight Mask
生成图像暗部和亮部的遮罩。
![image](image/shadow_and_highlight_mask_example.jpg)
Expand Down
Binary file added image/mask_by_color_example.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added image/mask_by_color_node.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
34 changes: 34 additions & 0 deletions py/imagefunc.py
Original file line number Diff line number Diff line change
Expand Up @@ -1262,6 +1262,40 @@ def generate_text_image(width:int, height:int, text:str, font_file:str, text_sca
return image

'''Mask Functions'''

def create_mask_from_color_cv2(image:Image, color:str, tolerance:int=0) -> Image:
(r, g, b) = Hex_to_RGB(color)
target_color = (b, g, r)
tolerance = 127 + int(tolerance * 1.28)
# tolerance = 255 - tolerance
# 将RGB颜色转换为HSV颜色空间
image = pil2cv2(image)
hsv_image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)

# 定义目标颜色的HSV范围
lower_color = np.array([max(target_color[0] - tolerance, 0), max(target_color[1] - tolerance, 0), max(target_color[2] - tolerance, 0)])
upper_color = np.array([min(target_color[0] + tolerance, 255), min(target_color[1] + tolerance, 255), min(target_color[2] + tolerance, 255)])

# 创建掩码
mask = cv2.inRange(hsv_image, lower_color, upper_color)

return cv22pil(mask).convert("L")

def create_mask_from_color_tensor(image:Image, color:str, tolerance:int=0) -> Image:
threshold = int(tolerance * 1.28)
(red, green, blue) = Hex_to_RGB(color)
image = pil2tensor(image).squeeze()
temp = (torch.clamp(image, 0, 1.0) * 255.0).round().to(torch.int)
color_value = torch.tensor([red, green, blue])
lower_bound = (color_value - threshold).clamp(min=0)
upper_bound = (color_value + threshold).clamp(max=255)
lower_bound = lower_bound.view(1, 1, 1, 3)
upper_bound = upper_bound.view(1, 1, 1, 3)
mask = (temp >= lower_bound) & (temp <= upper_bound)
mask = mask.all(dim=-1)
mask = mask.float()
return tensor2pil(mask).convert("L")

@lru_cache(maxsize=1, typed=False)
def load_RMBG_model():
current_directory = os.path.dirname(os.path.abspath(__file__))
Expand Down
54 changes: 54 additions & 0 deletions py/mask_by_color.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
from .imagefunc import *

NODE_NAME = 'MaskByColor'


class MaskByColor:
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"image": ("IMAGE", ),
"color": ("COLOR", {"default": "#FFFFFF"},),
"color_in_HEX": ("STRING", {"default": ""}),
"threshold": ("INT", { "default": 0, "min": 0, "max": 100, "step": 1, }),
"fix_gap": ("INT", {"default": 2, "min": 0, "max": 32, "step": 1}),
"fix_threshold": ("FLOAT", {"default": 0.75, "min": 0.01, "max": 0.99, "step": 0.01}),
"invert_mask": ("BOOLEAN", {"default": False}), # 反转mask
}
}

RETURN_TYPES = ("MASK",)
RETURN_NAMES = ("mask",)
FUNCTION = "mask_by_color"
CATEGORY = '😺dzNodes/LayerMask'

def mask_by_color(self, image, color, color_in_HEX, threshold,
fix_gap, fix_threshold, invert_mask):

if color_in_HEX != "" and color_in_HEX.startswith('#') and len(color_in_HEX) == 7:
color = color_in_HEX

ret_masks = []

for i in image:
img = tensor2pil(i.unsqueeze(0))
mask = create_mask_from_color_tensor(img, color, threshold)
mask = image2mask(mask)
if invert_mask:
mask = 1 - mask

if fix_gap:
mask = mask_fix(mask, 1, fix_gap, fix_threshold, fix_threshold)
ret_masks.append(mask)

return (torch.cat(ret_masks, dim=0), )


NODE_CLASS_MAPPINGS = {
"LayerMask: MaskByColor": MaskByColor
}

NODE_DISPLAY_NAME_MAPPINGS = {
"LayerMask: MaskByColor": "LayerMask: Mask by Color"
}
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[project]
name = "comfyui_layerstyle"
description = "A set of nodes for ComfyUI it generate image like Adobe Photoshop's Layer Style. the Drop Shadow is first completed node, and follow-up work is in progress."
version = "1.0.1"
version = "1.0.2"
license = "LICENSE"
dependencies = ["numpy", "pillow", "torch", "matplotlib", "Scipy", "scikit_image", "opencv-contrib-python", "pymatting", "segment_anything", "timm", "addict", "yapf", "colour-science", "wget", "mediapipe", "loguru", "typer_config", "fastapi", "rich", "google-generativeai", "diffusers", "omegaconf", "tqdm", "transformers", "kornia", "image-reward", "ultralytics", "blend_modes", "blind-watermark", "qrcode", "pyzbar", "psd-tools"]

Expand Down

0 comments on commit 690ea3d

Please sign in to comment.