diff --git a/README.MD b/README.MD
index 8ef4fec..aa65a69 100644
--- a/README.MD
+++ b/README.MD
@@ -575,6 +575,7 @@ Node options:
* detail_range: Edge detail range.
* black_point: Edge black sampling threshold.
* white_point: Edge white sampling threshold.
+* process_detail: Set to false here will skip edge processing to save runtime.
### PixelSpread
Pixel expansion preprocessing on the masked edge of an image can effectively improve the edges of image synthesis.
@@ -583,6 +584,7 @@ Pixel expansion preprocessing on the masked edge of an image can effectively imp
Node options:

* invert_mask: Whether to reverse the mask.
+* mask_grow: Mask expansion amplitude.
diff --git a/README_CN.MD b/README_CN.MD
index 9b343ed..70837c9 100644
--- a/README_CN.MD
+++ b/README_CN.MD
@@ -561,6 +561,7 @@
* detail_range: 边缘细节范围。
* black_point: 边缘黑色采样阈值。
* white_point: 边缘黑色采样阈值。
+* process_detail: 此处设为False将跳过边缘处理以节省运行时间。
### PixelSpread
对图像的遮罩边缘部分进行像素扩张预处理,可有效改善图像合成的边缘。
@@ -569,6 +570,7 @@
节点选项说明:

