add Alpha Clean node
This commit is contained in:
@@ -7,6 +7,81 @@ import cv2
|
||||
from cv2.ximgproc import guidedFilter
|
||||
import copy
|
||||
|
||||
class AlphaClean:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
return {
|
||||
"required": {
|
||||
"image": ("IMAGE",),
|
||||
"radius": ("INT", {
|
||||
"default": 8,
|
||||
"min": 1,
|
||||
"max": 64,
|
||||
"step": 1
|
||||
}),
|
||||
"fill_holes": ("INT", {
|
||||
"default": 1,
|
||||
"min": 0,
|
||||
"max": 16,
|
||||
"step": 1
|
||||
}),
|
||||
"white_threshold": ("FLOAT", {
|
||||
"default": 0.9,
|
||||
"min": 0.01,
|
||||
"max": 1.0,
|
||||
"step": 0.01
|
||||
}),
|
||||
"extra_clip": ("FLOAT", {
|
||||
"default": 0.98,
|
||||
"min": 0.01,
|
||||
"max": 1.0,
|
||||
"step": 0.01
|
||||
}),
|
||||
},
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("IMAGE",)
|
||||
FUNCTION = "alpha_clean"
|
||||
|
||||
CATEGORY = "image/filters"
|
||||
|
||||
def alpha_clean(self, image: torch.Tensor, radius: int, fill_holes: int, white_threshold: float, extra_clip: float):
|
||||
|
||||
d = radius * 2 + 1
|
||||
i_dup = copy.deepcopy(image.cpu().numpy())
|
||||
|
||||
for i in range(len(i_dup)):
|
||||
work_img = i_dup[i]
|
||||
|
||||
cleaned = cv2.bilateralFilter(work_img, 9, 0.05, 8)
|
||||
|
||||
alpha = np.clip((work_img - white_threshold) / (1 - white_threshold), 0, 1)
|
||||
rgb = work_img * alpha
|
||||
|
||||
alpha = cv2.GaussianBlur(alpha, (d,d), 0) * 0.99 + np.average(alpha) * 0.01
|
||||
rgb = cv2.GaussianBlur(rgb, (d,d), 0) * 0.99 + np.average(rgb) * 0.01
|
||||
|
||||
rgb = rgb / np.clip(alpha, 0.00001, 1)
|
||||
rgb = rgb * extra_clip
|
||||
|
||||
cleaned = np.clip(cleaned / rgb, 0, 1)
|
||||
|
||||
if fill_holes > 0:
|
||||
fD = fill_holes * 2 + 1
|
||||
gamma = cleaned * cleaned
|
||||
kD = np.ones((fD, fD), np.uint8)
|
||||
kE = np.ones((fD + 2, fD + 2), np.uint8)
|
||||
gamma = cv2.dilate(gamma, kD, iterations=1)
|
||||
gamma = cv2.erode(gamma, kE, iterations=1)
|
||||
gamma = cv2.GaussianBlur(gamma, (fD, fD), 0)
|
||||
cleaned = np.maximum(cleaned, gamma)
|
||||
|
||||
i_dup[i] = cleaned
|
||||
|
||||
return (torch.from_numpy(i_dup),)
|
||||
|
||||
class EnhanceDetail:
|
||||
def __init__(self):
|
||||
@@ -159,12 +234,14 @@ class RemapRange:
|
||||
|
||||
|
||||
NODE_CLASS_MAPPINGS = {
|
||||
"AlphaClean": AlphaClean,
|
||||
"EnhanceDetail": EnhanceDetail,
|
||||
"GuidedFilterAlpha": GuidedFilterAlpha,
|
||||
"RemapRange": RemapRange,
|
||||
}
|
||||
|
||||
NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
"AlphaClean": "Alpha Clean",
|
||||
"EnhanceDetail": "Enhance Detail",
|
||||
"GuidedFilterAlpha": "Guided Filter Alpha",
|
||||
"RemapRange": "Remap Range",
|
||||
|
||||
Reference in New Issue
Block a user