commit AutoBrightness node

This commit is contained in:
chflame
2024-04-08 22:38:31 +08:00
parent e8134be8f3
commit 4808f00667
7 changed files with 339 additions and 2 deletions
+10
View File
@@ -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 [AutoBrightness](#AutoBrightness) node,it can automatically adjust the brightness of image.
* [CreateGradientMask](#CreateGradientMask) node add ```center``` option.
* Commit [GetColorToneV2](#GetColorToneV2) node, can select the main and average colors for the background or body.
* Commit [ImageRewardFilter](#ImageRewardFilter) node, can filter out poor quality pictures.
@@ -311,6 +312,15 @@ Node options:
Open the text editing software and find the line starting with "LUT_dir=", after "=", enter the custom folder path name. all .cube files in this folder will be collected and displayed in the node list during ComfyUI initialization.
If the folder set in ini is invalid, the LUT folder that comes with the plugin will be enabled.
### <a id="table1">AutoBrightness</a>
Automatically adjust too dark or too bright image to moderate brightness, and support mask input. When mask input, only the content of the mask part is used as the data source of the automatic brightness. The output is still the whole adjusted image.
![image](image/auto_brightness_example.png)
Node options:
![image](image/auto_brightness_node.png)
* strength: Automatically adjust the intensity of the brightness. The larger the value, the more biased towards the middle value, the greater the difference from the original picture.
* saturation: Color saturation. Changes in brightness usually result in changes in color saturation, where appropriate compensation can be adjusted.
### <a id="table1">ColorAdapter</a>
Auto adjust the color tone of the image to resemble the reference image.
![image](image/color_adapter_example.png)
+11
View File
@@ -70,6 +70,7 @@ git clone https://github.com/chflame163/ComfyUI_LayerStyle.git
## 更新说明
<font size="4">**如果本插件更新后出现依赖包错误,请重新安装相关依赖包。
* 添加 [AutoBrightness](#AutoBrightness) 节点,可自动调整图片亮度。
* [CreateGradientMask](#CreateGradientMask) 节点增加 ```center``` 选项。
* 添加 [GetColorToneV2](#GetColorToneV2) 节点, 可选择背景或主体的主色和平均色。
* 添加[ImageRewardFilter](#ImageRewardFilter) 节点, 可过滤掉品质欠佳的图片。
@@ -305,6 +306,16 @@ git clone https://github.com/chflame163/ComfyUI_LayerStyle.git
<sup>*</sup>LUT文件夹在resource_dir.ini中定义,这个文件位于插件根目录下。用文本编辑软件打开,找到“LUT_dir=”开头的这一行,编辑“=”之后为自定义文件夹路径名。这个文件夹里面所有的.cube文件将在ComfyUI初始化时被收集并显示在节点的列表中。如果ini中设定的文件夹无效,将启用插件自带的LUT文件夹。
### <a id="table1">AutoBrightness</a>
将过暗或过亮的图片自动调整到适中的亮度,支持遮罩输入。有遮罩输入时仅以遮罩部分的内容作为自动亮度的数据来源。输出仍然是整个调整后的图像。
![image](image/auto_brightness_example.png)
节点选项说明:
![image](image/auto_brightness_node.png)
* strength: 自动调整亮度的强度。数值越大,越偏向中间值,与原图的差别越大。
* saturation: 色彩饱和度。亮度改变通常会导致色彩饱和度发生变化,可在此适当调整补偿。
### <a id="table1">ColorAdapter</a>
自动调整图片色调,使之与参考图片相似。
![image](image/color_adapter_example.png)
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

+77
View File
@@ -0,0 +1,77 @@
from .imagefunc import *
NODE_NAME = 'AutoBrightness'
class AutoBrightness:
def __init__(self):
pass
@classmethod
def INPUT_TYPES(self):
return {
"required": {
"image": ("IMAGE", ), #
"strength": ("INT", {"default": 75, "min": 0, "max": 100, "step": 1}),
"saturation": ("INT", {"default": 8, "min": -255, "max": 255, "step": 1}),
},
"optional": {
"mask": ("MASK", ),
}
}
RETURN_TYPES = ("IMAGE",)
RETURN_NAMES = ("image",)
FUNCTION = 'auto_brightness'
CATEGORY = '😺dzNodes/LayerColor'
def auto_brightness(self, image, strength, saturation, mask=None):
l_images = []
l_masks = []
ret_images = []
for l in image:
l_images.append(torch.unsqueeze(l, 0))
m = tensor2pil(l)
if m.mode == 'RGBA':
l_masks.append(m.split()[-1])
else:
l_masks.append(Image.new('L', m.size, 'white'))
if mask is not None:
if mask.dim() == 2:
mask = torch.unsqueeze(mask, 0)
l_masks = []
for m in mask:
l_masks.append(tensor2pil(torch.unsqueeze(m, 0)).convert('L'))
max_batch = max(len(l_images), len(l_masks))
for i in range(max_batch):
_image = l_images[i] if i < len(l_images) else l_images[-1]
_mask = l_masks[i] if i < len(l_masks) else l_masks[-1]
orig_image = tensor2pil(_image)
_l, _a, _b = orig_image.convert('LAB').split()
_histogram = histogram_equalization(_l, _mask, gamma_strength=strength/100)
_l = chop_image(_l, _histogram, 'normal', strength)
ret_image = image_channel_merge((_l, _a, _b), 'LAB')
if saturation != 0 :
_h, _s, _v = ret_image.convert('HSV').split()
_s = image_gray_offset(_s, saturation)
ret_image = image_channel_merge((_h, _s, _v), 'HSV')
if orig_image.mode == 'RGBA':
ret_image = RGB2RGBA(ret_image, orig_image.split()[-1])
ret_images.append(pil2tensor(ret_image))
# ret_images.append(pil2tensor(_l.convert('RGB')))
log(f"{NODE_NAME} Processed {len(ret_images)} image(s).", message_type='finish')
return (torch.cat(ret_images, dim=0),)
NODE_CLASS_MAPPINGS = {
"LayerColor: AutoBrightness": AutoBrightness
}
NODE_DISPLAY_NAME_MAPPINGS = {
"LayerColor: AutoBrightness": "LayerColor: AutoBrightness"
}
+33 -2
View File
@@ -681,7 +681,12 @@ def draw_rect(image:Image, x:int, y:int, width:int, height:int, line_color:str,
def draw_border(image:Image, border_width:int, color:str='#FFFFFF') -> Image:
return ImageOps.expand(image, border=border_width, fill=color)
def histogram_equalization(image:Image, mask:Image=None) -> Image:
def histogram_equalization(image:Image, mask:Image=None, gamma_strength=0.5) -> Image:
def remap_pixel(pixel, min_brightness, max_brightness):
return int((pixel - min_brightness) / (max_brightness - min_brightness) * 255)
if image.mode != 'L':
image = image.convert('L')
if mask is not None:
if mask.mode != 'L':
@@ -689,7 +694,33 @@ def histogram_equalization(image:Image, mask:Image=None) -> Image:
else:
mask = Image.new('L', size=image.size, color = 'white')
return ImageOps.equalize(image, mask=mask)
# calculate Min/Max brightness pixel
min_brightness = 255
max_brightness = 0
average_brightness = 0
total_pixel = 0
for y in range(image.height):
for x in range(image.width):
if mask.getpixel((x, y)) == 0:
continue
else:
pixel = image.getpixel((x, y))
if pixel < min_brightness:
min_brightness = pixel
if pixel > max_brightness:
max_brightness = pixel
average_brightness += pixel
total_pixel += 1
average_brightness = int(average_brightness / total_pixel)
for y in range(image.height):
for x in range(image.width):
pixel = image.getpixel((x, y))
image.putpixel((x, y), remap_pixel(pixel, min_brightness, max_brightness))
image = gamma_trans(image, (average_brightness - 127) / 127 * gamma_strength * 0.66 + 1)
return image.convert('L')
def get_image_color_tone(image:Image) -> str:
image = image.convert('RGB')
+208
View File
@@ -0,0 +1,208 @@
{
"last_node_id": 17,
"last_link_id": 23,
"nodes": [
{
"id": 16,
"type": "LayerMask: BiRefNetUltra",
"pos": [
1545,
315
],
"size": {
"0": 315,
"1": 198
},
"flags": {},
"order": 1,
"mode": 0,
"inputs": [
{
"name": "image",
"type": "IMAGE",
"link": 18
}
],
"outputs": [
{
"name": "image",
"type": "IMAGE",
"links": [],
"shape": 3,
"slot_index": 0
},
{
"name": "mask",
"type": "MASK",
"links": [
22
],
"shape": 3,
"slot_index": 1
}
],
"properties": {
"Node name for S&R": "LayerMask: BiRefNetUltra"
},
"widgets_values": [
"VITMatte(local)",
6,
6,
0.01,
0.99,
false
]
},
{
"id": 14,
"type": "LoadImage",
"pos": [
1051,
211
],
"size": [
444.985995205961,
348.55585826526465
],
"flags": {},
"order": 0,
"mode": 0,
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
18,
23
],
"shape": 3,
"slot_index": 0
},
{
"name": "MASK",
"type": "MASK",
"links": null,
"shape": 3
}
],
"properties": {
"Node name for S&R": "LoadImage"
},
"widgets_values": [
"1344x768_girl2 (2).png",
"image"
]
},
{
"id": 11,
"type": "LayerColor: AutoBrightness",
"pos": [
1897,
212
],
"size": {
"0": 315,
"1": 102
},
"flags": {},
"order": 2,
"mode": 0,
"inputs": [
{
"name": "image",
"type": "IMAGE",
"link": 23,
"slot_index": 0
},
{
"name": "mask",
"type": "MASK",
"link": 22
}
],
"outputs": [
{
"name": "image",
"type": "IMAGE",
"links": [
12
],
"shape": 3,
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "LayerColor: AutoBrightness"
},
"widgets_values": [
75,
8
]
},
{
"id": 12,
"type": "PreviewImage",
"pos": [
2258,
236
],
"size": [
508.56190074572487,
317.2527909712304
],
"flags": {},
"order": 3,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 12
}
],
"properties": {
"Node name for S&R": "PreviewImage"
}
}
],
"links": [
[
12,
11,
0,
12,
0,
"IMAGE"
],
[
18,
14,
0,
16,
0,
"IMAGE"
],
[
22,
16,
1,
11,
1,
"MASK"
],
[
23,
14,
0,
11,
0,
"IMAGE"
]
],
"groups": [],
"config": {},
"extra": {
"groupNodes": {}
},
"version": 0.4
}