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: ![image](image/pixel_spread_node.png) * 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 @@ 节点选项说明: ![image](image/pixel_spread_node.png) * 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 ] } ],