update readme
This commit is contained in:
@@ -1,2 +1,3 @@
|
|||||||
|
_test_*.*
|
||||||
__pycache__
|
__pycache__
|
||||||
model.pth
|
model.pth
|
||||||
@@ -13,7 +13,7 @@ Nodes are divided into 5 groups according to their functions: LayerStyle, LayerC
|
|||||||
[中文说明点这里](./README_CN.MD)
|
[中文说明点这里](./README_CN.MD)
|
||||||
|
|
||||||
## Update
|
## 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.
|
* 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.
|
* 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.)
|
(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.)
|
||||||
|
|||||||
+1
-1
@@ -10,7 +10,7 @@
|
|||||||
* [LayerFilter](#LayerFilter)节点组提供图像效果滤镜。
|
* [LayerFilter](#LayerFilter)节点组提供图像效果滤镜。
|
||||||
|
|
||||||
## 更新说明
|
## 更新说明
|
||||||
**由于引入新的节点,请重新安装依赖包。
|
**如果本插件更新后出现依赖包错误,请重新安装相关依赖包。详情见[这里](https://github.com/chflame163/ComfyUI_LayerStyle/issues/5)。
|
||||||
* 新增[Sharp & Soft](#Sharp)节点,可提升或抹平图像细节。新增[MaskByDifferent](#MaskByDifferent)节点,比较两张图片并输出Mask。新增[SegmentAnythingUltra](#SegmentAnythingUltra)节点,提升遮罩边缘质量。*如果没有安装SegmentAnything, 需要手动下载模型。
|
* 新增[Sharp & Soft](#Sharp)节点,可提升或抹平图像细节。新增[MaskByDifferent](#MaskByDifferent)节点,比较两张图片并输出Mask。新增[SegmentAnythingUltra](#SegmentAnythingUltra)节点,提升遮罩边缘质量。*如果没有安装SegmentAnything, 需要手动下载模型。
|
||||||
* 所有节点已全面支持批量图片,为创作视频提供方便。( CropByMask 节点仅支持相同尺寸的切除, 如果输入批量mask_for_crop,将使用第一张的数据。)
|
* 所有节点已全面支持批量图片,为创作视频提供方便。( CropByMask 节点仅支持相同尺寸的切除, 如果输入批量mask_for_crop,将使用第一张的数据。)
|
||||||
* 添加[RemBgUltra](#RemBgUltra) 和 [PixelSpread](#PixelSpread) 节点,显著提升了遮罩质量。*RemBgUltra需手动下载模型。
|
* 添加[RemBgUltra](#RemBgUltra) 和 [PixelSpread](#PixelSpread) 节点,显著提升了遮罩质量。*RemBgUltra需手动下载模型。
|
||||||
|
|||||||
+26
-4
@@ -16,17 +16,24 @@ import time
|
|||||||
from typing import Union, List
|
from typing import Union, List
|
||||||
from PIL import Image, ImageFilter, ImageChops, ImageDraw, ImageOps, ImageEnhance, ImageFont
|
from PIL import Image, ImageFilter, ImageChops, ImageDraw, ImageOps, ImageEnhance, ImageFont
|
||||||
from skimage import img_as_float, img_as_ubyte
|
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 torchvision.transforms.functional as TF
|
||||||
import torch.nn.functional as F
|
import torch.nn.functional as F
|
||||||
import colorsys
|
import colorsys
|
||||||
from .briarmbg import BriaRMBG
|
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__))
|
current_directory = os.path.dirname(os.path.abspath(__file__))
|
||||||
device = "cuda" if torch.cuda.is_available() else "cpu"
|
device = "cuda" if torch.cuda.is_available() else "cpu"
|
||||||
|
|
||||||
def log(message):
|
def log(message:str, message_type:str='info'):
|
||||||
name = 'LayerStyle'
|
name = 'LayerStyle'
|
||||||
|
if message_type == 'error':
|
||||||
|
message = '\033[33m' + message + '\033[m'
|
||||||
print(f"# 😺dzNodes: {name} -> {message}")
|
print(f"# 😺dzNodes: {name} -> {message}")
|
||||||
|
|
||||||
'''Converter'''
|
'''Converter'''
|
||||||
@@ -668,8 +675,7 @@ def RMBG(image:Image) -> Image:
|
|||||||
return _mask
|
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:
|
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 * 5 + 1
|
||||||
d = detail_range * 2 + 1
|
|
||||||
i_dup = copy.deepcopy(image.cpu().numpy().astype(np.float64))
|
i_dup = copy.deepcopy(image.cpu().numpy().astype(np.float64))
|
||||||
a_dup = copy.deepcopy(pil2tensor(mask.convert('RGB')).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):
|
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
|
a_dup[index] = np.stack([alpha, alpha, alpha], axis=-1) # convert back to rgb
|
||||||
return torch.from_numpy(a_dup.astype(np.float32))
|
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:
|
def mask_fix(images:torch.Tensor, radius:int, fill_holes:int, white_threshold:float, extra_clip:float) -> torch.Tensor:
|
||||||
d = radius * 2 + 1
|
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
|
i_dup[index] = cleaned
|
||||||
return torch.from_numpy(i_dup)
|
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:
|
def expand_mask(mask:torch.Tensor, grow:int, blur:int) -> torch.Tensor:
|
||||||
# grow
|
# grow
|
||||||
c = 0
|
c = 0
|
||||||
|
|||||||
@@ -15,9 +15,9 @@ class MaskByDifferent:
|
|||||||
"image_1": ("IMAGE", ), #
|
"image_1": ("IMAGE", ), #
|
||||||
"image_2": ("IMAGE",), #
|
"image_2": ("IMAGE",), #
|
||||||
"gain": ("FLOAT", {"default": 1.5, "min": 0.1, "max": 100, "step": 0.1}),
|
"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_gap": ("INT", {"default": 4, "min": 0, "max": 32, "step": 1}),
|
||||||
"fix_threshold": ("FLOAT", {"default": 0.75, "min": 0.01, "max": 1.0, "step": 0.01}),
|
"fix_threshold": ("FLOAT", {"default": 0.75, "min": 0.01, "max": 0.99, "step": 0.01}),
|
||||||
"main_subject_detect": ("BOOLEAN", {"default": True}),
|
"main_subject_detect": ("BOOLEAN", {"default": False}),
|
||||||
},
|
},
|
||||||
"optional": {
|
"optional": {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
from pymatting import estimate_foreground_ml
|
|
||||||
from .imagefunc import *
|
from .imagefunc import *
|
||||||
|
|
||||||
NODE_NAME = 'PixelSpread'
|
NODE_NAME = 'PixelSpread'
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
import torch
|
|
||||||
|
|
||||||
from .imagefunc import *
|
from .imagefunc import *
|
||||||
from .segment_anything_func import *
|
from .segment_anything_func import *
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
from cv2.ximgproc import guidedFilter
|
|
||||||
from .imagefunc import *
|
from .imagefunc import *
|
||||||
|
|
||||||
NODE_NAME = 'Sharp & Soft'
|
NODE_NAME = 'Sharp & Soft'
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ pillow
|
|||||||
torch
|
torch
|
||||||
matplotlib
|
matplotlib
|
||||||
Scipy
|
Scipy
|
||||||
opencv-python
|
|
||||||
scikit_image
|
scikit_image
|
||||||
opencv-contrib-python
|
opencv-contrib-python
|
||||||
pymatting
|
pymatting
|
||||||
|
|||||||
Reference in New Issue
Block a user