* invert_mask: 是否反转遮罩。
+* mask_grow: 遮罩扩张幅度。
### MaskGrow
diff --git a/image/layermask_nodes.png b/image/layermask_nodes.png
index 713fe18..4f561de 100644
Binary files a/image/layermask_nodes.png and b/image/layermask_nodes.png differ
diff --git a/image/pixel_spread_example.png b/image/pixel_spread_example.png
index e026134..9e92e93 100644
Binary files a/image/pixel_spread_example.png and b/image/pixel_spread_example.png differ
diff --git a/image/pixel_spread_node.png b/image/pixel_spread_node.png
index 176c060..648730e 100644
Binary files a/image/pixel_spread_node.png and b/image/pixel_spread_node.png differ
diff --git a/image/rembg_ultra_example.png b/image/rembg_ultra_example.png
index 0189831..8e76ccb 100644
Binary files a/image/rembg_ultra_example.png and b/image/rembg_ultra_example.png differ
diff --git a/image/rembg_ultra_node.png b/image/rembg_ultra_node.png
index df83016..a6f0818 100644
Binary files a/image/rembg_ultra_node.png and b/image/rembg_ultra_node.png differ
diff --git a/py/pixel_spread.py b/py/pixel_spread.py
index 8784566..a732035 100644
--- a/py/pixel_spread.py
+++ b/py/pixel_spread.py
@@ -14,6 +14,7 @@ class PixelSpread:
"required": {
"image": ("IMAGE", ), #
"invert_mask": ("BOOLEAN", {"default": False}), # 鍙嶈浆mask
+ "mask_grow": ("INT", {"default": 0, "min": -999, "max": 999, "step": 1}),
},
"optional": {
"mask": ("MASK",), #
@@ -26,15 +27,19 @@ class PixelSpread:
CATEGORY = '馃樅dzNodes/LayerMask'
OUTPUT_NODE = True
- def pixel_spread(self, image, invert_mask, mask=None):
+ def pixel_spread(self, image, invert_mask, mask_grow, mask=None):
_image = tensor2pil(image)
if _image.mode == 'RGBA':
_mask = _image.split()[-1]
+ if mask_grow != 0:
+ _mask = expand_mask(image2mask(_mask), mask_grow, 0) # 鎵╁紶锛屾ā绯�
else:
_mask = Image.new('L', _image.size, 'white')
if mask is not None:
if invert_mask:
mask = 1 - mask
+ if mask_grow != 0:
+ _mask = expand_mask(mask, mask_grow, 0) # 鎵╁紶锛屾ā绯�
_mask = mask2image(mask).convert('L')
image = pil2tensor(_image.convert('RGB'))
_mask = _mask.convert('RGB')
diff --git a/py/rembg_ultra.py b/py/rembg_ultra.py
index ac5bde7..804e168 100644
--- a/py/rembg_ultra.py
+++ b/py/rembg_ultra.py
@@ -34,6 +34,7 @@ class RemBgUltra:
"detail_range": ("INT", {"default": 8, "min": 0, "max": 256, "step": 1}),
"black_point": ("FLOAT", {"default": 0.01, "min": 0.01, "max": 0.98, "step": 0.01}),
"white_point": ("FLOAT", {"default": 0.99, "min": 0.02, "max": 0.99, "step": 0.01}),
+ "process_detail": ("BOOLEAN", {"default": True}),
},
"optional": {
}
@@ -44,7 +45,7 @@ class RemBgUltra:
FUNCTION = "rembg_ultra"
CATEGORY = '馃樅dzNodes/LayerMask'
- def rembg_ultra(self, image, detail_range, black_point, white_point):
+ def rembg_ultra(self, image, detail_range, black_point, white_point, process_detail):
rmbgmodel = load_model()
orig_image = tensor2pil(image).convert('RGB')
@@ -64,19 +65,20 @@ class RemBgUltra:
result = (result-mi)/(ma-mi)
im_array = (result*255).cpu().data.numpy().astype(np.uint8)
_mask = Image.fromarray(np.squeeze(im_array)).convert('L')
- # ultra edge process
- d = detail_range * 2 + 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):
- trimap = a_dup[index][:,:,0] # convert to single channel
- if detail_range > 0:
- trimap = cv2.GaussianBlur(trimap, (d, d), 0)
- trimap = fix_trimap(trimap, black_point, white_point)
- alpha = estimate_alpha_cf(img, trimap, laplacian_kwargs={"epsilon": 1e-6},
- cg_kwargs={"maxiter": 500})
- a_dup[index] = np.stack([alpha, alpha, alpha], axis=-1) # convert back to rgb
- _mask = tensor2pil(torch.from_numpy(a_dup.astype(np.float32))) # alpha
+ if process_detail:
+ # ultra edge process
+ d = detail_range * 2 + 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):
+ trimap = a_dup[index][:,:,0] # convert to single channel
+ if detail_range > 0:
+ trimap = cv2.GaussianBlur(trimap, (d, d), 0)
+ trimap = fix_trimap(trimap, black_point, white_point)
+ alpha = estimate_alpha_cf(img, trimap, laplacian_kwargs={"epsilon": 1e-6},
+ cg_kwargs={"maxiter": 500})
+ a_dup[index] = np.stack([alpha, alpha, alpha], axis=-1) # convert back to rgb
+ _mask = tensor2pil(torch.from_numpy(a_dup.astype(np.float32))) # alpha
ret_image = RGB2RGBA(orig_image, _mask.convert('L'))
return (pil2tensor(ret_image), image2mask(_mask),)
diff --git a/workflow/pixel_spread_example.json b/workflow/pixel_spread_example.json
index 8adef58..19ccb1d 100644
--- a/workflow/pixel_spread_example.json
+++ b/workflow/pixel_spread_example.json
@@ -9,10 +9,10 @@
490,
660
],
- "size": {
- "0": 330.9508972167969,
- "1": 298.0813903808594
- },
+ "size": [
+ 330.9508972167969,
+ 314
+ ],
"flags": {},
"order": 0,
"mode": 0,
@@ -51,7 +51,7 @@
],
"size": {
"0": 315,
- "1": 126
+ "1": 150
},
"flags": {},
"order": 1,
@@ -87,34 +87,10 @@
"widgets_values": [
10,
0.01,
- 0.99
+ 0.99,
+ true
]
},
- {
- "id": 41,
- "type": "LayerMask: MaskPreview",
- "pos": [
- 1247,
- 802
- ],
- "size": {
- "0": 309.01806640625,
- "1": 246
- },
- "flags": {},
- "order": 2,
- "mode": 0,
- "inputs": [
- {
- "name": "mask",
- "type": "MASK",
- "link": 75
- }
- ],
- "properties": {
- "Node name for S&R": "LayerMask: MaskPreview"
- }
- },
{
"id": 42,
"type": "PreviewImage",
@@ -149,7 +125,7 @@
],
"size": {
"0": 315,
- "1": 78
+ "1": 102
},
"flags": {},
"order": 3,
@@ -181,8 +157,34 @@
"Node name for S&R": "LayerMask: PixelSpread"
},
"widgets_values": [
- false
+ false,
+ 0
]
+ },
+ {
+ "id": 41,
+ "type": "LayerMask: MaskPreview",
+ "pos": [
+ 1244,
+ 827
+ ],
+ "size": {
+ "0": 309.01806640625,
+ "1": 246
+ },
+ "flags": {},
+ "order": 2,
+ "mode": 0,
+ "inputs": [
+ {
+ "name": "mask",
+ "type": "MASK",
+ "link": 75
+ }
+ ],
+ "properties": {
+ "Node name for S&R": "LayerMask: MaskPreview"
+ }
}
],
"links": [
diff --git a/workflow/rembg_ultra_example.json b/workflow/rembg_ultra_example.json
index 182de1b..0a251f0 100644
--- a/workflow/rembg_ultra_example.json
+++ b/workflow/rembg_ultra_example.json
@@ -452,7 +452,7 @@
],
"size": {
"0": 315,
- "1": 78
+ "1": 102
},
"flags": {},
"order": 7,
@@ -484,19 +484,20 @@
"Node name for S&R": "LayerMask: PixelSpread"
},
"widgets_values": [
- false
+ false,
+ 0
]
},
{
"id": 29,
"type": "LayerMask: RemBgUltra",
"pos": [
- 1124,
- 1484
+ 1126,
+ 1519
],
"size": {
"0": 315,
- "1": 126
+ "1": 150
},
"flags": {},
"order": 4,
@@ -533,7 +534,8 @@
"widgets_values": [
10,
0.01,
- 0.99
+ 0.99,
+ true
]
}
],