diff --git a/.gitignore b/.gitignore index 140998f..2887b2a 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,4 @@ _test_*.* __pycache__ .venv .idea -*.pth -pickle \ No newline at end of file +*.pth \ No newline at end of file diff --git a/README.MD b/README.MD index 82ada44..079309c 100644 --- a/README.MD +++ b/README.MD @@ -17,7 +17,7 @@ Nodes are divided into 5 groups according to their functions: LayerStyle, LayerC ## Update **If the dependency package error after updating, please reinstall the relevant dependency packages. for details, please refer to [here](https://github.com/chflame163/ComfyUI_LayerStyle/issues/5). - +* Commit [LightLeak](#LightLeak) node, this filter simulate the light leakage effect of the film. * Commit [Film](#Film) node, this filter simulate the grain, dark edge, and blurred edge of the film, support input depth map to simulate defocus. it is reorganize and encapsulate of [digitaljohn/comfyui-propost](https://github.com/digitaljohn/comfyui-propost). * Commit [ImageAutoCrop](#ImageAutoCrop) node, which is designed to generate image materials for training models. * Commit [ImageScaleByAspectRatio](#ImageScaleByAspectRatio) node, it can be scaled image or mask according to frame ratio. @@ -671,13 +671,13 @@ Output: Improvements to [ComfyUI Segment Anything](https://github.com/storyicon/comfyui_segment_anything), combined with the Alpha Matte node of [ComfyUI-Image-Filters](https://github.com/spacepxl/ComfyUI-Image-Filters) in spacepxl, result in more detailed edges for masks. *Please refer to the installation of ComfyUI Segment Anything to install the model. If ComfyUI Segment Anything has been correctly installed, you can skip this step. -* From [here](https://huggingface.co/bert-base-uncased/tree/main) download the config.json,model.safetensors,tokenizer_config.json,tokenizer.json å’Œ vocab.txt 5 files to ComfyUI/models/bert-base-uncased folder. +* From [here](https://huggingface.co/bert-base-uncased/tree/main) download the config.json,model.safetensors,tokenizer_config.json,tokenizer.json and vocab.txt 5 files to ```ComfyUI/models/bert-base-uncased``` folder. * Download [GroundingDINO_SwinT_OGC config file](https://huggingface.co/ShilongLiu/GroundingDINO/resolve/main/GroundingDINO_SwinT_OGC.cfg.py), [GroundingDINO_SwinT_OGC model](https://huggingface.co/ShilongLiu/GroundingDINO/resolve/main/groundingdino_swint_ogc.pth), -[GroundingDINO_SwinB config file](https://huggingface.co/ShilongLiu/GroundingDINO/resolve/main/GroundingDINO_SwinB.cfg.py), [GroundingDINO_SwinB model](https://huggingface.co/ShilongLiu/GroundingDINO/resolve/main/groundingdino_swinb_cogcoor.pth) to ComfyUI/models/grounding-dino folder. +[GroundingDINO_SwinB config file](https://huggingface.co/ShilongLiu/GroundingDINO/resolve/main/GroundingDINO_SwinB.cfg.py), [GroundingDINO_SwinB model](https://huggingface.co/ShilongLiu/GroundingDINO/resolve/main/groundingdino_swinb_cogcoor.pth) to ```ComfyUI/models/grounding-dino``` folder. * Download [sam_vit_h](https://dl.fbaipublicfiles.com/segment_anything/sam_vit_h_4b8939.pth),[sam_vit_l](https://dl.fbaipublicfiles.com/segment_anything/sam_vit_l_0b3195.pth), [sam_vit_b](https://dl.fbaipublicfiles.com/segment_anything/sam_vit_b_01ec64.pth), [sam_hq_vit_h](https://huggingface.co/lkeab/hq-sam/resolve/main/sam_hq_vit_h.pth), [sam_hq_vit_l](https://huggingface.co/lkeab/hq-sam/resolve/main/sam_hq_vit_l.pth), [sam_hq_vit_b](https://huggingface.co/lkeab/hq-sam/resolve/main/sam_hq_vit_b.pth), -[mobile_sam](https://github.com/ChaoningZhang/MobileSAM/blob/master/weights/mobile_sam.pt) to ComfyUI/models/sams folder. +[mobile_sam](https://github.com/ChaoningZhang/MobileSAM/blob/master/weights/mobile_sam.pt) to ```ComfyUI/models/sams``` folder. ![image](image/segment_anything_ultra_compare.png) ![image](image/segment_anything_ultra_example.png) @@ -699,7 +699,7 @@ Remove background. compared to the similar background removal nodes, this node h This node combines the Alpha Matte node of Spacepxl's [ComfyUI-Image-Filters](https://github.com/spacepxl/ComfyUI-Image-Filters) and the functionality of ZHO-ZHO-ZHO's [ComfyUI-BRIA_AI-RMBG](https://github.com/ZHO-ZHO-ZHO/ComfyUI-BRIA_AI-RMBG). -*Download the [BRIA Background Removal v1.4](https://huggingface.co/briaai/RMBG-1.4) model file (model. pth) to the /ComfyUI/models/rmbg/RMBG-1.4 folder. This model was developed by BRIA AI and can be used as an open-source model for non-commercial purposes. +*Download the [BRIA Background Removal v1.4](https://huggingface.co/briaai/RMBG-1.4) model file (```model.pth```) to the ```/ComfyUI/models/rmbg/RMBG-1.4``` folder. This model was developed by BRIA AI and can be used as an open-source model for non-commercial purposes. **After downloading the model, recommended to add a line 'rmbg: models/rmbg/RMBG-1.4' in ComfyUI/extra_model_paths.yaml. (This step is not mandatory) ![image](image/rembg_ultra_example.png) @@ -907,6 +907,18 @@ Node options: * blur_focus_spread: Focus diffusion range. larger value means larger clear range. * focal_depth: Simulate the focal distance of defucus. 0 indicates that focus is farthest, and 1 indicates that is closest. this setting only valid when input the depth_map. +### LightLeak +Simulate the light leakage effect of the film. please download the [light_leak.pkl(on Baidu Netdisk)](https://pan.baidu.com/s/1QY1ZyYm885krrqDB2t8lPg?pwd=yvs3), copy the file to ```ComfyUI/models/layerstyle``` folder. +![image](image/light_leak_example.png) + +Node options: +![image](image/light_leak_node.png) +* light: 32 types of light spots are provided. random is a random selection. +* corner: There are four options for the corner where the light appears: top left, top right, bottom left, and bottom right. +* hue: The hue of the light. +* saturation: The color saturation of the light. +* opacity: The opacity of the light. + ### ColorMap Pseudo color heat map effect. ![image](image/colormap_result.png) diff --git a/README_CN.MD b/README_CN.MD index 2c1106c..d8ce7f1 100644 --- a/README_CN.MD +++ b/README_CN.MD @@ -13,10 +13,11 @@ ## ¸üÐÂ˵Ã÷ **Èç¹û±¾²å¼þ¸üкó³öÏÖÒÀÀµ°ü´íÎó£¬ÇëÖØÐ°²×°Ïà¹ØÒÀÀµ°ü¡£ÏêÇé¼û[ÕâÀï](https://github.com/chflame163/ComfyUI_LayerStyle/issues/5)¡£ -* Ìí¼Ó [Film](#Film) ½Úµã, Õâ¸öÂ˾µÄ£Ä⽺ƬµÄ¿ÅÁ£¡¢°µ±ßºÍ±ßԵģºý£¬Ö§³ÖÊäÈëÉî¶ÈͼģÄâÐé½¹£¬ÊÇ[digitaljohn/comfyui-propost](https://github.com/digitaljohn/comfyui-propost)µÄÖØÐ·â×°¡£ -* Ìí¼Ó [ImageAutoCrop](#ImageAutoCrop) ½Úµã, Õâ¸ö½ÚµãÊÇΪÉú³ÉѵÁ·Ä£Ð͵ÄÍ¼Æ¬ËØ²Ä¶øÉè¼ÆµÄ¡£ -* Ìí¼Ó [ImageScaleByAspectRatio](#ImageScaleByAspectRatio) ½Úµã£¬ ¿É°´»­·ù±ÈÀýËõ·ÅͼÏñ¡£ -* ¸ÄÕý [LUT Apply](#LUT) ½ÚµãäÖȾ³öÏÖÉ«½×µÄbug, ²¢Ôö¼ÓlogÉ«²Ê¿Õ¼äÖ§³Ö¡£*logÉ«²Ê¿Õ¼äͼƬÇë¼ÓÔØ×¨ÃŵÄlog lut¡£ +* Ìí¼Ó[LightLeak](#LightLeak) ½Úµã£¬Õâ¸öÂ˾µÄ£Ä⽺Ƭ©¹âЧ¹û¡£ +* Ìí¼Ó[Film](#Film) ½Úµã, Õâ¸öÂ˾µÄ£Ä⽺ƬµÄ¿ÅÁ£¡¢°µ±ßºÍ±ßԵģºý£¬Ö§³ÖÊäÈëÉî¶ÈͼģÄâÐé½¹£¬ÊÇ[digitaljohn/comfyui-propost](https://github.com/digitaljohn/comfyui-propost)µÄÖØÐ·â×°¡£ +* Ìí¼Ó[ImageAutoCrop](#ImageAutoCrop) ½Úµã, Õâ¸ö½ÚµãÊÇΪÉú³ÉѵÁ·Ä£Ð͵ÄÍ¼Æ¬ËØ²Ä¶øÉè¼ÆµÄ¡£ +* Ìí¼Ó[ImageScaleByAspectRatio](#ImageScaleByAspectRatio) ½Úµã£¬ ¿É°´»­·ù±ÈÀýËõ·ÅͼÏñ¡£ +* ¸ÄÕý[LUT Apply](#LUT) ½ÚµãäÖȾ³öÏÖÉ«½×µÄbug, ²¢Ôö¼ÓlogÉ«²Ê¿Õ¼äÖ§³Ö¡£*logÉ«²Ê¿Õ¼äͼƬÇë¼ÓÔØ×¨ÃŵÄlog lut¡£ * Ìí¼Ó[CreateGradientMask](#CreateGradientMask) ½Úµã¡£Ìí¼Ó [LayerImageTransform](#LayerImageTransform) ºÍ [LayerMaskTransform](#LayerMaskTransform) ½Úµã¡£ * Ìí¼Ó[MaskEdgeUltraDetail](#MaskEdgeUltraDetail) ½Úµã£¬¸ø´Ö²ÚµÄÕÚÕÖ½øÐд¦Àí»ñµÃ³¬¾«Ï¸µÄ±ßÔµ¡£Ìí¼Ó [Exposure](#Exposure) ½Úµã£¬µ÷ÕûͼÏñÆØ¹â¡£ * Ìí¼Ó[Sharp & Soft](#Sharp) ½Úµã£¬¿ÉÌáÉý»òĨƽͼÏñϸ½Ú¡£ÐÂÔö[MaskByDifferent](#MaskByDifferent)½Úµã£¬±È½ÏÁ½ÕÅͼƬ²¢Êä³öMask¡£ÐÂÔö[SegmentAnythingUltra](#SegmentAnythingUltra)½Úµã£¬ÌáÉýÕÚÕÖ±ßÔµÖÊÁ¿¡£*Èç¹ûûÓа²×°SegmentAnything, ÐèÒªÊÖ¶¯ÏÂÔØÄ£ÐÍ¡£ @@ -658,13 +659,13 @@ cropped_mask: ¶Ô[ComfyUI Segment Anything](https://github.com/storyicon/comfyui_segment_anything)µÄ¸Ä½ø£¬½áºÏÁËspacepxlµÄ[ComfyUI-Image-Filters](https://github.com/spacepxl/ComfyUI-Image-Filters)µÄAlpha Matte½Úµã£¬Ê¹ÕÚÕÖÓиü¾ßϸ½ÚµÄ±ßÔµ¡£ *Çë²ÎÕÕComfyUI Segment AnythingµÄ°²×°·½·¨°²×°Ä£ÐÍ¡£Èç¹ûÒѾ­ÕýÈ·°²×°ÁËComfyUI Segment Anything£¬¿ÉÌø¹ý´Ë²½Öè¡£ -* ´Ó [ÕâÀï](https://huggingface.co/bert-base-uncased/tree/main) ÏÂÔØ config.json£¬model.safetensors£¬tokenizer_config.json£¬tokenizer.json ºÍ vocab.txt 5¸öÎļþµ½ ComfyUI/models/bert-base-uncasedÎļþ¼Ð¡£ +* ´Ó [ÕâÀï](https://huggingface.co/bert-base-uncased/tree/main) ÏÂÔØ config.json£¬model.safetensors£¬tokenizer_config.json£¬tokenizer.json ºÍ vocab.txt 5¸öÎļþµ½ ```ComfyUI/models/bert-base-uncased```Îļþ¼Ð¡£ * ÏÂÔØ [GroundingDINO_SwinT_OGC config file](https://huggingface.co/ShilongLiu/GroundingDINO/resolve/main/GroundingDINO_SwinT_OGC.cfg.py), [GroundingDINO_SwinT_OGC model](https://huggingface.co/ShilongLiu/GroundingDINO/resolve/main/groundingdino_swint_ogc.pth), -[GroundingDINO_SwinB config file](https://huggingface.co/ShilongLiu/GroundingDINO/resolve/main/GroundingDINO_SwinB.cfg.py), [GroundingDINO_SwinB model](https://huggingface.co/ShilongLiu/GroundingDINO/resolve/main/groundingdino_swinb_cogcoor.pth) µ½ ComfyUI/models/grounding-dinoÎļþ¼Ð¡£ +[GroundingDINO_SwinB config file](https://huggingface.co/ShilongLiu/GroundingDINO/resolve/main/GroundingDINO_SwinB.cfg.py), [GroundingDINO_SwinB model](https://huggingface.co/ShilongLiu/GroundingDINO/resolve/main/groundingdino_swinb_cogcoor.pth) µ½ ```ComfyUI/models/grounding-dino```Îļþ¼Ð¡£ * ÏÂÔØ [sam_vit_h](https://dl.fbaipublicfiles.com/segment_anything/sam_vit_h_4b8939.pth)£¬[sam_vit_l](https://dl.fbaipublicfiles.com/segment_anything/sam_vit_l_0b3195.pth), [sam_vit_b](https://dl.fbaipublicfiles.com/segment_anything/sam_vit_b_01ec64.pth), [sam_hq_vit_h](https://huggingface.co/lkeab/hq-sam/resolve/main/sam_hq_vit_h.pth), [sam_hq_vit_l](https://huggingface.co/lkeab/hq-sam/resolve/main/sam_hq_vit_l.pth), [sam_hq_vit_b](https://huggingface.co/lkeab/hq-sam/resolve/main/sam_hq_vit_b.pth), -[mobile_sam](https://github.com/ChaoningZhang/MobileSAM/blob/master/weights/mobile_sam.pt) Õ⼸¸öÎļþµ½ComfyUI/models/samsÎļþ¼Ð¡£ +[mobile_sam](https://github.com/ChaoningZhang/MobileSAM/blob/master/weights/mobile_sam.pt) Õ⼸¸öÎļþµ½```ComfyUI/models/sams```Îļþ¼Ð¡£ ![image](image/segment_anything_ultra_compare.png) ![image](image/segment_anything_ultra_example.png) @@ -685,7 +686,7 @@ cropped_mask: È¥³ý±³¾°¡£ÓëÀàËÆµÄ±³¾°ÒƳý½ÚµãÏà±È£¬Õâ¸ö½Úµã¾ßÓг¬¸ßµÄ±ßԵϸ½Ú¡£ ±¾½Úµã½áºÏÁËspacepxlµÄ[ComfyUI-Image-Filters](https://github.com/spacepxl/ComfyUI-Image-Filters)µÄAlpha Matte½Úµã£¬ÒÔ¼°ZHO-ZHO-ZHOµÄ[ComfyUI-BRIA_AI-RMBG](https://github.com/ZHO-ZHO-ZHO/ComfyUI-BRIA_AI-RMBG)µÄ¹¦ÄÜ¡£ -*½«[BRIA Background Removal v1.4](https://huggingface.co/briaai/RMBG-1.4)Ä£ÐÍÎļþ(model.pth)ÏÂÔØÖÁ/ComfyUI/models/rmbg/RMBG-1.4Îļþ¼Ð¡£¸ÃÄ£ÐÍÓÉ BRIA AI ¿ª·¢£¬¿É×÷Ϊ·ÇÉÌÒµÓÃ;µÄ¿ªÔ´Ä£ÐÍ¡£ +*½«[BRIA Background Removal v1.4](https://huggingface.co/briaai/RMBG-1.4)Ä£ÐÍÎļþ(model.pth)ÏÂÔØÖÁ```ComfyUI/models/rmbg/RMBG-1.4```Îļþ¼Ð¡£¸ÃÄ£ÐÍÓÉ BRIA AI ¿ª·¢£¬¿É×÷Ϊ·ÇÉÌÒµÓÃ;µÄ¿ªÔ´Ä£ÐÍ¡£ **ÏÂÔØÄ£Ðͺ󣬽¨ÒéÔÚComfyUI/extra_model_paths.yamlÖÐÌí¼ÓÒ»ÐÐ'rmbg: models/rmbg/RMBG-1.4'¡£(´Ë²½Öè·Ç±ØÐ룩 @@ -895,6 +896,17 @@ mask * blur_focus_spread: ½¹µãÀ©É¢·¶Î§¡£ÊýÖµÔ½´ó£¬ÇåÎúµÄ·¶Î§Ô½´ó¡£ * focal_depth: Ä£ÄâÐé½¹µÄ½¹µã¾àÀë¡£0±íʾ½¹µãÔÚ×îÔ¶£¬1±íʾ½¹µãÔÚ×î½ü¡£´ËÏîÉèÖÃÖ»ÔÚdepth_mapÓÐÊäÈëʱ²ÅÉúЧ¡£ +### LightLeak +Ä£Ä⽺Ƭ©¹âЧ¹û¡£ÇëÏÂÔØ[light_leak.pkl(°Ù¶ÈÍøÅÌ)](https://pan.baidu.com/s/1QY1ZyYm885krrqDB2t8lPg?pwd=yvs3)½«Îļþ¸´ÖƵ½```ComfyUI/models/layerstyle``` Îļþ¼Ð¡£ +![image](image/light_leak_example.png) + +½ÚµãÑ¡Ïî˵Ã÷: +![image](image/light_leak_node.png) +* light: ÌṩÁË32ÖÖ¹â°ß¡£randomÎªËæ»úÑ¡Ôñ¡£ +* corner: ¹â°ß³öÏֵĽÇÂ䣬ÓÐ×óÉÏ¡¢ÓÒÉÏ¡¢×óϺÍÓÒÏÂ4¸öÑ¡Ïî¡£ +* hue: ¹â°ßµÄÉ«Ïà¡£ +* saturation: ¹â°ßµÄÉ«²Ê±¥ºÍ¶È¡£ +* opacity: ¹â°ßµÄ²»Í¸Ã÷¶È¡£ ### ColorMap α²ÊÉ«ÈÈÁ¦Í¼Ð§¹û¡£ diff --git a/image/light_leak_example.png b/image/light_leak_example.png new file mode 100644 index 0000000..5d74f2a Binary files /dev/null and b/image/light_leak_example.png differ diff --git a/image/light_leak_node.png b/image/light_leak_node.png new file mode 100644 index 0000000..25c0bd4 Binary files /dev/null and b/image/light_leak_node.png differ diff --git a/py/imagefunc.py b/py/imagefunc.py index b7fd311..6c78603 100644 --- a/py/imagefunc.py +++ b/py/imagefunc.py @@ -55,6 +55,8 @@ except ImportError as e: '''pickle''' + + def read_image(filename:str) -> Image: return Image.open(filename) @@ -67,6 +69,10 @@ def load_pickle(file_name:str) -> object: obj = pickle.load(f) return obj +def load_light_leak_images() -> list: + file = os.path.join(COMFY_FOLDER_PATH.models_dir, "layerstyle", "light_leak.pkl") + return load_pickle(file) + '''Converter''' def cv22ski(cv2_image:np.ndarray) -> np.array: diff --git a/py/light_leak.py b/py/light_leak.py new file mode 100644 index 0000000..f25ac9f --- /dev/null +++ b/py/light_leak.py @@ -0,0 +1,86 @@ +import os.path +import random +import time + +from .imagefunc import * + + +NODE_NAME = 'LightLeak' + +blend_mode = 'screen' + +class LightLeak: + + def __init__(self): + pass + + @classmethod + def INPUT_TYPES(self): + light_list = ['random', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', + '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', + '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', + '31', '32'] + corner_list = ['left_top', 'right_top', 'left_bottom', 'right_bottom'] + return { + "required": { + "image": ("IMAGE", ), + "light": (light_list,), + "corner": (corner_list,), + "hue": ("INT", {"default": 0, "min": -255, "max": 255, "step": 1}), + "saturation": ("INT", {"default": 0, "min": -255, "max": 255, "step": 1}), + "opacity": ("INT", {"default": 100, "min": 0, "max": 100, "step": 1}) + }, + "optional": { + } + } + + RETURN_TYPES = ("IMAGE",) + RETURN_NAMES = ("image",) + FUNCTION = 'light_leak' + CATEGORY = '😺dzNodes/LayerFilter' + OUTPUT_NODE = True + + def light_leak(self, image, light, corner, hue, saturation, opacity): + + ret_images = [] + light_leak_images = load_light_leak_images() + if light == 'random': + random.seed(time.time()) + light_index = random.randint(0,31) + else: + light_index = int(light) - 1 + + for i in image: + i = torch.unsqueeze(i, 0) + _canvas = tensor2pil(i).convert('RGB') + _light = light_leak_images[light_index] + if _canvas.width < _canvas.height: + _light = _light.transpose(Image.ROTATE_90).transpose(Image.FLIP_TOP_BOTTOM) + if corner == 'right_top': + _light = _light.transpose(Image.FLIP_LEFT_RIGHT) + elif corner == 'left_bottom': + _light = _light.transpose(Image.FLIP_TOP_BOTTOM) + elif corner == 'right_bottom': + _light = _light.transpose(Image.ROTATE_180) + if hue != 0 or saturation != 0: + _h, _s, _v = _light.convert('HSV').split() + if hue != 0: + _h = image_hue_offset(_h, hue) + if saturation != 0: + _s = image_gray_offset(_s, saturation) + _light = image_channel_merge((_h, _s, _v), 'HSV') + resize_sampler = Image.BILINEAR + _light = fit_resize_image(_light, _canvas.width, _canvas.height, fit='crop', resize_sampler=resize_sampler) + ret_image = chop_image(_canvas, _light, blend_mode=blend_mode, opacity = opacity) + ret_images.append(pil2tensor(ret_image)) + + log(f"{NODE_NAME} Processed {len(ret_images)} image(s).", message_type='finish') + return (torch.cat(ret_images, dim=0),) + +NODE_CLASS_MAPPINGS = { + "LayerFilter: LightLeak": LightLeak +} + +NODE_DISPLAY_NAME_MAPPINGS = { + "LayerFilter: LightLeak": "LayerFilter: LightLeak" +} \ No newline at end of file