From 48066ea5fa7a07316a2454d52fa01fdbfd8916e8 Mon Sep 17 00:00:00 2001 From: chflame163 Date: Thu, 15 Feb 2024 16:02:25 +0800 Subject: [PATCH] update readme --- .gitignore | 1 + README.MD | 2 +- README_CN.MD | 2 +- py/imagefunc.py | 30 ++++++++++++++++++++++++++---- py/mask_by_different.py | 6 +++--- py/pixel_spread.py | 1 - py/segment_anything_ultra.py | 2 -- py/sharp&soft.py | 1 - requirements.txt | 1 - 9 files changed, 32 insertions(+), 14 deletions(-) diff --git a/.gitignore b/.gitignore index afe85e9..e48573b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ +_test_*.* __pycache__ model.pth \ No newline at end of file diff --git a/README.MD b/README.MD index dece96c..055d5e6 100644 --- a/README.MD +++ b/README.MD @@ -13,7 +13,7 @@ Nodes are divided into 5 groups according to their functions: LayerStyle, LayerC [中文说明点这里](./README_CN.MD) ## Update -**Due to the new nodes, if error occurs during runtime, please reinstall the dependency package. +**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 [Sharp & Soft](#Sharp) node, it can enhance or smooth out image details. Commit [MaskByDifferent](#MaskByDifferent) node, it compare two images and output a Mask. Commit [SegmentAnythingUltra](#SegmentAnythingUltra) node, Improve the quality of mask edges. *If SegmentAnything is not installed, you will need to manually download the model. * All nodes have fully supported batch images, providing convenience for video creation. (The CropByMask node only supports cuts of the same size. if a batch mask_for_crop inputted, the data from the first sheet will be used.) diff --git a/README_CN.MD b/README_CN.MD index 98155f4..91639f6 100644 --- a/README_CN.MD +++ b/README_CN.MD @@ -10,7 +10,7 @@ * [LayerFilter](#LayerFilter)½Úµã×éÌṩͼÏñЧ¹ûÂ˾µ¡£ ## ¸üÐÂ˵Ã÷ -**ÓÉÓÚÒýÈëеĽڵ㣬ÇëÖØÐ°²×°ÒÀÀµ°ü¡£ +**Èç¹û±¾²å¼þ¸üкó³öÏÖÒÀÀµ°ü´íÎó£¬ÇëÖØÐ°²×°Ïà¹ØÒÀÀµ°ü¡£ÏêÇé¼û[ÕâÀï](https://github.com/chflame163/ComfyUI_LayerStyle/issues/5)¡£ * ÐÂÔö[Sharp & Soft](#Sharp)½Úµã£¬¿ÉÌáÉý»òĨƽͼÏñϸ½Ú¡£ÐÂÔö[MaskByDifferent](#MaskByDifferent)½Úµã£¬±È½ÏÁ½ÕÅͼƬ²¢Êä³öMask¡£ÐÂÔö[SegmentAnythingUltra](#SegmentAnythingUltra)½Úµã£¬ÌáÉýÕÚÕÖ±ßÔµÖÊÁ¿¡£*Èç¹ûûÓа²×°SegmentAnything, ÐèÒªÊÖ¶¯ÏÂÔØÄ£ÐÍ¡£ * ËùÓнڵãÒÑÈ«ÃæÖ§³ÖÅúÁ¿Í¼Æ¬£¬Îª´´×÷ÊÓÆµÌṩ·½±ã¡£( CropByMask ½Úµã½öÖ§³ÖÏàͬ³ß´çµÄÇгý, Èç¹ûÊäÈëÅúÁ¿mask_for_crop£¬½«Ê¹ÓõÚÒ»ÕŵÄÊý¾Ý¡£) * Ìí¼Ó[RemBgUltra](#RemBgUltra) ºÍ [PixelSpread](#PixelSpread) ½Úµã£¬ÏÔÖøÌáÉýÁËÕÚÕÖÖÊÁ¿¡£*RemBgUltraÐèÊÖ¶¯ÏÂÔØÄ£ÐÍ¡£ diff --git a/py/imagefunc.py b/py/imagefunc.py index d497f91..ff93626 100644 --- a/py/imagefunc.py +++ b/py/imagefunc.py @@ -16,17 +16,24 @@ import time from typing import Union, List from PIL import Image, ImageFilter, ImageChops, ImageDraw, ImageOps, ImageEnhance, ImageFont from skimage import img_as_float, img_as_ubyte -from pymatting import fix_trimap, estimate_alpha_cf +from pymatting import fix_trimap, estimate_alpha_cf, estimate_foreground_ml import torchvision.transforms.functional as TF import torch.nn.functional as F import colorsys from .briarmbg import BriaRMBG +try: + from cv2.ximgproc import guidedFilter +except ImportError: + print(f'# 😺dzNodes: \033[33mDependency package error -> Unable import "guidedFilter", please reinstall "opencv-contrib-python"\033[m') + current_directory = os.path.dirname(os.path.abspath(__file__)) device = "cuda" if torch.cuda.is_available() else "cpu" -def log(message): +def log(message:str, message_type:str='info'): name = 'LayerStyle' + if message_type == 'error': + message = '\033[33m' + message + '\033[m' print(f"# 😺dzNodes: {name} -> {message}") '''Converter''' @@ -668,8 +675,7 @@ def RMBG(image:Image) -> Image: return _mask def mask_edge_detail(image:torch.Tensor, mask:Image, detail_range:int=8, black_point:float=0.01, white_point:float=0.99) -> torch.Tensor: - - d = detail_range * 2 + 1 + d = detail_range * 5 + 1 i_dup = copy.deepcopy(image.cpu().numpy().astype(np.float64)) a_dup = copy.deepcopy(pil2tensor(mask.convert('RGB')).cpu().numpy().astype(np.float64)) for index, img in enumerate(i_dup): @@ -682,6 +688,15 @@ def mask_edge_detail(image:torch.Tensor, mask:Image, detail_range:int=8, black_p a_dup[index] = np.stack([alpha, alpha, alpha], axis=-1) # convert back to rgb return torch.from_numpy(a_dup.astype(np.float32)) +def guided_filter_alpha(image:torch.Tensor, mask:Image, filter_radius:int, sigma:float) -> torch.Tensor: + d = filter_radius + 1 + s = sigma / 10 + i_dup = copy.deepcopy(image.cpu().numpy()) + a_dup = copy.deepcopy(pil2tensor(mask.convert('RGB')).cpu().numpy()) + for index, image in enumerate(i_dup): + alpha_work = a_dup[index] + i_dup[index] = guidedFilter(image, alpha_work, d, s) + return torch.from_numpy(i_dup) def mask_fix(images:torch.Tensor, radius:int, fill_holes:int, white_threshold:float, extra_clip:float) -> torch.Tensor: d = radius * 2 + 1 @@ -707,6 +722,13 @@ def mask_fix(images:torch.Tensor, radius:int, fill_holes:int, white_threshold:fl i_dup[index] = cleaned return torch.from_numpy(i_dup) +def histogram_remap(image:torch.Tensor, blackpoint:float, whitepoint:float) -> torch.Tensor: + bp = min(blackpoint, whitepoint - 0.001) + scale = 1 / (whitepoint - bp) + i_dup = copy.deepcopy(image.cpu().numpy()) + i_dup = np.clip((i_dup - bp) * scale, 0.0, 1.0) + return torch.from_numpy(i_dup) + def expand_mask(mask:torch.Tensor, grow:int, blur:int) -> torch.Tensor: # grow c = 0 diff --git a/py/mask_by_different.py b/py/mask_by_different.py index c4f361f..8309761 100644 --- a/py/mask_by_different.py +++ b/py/mask_by_different.py @@ -15,9 +15,9 @@ class MaskByDifferent: "image_1": ("IMAGE", ), # "image_2": ("IMAGE",), # "gain": ("FLOAT", {"default": 1.5, "min": 0.1, "max": 100, "step": 0.1}), - "fix_gap": ("INT", {"default": 4, "min": 0, "max": 16, "step": 1}), - "fix_threshold": ("FLOAT", {"default": 0.75, "min": 0.01, "max": 1.0, "step": 0.01}), - "main_subject_detect": ("BOOLEAN", {"default": True}), + "fix_gap": ("INT", {"default": 4, "min": 0, "max": 32, "step": 1}), + "fix_threshold": ("FLOAT", {"default": 0.75, "min": 0.01, "max": 0.99, "step": 0.01}), + "main_subject_detect": ("BOOLEAN", {"default": False}), }, "optional": { } diff --git a/py/pixel_spread.py b/py/pixel_spread.py index 881e2ed..3df6b2b 100644 --- a/py/pixel_spread.py +++ b/py/pixel_spread.py @@ -1,4 +1,3 @@ -from pymatting import estimate_foreground_ml from .imagefunc import * NODE_NAME = 'PixelSpread' diff --git a/py/segment_anything_ultra.py b/py/segment_anything_ultra.py index 8a49530..690b05d 100644 --- a/py/segment_anything_ultra.py +++ b/py/segment_anything_ultra.py @@ -1,5 +1,3 @@ -import torch - from .imagefunc import * from .segment_anything_func import * diff --git a/py/sharp&soft.py b/py/sharp&soft.py index 7ec7e99..f7197bb 100644 --- a/py/sharp&soft.py +++ b/py/sharp&soft.py @@ -1,4 +1,3 @@ -from cv2.ximgproc import guidedFilter from .imagefunc import * NODE_NAME = 'Sharp & Soft' diff --git a/requirements.txt b/requirements.txt index 392cb65..8d005b8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,7 +3,6 @@ pillow torch matplotlib Scipy -opencv-python scikit_image opencv-contrib-python pymatting