LutApply node add the strenght option

This commit is contained in:
chflame163
2024-07-11 19:01:41 +08:00
parent dcd13b4b1a
commit aed1162b28
6 changed files with 74 additions and 18 deletions
+3
View File
@@ -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 />
* [LUT Apply](#LUT) Add the street parameter.
* Commit [AutoAdjustV2](#AutoAdjustV2) node, add optional mask input and support for multiple automatic color adjustment modes.
* Due to the upcoming discontinuation of gemini-pro vision services, [PromptTagger](#PromptTagger) and [PromptEmbellish](#PromptEmbellish) have added the "gemini-1.5-flash" API to continue using it.
* [Ultra](#Ultra) nodes added the option to run ```VitMatte``` on the CUDA device, resulting in a 5-fold increase in running speed.
@@ -356,11 +357,13 @@ Node options:
### <a id="table1">LUT</a> Apply
Apply LUT to the image. only supports .cube format.
![image](image/lut_apply_example.jpg)
Node options:
![image](image/lut_apply_node.jpg)
* LUT<sup>*</sup>: Here is a list of available. cube files in the LUT folder, and the selected LUT files will be applied to the image.
* color_space: For regular image, please select linear, for image in the log color space, please select log.
* strength: Range 0~100, LUT application strength. The larger the value, the greater the difference from the original image, and the smaller the value, the closer it is to the original image.
<sup>*</sup><font size="3">LUT folder is defined in ```resource_dir.ini```, this file is located in the root directory of the plug-in, and the default name is ```resource_dir.ini.example```. to use this file for the first time, you need to change the file suffix to ```.ini```.
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.
+2
View File
@@ -80,6 +80,7 @@ git clone https://github.com/chflame163/ComfyUI_LayerStyle.git
## 更新说明
<font size="4">**如果本插件更新后出现依赖包错误,请重新安装相关依赖包。
* [LUT Apply](#LUT) 节点增加strenght参数。
* 添加 [AutoAdjustV2](#AutoAdjustV2) 节点,增加可选遮罩输入,增加多种自动调色模式支持。
* 由于gemini-pro-vision即将停止服务, [PromptTagger](#PromptTagger) 和 [PromptEmbellish](#PromptEmbellish) 添加"gemini-1.5-flash" API以继续使用。
* [Ultra](#Ultra) 节点增加```VitMatte```方法在CUDA设备运行选项,运行速度提升5倍。
@@ -357,6 +358,7 @@ git clone https://github.com/chflame163/ComfyUI_LayerStyle.git
![image](image/lut_apply_node.jpg)
* LUT<sup>*</sup>: 这里列出了LUT文件夹中可用的.cube文件列表,选中的LUT文件将被应用到图像。
* color_space: 普通图片请选择linear, log色彩空间的图片请选择log。
* strength: 范围0~100, LUT应用强度。数值越大,与原图的差别越大, 数值越小,越接近原图。
<sup>*</sup><font size="3">LUT文件夹在```resource_dir.ini```中定义,这个文件位于插件根目录下, 默认名字是```resource_dir.ini.example```, 初次使用这个文件需将文件后缀改为.ini。用文本编辑软件打开,找到“LUT_dir=”开头的这一行,编辑“=”之后为自定义文件夹路径名。这个文件夹里面所有的.cube文件将在ComfyUI初始化时被收集并显示在节点的列表中。如果ini中设定的文件夹无效,将启用插件自带的LUT文件夹。</font>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 186 KiB

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

After

Width:  |  Height:  |  Size: 40 KiB

+3 -2
View File
@@ -15,6 +15,7 @@ class ColorCorrectLUTapply:
"image": ("IMAGE", ), #
"LUT": (LUT_LIST,), # LUT文件
"color_space": (color_space_list,),
"strength": ("INT", {"default": 100, "min": 0, "max": 100, "step": 1}),
},
"optional": {
}
@@ -25,14 +26,14 @@ class ColorCorrectLUTapply:
FUNCTION = 'color_correct_LUTapply'
CATEGORY = '😺dzNodes/LayerColor'
def color_correct_LUTapply(self, image, LUT, color_space):
def color_correct_LUTapply(self, image, LUT, color_space, strength):
ret_images = []
for i in image:
i = torch.unsqueeze(i, 0)
_image = tensor2pil(i)
lut_file = LUT_DICT[LUT]
ret_image = apply_lut(_image, lut_file, log=(color_space == 'log'))
ret_image = apply_lut(_image, lut_file=lut_file, colorspace=color_space, strength=strength)
if _image.mode == 'RGBA':
ret_image = RGB2RGBA(ret_image, _image.split()[-1])
+66 -16
View File
@@ -1077,29 +1077,79 @@ def gamma_trans(image:Image, gamma:float) -> Image:
_corrected = cv2.LUT(cv2_image,gamma_table)
return cv22pil(_corrected)
def apply_lut(image:Image, lut_file:str, log:bool=False) -> Image:
from colour.io.luts.iridas_cube import read_LUT_IridasCube, LUT3D, LUT3x1D
lut: Union[LUT3x1D, LUT3D] = read_LUT_IridasCube(lut_file)
lut.name = os.path.splitext(os.path.basename(lut_file))[0] # use base filename instead of internal LUT name
# def apply_lut(image:Image, lut_file:str, log:bool=False) -> Image:
# from colour.io.luts.iridas_cube import read_LUT_IridasCube, LUT3D, LUT3x1D
# lut: Union[LUT3x1D, LUT3D] = read_LUT_IridasCube(lut_file)
# lut.name = os.path.splitext(os.path.basename(lut_file))[0] # use base filename instead of internal LUT name
#
# im_array = np.asarray(image.convert('RGB'), dtype=np.float32) / 255
# is_non_default_domain = not np.array_equal(lut.domain, np.array([[0., 0., 0.], [1., 1., 1.]]))
# dom_scale = None
# if is_non_default_domain:
# dom_scale = lut.domain[1] - lut.domain[0]
# im_array = im_array * dom_scale + lut.domain[0]
# if log:
# im_array = im_array ** (1 / 2.2)
# im_array = lut.apply(im_array)
# if log:
# im_array = im_array ** (2.2)
# if is_non_default_domain:
# im_array = (im_array - lut.domain[0]) / dom_scale
# im_array = im_array * 255
# ret_image = Image.fromarray(np.uint8(im_array))
#
# return ret_image
im_array = np.asarray(image.convert('RGB'), dtype=np.float32) / 255
def apply_lut(image:Image, lut_file:str, colorspace:str, strength:int, clip_values:bool=True) -> Image:
"""
Apply a LUT to an image.
:param image: Image to apply the LUT to.
:param lut_file: LUT file to apply.
:param colorspace: Colorspace to convert the image to before applying the LUT.
:param clip_values: Clip the values of the LUT to the domain of the LUT.
:param strength: Strength of the LUT.
:return: Image with the LUT applied.
"""
log_colorspace = False
if colorspace == "log":
log_colorspace = True
from colour.io.luts.iridas_cube import read_LUT_IridasCube
lut = read_LUT_IridasCube(lut_file)
lut.name = lut_file
if clip_values:
if lut.domain[0].max() == lut.domain[0].min() and lut.domain[1].max() == lut.domain[1].min():
lut.table = np.clip(lut.table, lut.domain[0, 0], lut.domain[1, 0])
else:
if len(lut.table.shape) == 2: # 3x1D
for dim in range(3):
lut.table[:, dim] = np.clip(lut.table[:, dim], lut.domain[0, dim], lut.domain[1, dim])
else: # 3D
for dim in range(3):
lut.table[:, :, :, dim] = np.clip(lut.table[:, :, :, dim], lut.domain[0, dim], lut.domain[1, dim])
img = pil2tensor(image)
lut_img = img.numpy().copy()
is_non_default_domain = not np.array_equal(lut.domain, np.array([[0., 0., 0.], [1., 1., 1.]]))
dom_scale = None
if is_non_default_domain:
dom_scale = lut.domain[1] - lut.domain[0]
im_array = im_array * dom_scale + lut.domain[0]
if log:
im_array = im_array ** (1 / 2.2)
im_array = lut.apply(im_array)
if log:
im_array = im_array ** (2.2)
lut_img = lut_img * dom_scale + lut.domain[0]
if log_colorspace:
lut_img = lut_img ** (1/2.2)
lut_img = lut.apply(lut_img)
if log_colorspace:
lut_img = lut_img ** (2.2)
if is_non_default_domain:
im_array = (im_array - lut.domain[0]) / dom_scale
im_array = im_array * 255
ret_image = Image.fromarray(np.uint8(im_array))
return ret_image
lut_img = (lut_img - lut.domain[0]) / dom_scale
lut_img = torch.from_numpy(lut_img)
if strength < 100:
strength /= 100
lut_img = strength * lut_img + (1 - strength) * img
return tensor2pil(lut_img)
def color_adapter(image:Image, ref_image:Image) -> Image:
image = pil2cv2(image)