GetColorToneV2 node add 'mask' method of color_of option
This commit is contained in:
@@ -80,6 +80,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 />
|
||||
|
||||
* [GetColorToneV2](#GetColorToneV2) node add the ```mask``` method to the color selection option, which can accurately obtain the main color and average color within the mask.
|
||||
* [ImageScaleByAspectRatioV2](#ImageScaleByAspectRatioV2) node add the "background_color" option.
|
||||
* [LUT Apply](#LUT) Add the "strength" option.
|
||||
* Commit [AutoAdjustV2](#AutoAdjustV2) node, add optional mask input and support for multiple automatic color adjustment modes.
|
||||
@@ -814,13 +815,14 @@ V2 upgrade of GetColorTone. You can specify the dominant or average color to get
|
||||
|
||||
The following changes have been made on the basis of GetColorTong:
|
||||

|
||||
* color_of: Provides three options, entire, background, and subject, to select the color of the entire picture, background, or body, respectively.
|
||||
* color_of: Provides 4 options, mask, entire, background, and subject, to select the color of the mask area, entire picture, background, or subject, respectively.
|
||||
* remove_background_method: There are two methods of background recognition: BiRefNet and RMBG V1.4.
|
||||
* invert_mask: Whether to reverse the mask.
|
||||
* mask_grow: Mask expansion. For subject, a larger value brings the obtained color closer to the color at the center of the body.
|
||||
|
||||
Output:
|
||||
* image: Solid color picture output, the size is the same as the input picture.
|
||||
* mask: Mask output.
|
||||
|
||||
### <a id="table1">ExtendCanvas</a>
|
||||
Extend the canvas
|
||||
|
||||
+5
-3
@@ -80,6 +80,7 @@ git clone https://github.com/chflame163/ComfyUI_LayerStyle.git
|
||||
## 更新说明
|
||||
<font size="4">**如果本插件更新后出现依赖包错误,请重新安装相关依赖包。
|
||||
|
||||
* [GetColorToneV2](#GetColorToneV2) 节点的取色选项增加```mask```方法,可精确获取遮罩内的主色和平均色。
|
||||
* [ImageScaleByAspectRatioV2](#ImageScaleByAspectRatioV2) 节点增加background_color选项。
|
||||
* [LUT Apply](#LUT) 节点增加strenght选项。
|
||||
* 添加 [AutoAdjustV2](#AutoAdjustV2) 节点,增加可选遮罩输入,增加多种自动调色模式支持。
|
||||
@@ -800,18 +801,19 @@ ImageScaleByAspectRatio的V2升级版
|
||||
|
||||
### <a id="table1">GetColorToneV2</a>
|
||||
GetColorTone的V2升级版。可以指定获取主体或背景的主色或平均色。
|
||||

|
||||

|
||||

|
||||
|
||||
在GetColorTong基础上做了如下改变:
|
||||

|
||||
* color_of: 提供三个选项,entire, background和subject, 分别表示选择整个图片,背景,或主体的颜色。
|
||||
* color_of: 提供4个选项,mask, entire, background和subject, 分别表示选择遮罩区域,整个图片,背景,或主体的颜色。
|
||||
* remove_background_method: 背景识别的方法, 有BiRefNet和RMBG V1.4两种可以选择。
|
||||
* invert_mask: 是否反转遮罩。
|
||||
* mask_grow: 遮罩扩张。对于subject, 更大的值使获得的颜色更接近主体中心的颜色。
|
||||
|
||||
输出:
|
||||
* image: 纯色图片输出, 尺寸与输入的图片相同。
|
||||
|
||||
* mask: 遮罩输出。
|
||||
|
||||
### <a id="table1">ExtendCanvas</a>
|
||||
扩展画布。
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 86 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 71 KiB After Width: | Height: | Size: 48 KiB |
+25
-15
@@ -9,8 +9,8 @@ class GetColorToneV2:
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(self):
|
||||
remove_background_list = ['BiRefNet', 'RMBG 1.4',]
|
||||
subject_list = ['entire', 'background', 'subject']
|
||||
remove_background_list = ['none','BiRefNet', 'RMBG 1.4',]
|
||||
subject_list = ['mask','entire', 'background', 'subject']
|
||||
mode_list = ['main_color', 'average']
|
||||
return {
|
||||
"required": {
|
||||
@@ -19,15 +19,15 @@ class GetColorToneV2:
|
||||
"color_of": (subject_list,),
|
||||
"remove_bkgd_method": (remove_background_list,),
|
||||
"invert_mask": ("BOOLEAN", {"default": False}), # 反转mask#
|
||||
"mask_grow": ("INT", {"default": 16, "min": -999, "max": 999, "step": 1}),
|
||||
"mask_grow": ("INT", {"default": 0, "min": -999, "max": 999, "step": 1}),
|
||||
},
|
||||
"optional": {
|
||||
"mask": ("MASK",), #
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("IMAGE", "STRING", "LIST",)
|
||||
RETURN_NAMES = ("image", "color_in_hex", "HSV color in list",)
|
||||
RETURN_TYPES = ("IMAGE", "STRING", "LIST", "MASK")
|
||||
RETURN_NAMES = ("image", "color_in_hex", "HSV color in list", "mask",)
|
||||
FUNCTION = 'get_color_tone_v2'
|
||||
CATEGORY = '😺dzNodes/LayerUtility'
|
||||
|
||||
@@ -38,6 +38,7 @@ class GetColorToneV2:
|
||||
_images = []
|
||||
_masks = []
|
||||
ret_images = []
|
||||
ret_masks = []
|
||||
need_rmbg = False
|
||||
for i in image:
|
||||
_images.append(torch.unsqueeze(i, 0))
|
||||
@@ -45,14 +46,15 @@ class GetColorToneV2:
|
||||
if m.mode == 'RGBA':
|
||||
_masks.append(1 - image2mask(m.split()[-1]))
|
||||
else:
|
||||
need_rmbg = True
|
||||
_masks.append(pil2tensor(Image.new("L", (m.width, m.height), color="white")))
|
||||
if remove_bkgd_method != 'none':
|
||||
need_rmbg = True
|
||||
|
||||
if mask is not None:
|
||||
if mask.dim() == 2:
|
||||
mask = torch.unsqueeze(mask, 0)
|
||||
_masks = []
|
||||
for m in mask:
|
||||
if not invert_mask:
|
||||
m = 1 - m
|
||||
_masks.append(torch.unsqueeze(m, 0))
|
||||
need_rmbg = False
|
||||
|
||||
@@ -71,32 +73,40 @@ class GetColorToneV2:
|
||||
else:
|
||||
_mask = RMBG(_image)
|
||||
_mask = image2mask(_mask)
|
||||
_mask = 1 - _mask
|
||||
else:
|
||||
_mask = _masks[i] if i < len(_masks) else _masks[-1]
|
||||
|
||||
if invert_mask:
|
||||
_mask = 1 - _mask
|
||||
|
||||
if mask_grow != 0:
|
||||
_mask = expand_mask(_mask, mask_grow, 0) # 扩张,模糊
|
||||
|
||||
if color_of == 'subject':
|
||||
_mask = 1 - _mask
|
||||
|
||||
if color_of == 'entire':
|
||||
blured_image = gaussian_blur(_image, int((_image.width + _image.height) / 400))
|
||||
else:
|
||||
if color_of == 'background':
|
||||
_mask = 1 - _mask
|
||||
_mask = tensor2pil(_mask)
|
||||
pixel_spread_image = pixel_spread(_image, _mask.convert('RGB'))
|
||||
blured_image = gaussian_blur(pixel_spread_image, int((_image.width + _image.height) / 400))
|
||||
if mode == 'main_color':
|
||||
|
||||
ret_color = '#000000'
|
||||
if mode == 'main_color' and color_of != 'mask':
|
||||
ret_color = get_image_color_tone(blured_image)
|
||||
else:
|
||||
elif mode == 'average' and color_of != 'mask':
|
||||
ret_color = get_image_color_average(blured_image)
|
||||
elif mode == 'main_color' and color_of == 'mask':
|
||||
ret_color = get_image_color_tone(blured_image, mask=_mask)
|
||||
elif mode == 'average' and color_of == 'mask':
|
||||
ret_color = get_image_color_average(blured_image, mask=_mask)
|
||||
|
||||
ret_image = Image.new('RGB', size=_image.size, color=ret_color)
|
||||
ret_images.append(pil2tensor(ret_image))
|
||||
ret_masks.append(pil2tensor(_mask))
|
||||
log(f"{NODE_NAME} Processed {len(ret_images)} image(s).", message_type='finish')
|
||||
hsv_color = RGB_to_HSV(Hex_to_RGB(ret_color))
|
||||
return (torch.cat(ret_images, dim=0), ret_color, hsv_color,)
|
||||
return (torch.cat(ret_images, dim=0), ret_color, hsv_color, torch.cat(ret_masks, dim=0),)
|
||||
|
||||
NODE_CLASS_MAPPINGS = {
|
||||
"LayerUtility: GetColorToneV2": GetColorToneV2
|
||||
|
||||
+24
-7
@@ -893,12 +893,22 @@ def adjust_levels(image:Image, input_black:int=0, input_white:int=255, midtones:
|
||||
img = img.astype(np.uint8)
|
||||
return cv22pil(img)
|
||||
|
||||
|
||||
def get_image_color_tone(image:Image) -> str:
|
||||
def get_image_color_tone(image:Image, mask:Image=None) -> str:
|
||||
image = image.convert('RGB')
|
||||
max_score = 0.0001
|
||||
dominant_color = (255, 255, 255)
|
||||
for count, (r, g, b) in image.getcolors(image.width * image.height):
|
||||
if mask is not None:
|
||||
if mask.mode != 'L':
|
||||
mask = mask.convert('L')
|
||||
canvas = Image.new('RGB', size=image.size, color='black')
|
||||
canvas.paste(image, mask=mask)
|
||||
image = canvas
|
||||
|
||||
all_colors = image.getcolors(image.width * image.height)
|
||||
for count, (r, g, b) in all_colors:
|
||||
if mask is not None:
|
||||
if r + g + b < 2: # 忽略黑色
|
||||
continue
|
||||
saturation = colorsys.rgb_to_hsv(r / 255.0, g / 255.0, b / 255.0)[1]
|
||||
y = min(abs(r * 2104 + g * 4130 + b * 802 + 4096 + 131072) >> 13,235)
|
||||
y = (y - 16.0) / (235 - 16)
|
||||
@@ -909,22 +919,29 @@ def get_image_color_tone(image:Image) -> str:
|
||||
ret_color = RGB_to_Hex(dominant_color)
|
||||
return ret_color
|
||||
|
||||
def get_image_color_average(image:Image) -> str:
|
||||
def get_image_color_average(image:Image, mask:Image=None) -> str:
|
||||
image = image.convert('RGB')
|
||||
width, height = image.size
|
||||
total_red = 0
|
||||
total_green = 0
|
||||
total_blue = 0
|
||||
total_pixel =0
|
||||
for y in range(height):
|
||||
for x in range(width):
|
||||
if mask is not None:
|
||||
if mask.mode != 'L':
|
||||
mask = mask.convert('L')
|
||||
if mask.getpixel((x, y)) <= 127:
|
||||
continue
|
||||
rgb = image.getpixel((x, y))
|
||||
total_red += rgb[0]
|
||||
total_green += rgb[1]
|
||||
total_blue += rgb[2]
|
||||
total_pixel += 1
|
||||
|
||||
average_red = total_red // (width * height)
|
||||
average_green = total_green // (width * height)
|
||||
average_blue = total_blue // (width * height)
|
||||
average_red = total_red // total_pixel
|
||||
average_green = total_green // total_pixel
|
||||
average_blue = total_blue // total_pixel
|
||||
color = (average_red, average_green, average_blue)
|
||||
ret_color = RGB_to_Hex(color)
|
||||
return ret_color
|
||||
|
||||
+1
-1
@@ -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.12"
|
||||
version = "1.0.13"
|
||||
license = "MIT"
|
||||
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"]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user