diff --git a/BiRefNet_node_config.py b/BiRefNet_node_config.py deleted file mode 100644 index 4b4f600..0000000 --- a/BiRefNet_node_config.py +++ /dev/null @@ -1,148 +0,0 @@ -### config.py - -import os -import math - -os.environ['HOME'] = os.path.expanduser("~") -class Config(): - def __init__(self) -> None: - # PATH settings - self.sys_home_dir = os.environ['HOME'] # Make up your file system as: SYS_HOME_DIR/codes/dis/BiRefNet, SYS_HOME_DIR/datasets/dis/xx, SYS_HOME_DIR/weights/xx - # TASK settings - self.task = ['DIS5K', 'COD', 'HRSOD', 'DIS5K+HRSOD+HRS10K', 'P3M-10k'][0] - self.training_set = { - 'DIS5K': ['DIS-TR', 'DIS-TR+DIS-TE1+DIS-TE2+DIS-TE3+DIS-TE4'][0], - 'COD': 'TR-COD10K+TR-CAMO', - 'HRSOD': ['TR-DUTS', 'TR-HRSOD', 'TR-UHRSD', 'TR-DUTS+TR-HRSOD', 'TR-DUTS+TR-UHRSD', 'TR-HRSOD+TR-UHRSD', 'TR-DUTS+TR-HRSOD+TR-UHRSD'][5], - 'DIS5K+HRSOD+HRS10K': 'DIS-TE1+DIS-TE2+DIS-TE3+DIS-TE4+DIS-TR+TE-HRS10K+TE-HRSOD+TE-UHRSD+TR-HRS10K+TR-HRSOD+TR-UHRSD', # leave DIS-VD for evaluation. - 'P3M-10k': 'TR-P3M-10k', - }[self.task] - self.prompt4loc = ['dense', 'sparse'][0] - - # Faster-Training settings - self.load_all = True - self.compile = True # 1. Trigger CPU memory leak in some extend, which is an inherent problem of PyTorch. - # Machines with > 70GB CPU memory can run the whole training on DIS5K with default setting. - # 2. Higher PyTorch version may fix it: https://github.com/pytorch/pytorch/issues/119607. - # 3. But compile in Pytorch > 2.0.1 seems to bring no acceleration for training. - self.precisionHigh = True - - # MODEL settings - self.ms_supervision = True - self.out_ref = self.ms_supervision and True - self.dec_ipt = True - self.dec_ipt_split = True - self.cxt_num = [0, 3][1] # multi-scale skip connections from encoder - self.mul_scl_ipt = ['', 'add', 'cat'][2] - self.dec_att = ['', 'ASPP', 'ASPPDeformable'][2] - self.squeeze_block = ['', 'BasicDecBlk_x1', 'ResBlk_x4', 'ASPP_x3', 'ASPPDeformable_x3'][1] - self.dec_blk = ['BasicDecBlk', 'ResBlk', 'HierarAttDecBlk'][0] - - # TRAINING settings - self.batch_size = 4 - self.IoU_finetune_last_epochs = [ - 0, - { - 'DIS5K': -50, - 'COD': -20, - 'HRSOD': -20, - 'DIS5K+HRSOD+HRS10K': -20, - 'P3M-10k': -20, - }[self.task] - ][1] # choose 0 to skip - self.lr = (1e-4 if 'DIS5K' in self.task else 1e-5) * math.sqrt(self.batch_size / 4) # DIS needs high lr to converge faster. Adapt the lr linearly - self.size = 1024 - self.num_workers = max(4, self.batch_size) # will be decrease to min(it, batch_size) at the initialization of the data_loader - - # Backbone settings - self.bb = [ - 'vgg16', 'vgg16bn', 'resnet50', # 0, 1, 2 - 'swin_v1_t', 'swin_v1_s', # 3, 4 - 'swin_v1_b', 'swin_v1_l', # 5-bs9, 6-bs4 - 'pvt_v2_b0', 'pvt_v2_b1', # 7, 8 - 'pvt_v2_b2', 'pvt_v2_b5', # 9-bs10, 10-bs5 - ][6] - self.lateral_channels_in_collection = { - 'vgg16': [512, 256, 128, 64], 'vgg16bn': [512, 256, 128, 64], 'resnet50': [1024, 512, 256, 64], - 'pvt_v2_b2': [512, 320, 128, 64], 'pvt_v2_b5': [512, 320, 128, 64], - 'swin_v1_b': [1024, 512, 256, 128], 'swin_v1_l': [1536, 768, 384, 192], - 'swin_v1_t': [768, 384, 192, 96], 'swin_v1_s': [768, 384, 192, 96], - 'pvt_v2_b0': [256, 160, 64, 32], 'pvt_v2_b1': [512, 320, 128, 64], - }[self.bb] - if self.mul_scl_ipt == 'cat': - self.lateral_channels_in_collection = [channel * 2 for channel in self.lateral_channels_in_collection] - self.cxt = self.lateral_channels_in_collection[1:][::-1][-self.cxt_num:] if self.cxt_num else [] - - # MODEL settings - inactive - self.lat_blk = ['BasicLatBlk'][0] - self.dec_channels_inter = ['fixed', 'adap'][0] - self.refine = ['', 'itself', 'RefUNet', 'Refiner', 'RefinerPVTInChannels4'][0] - self.progressive_ref = self.refine and True - self.ender = self.progressive_ref and False - self.scale = self.progressive_ref and 2 - self.auxiliary_classification = False # Only for DIS5K, where class labels are saved in `dataset.py`. - self.refine_iteration = 1 - self.freeze_bb = False - self.model = [ - 'BiRefNet', - ][0] - if self.dec_blk == 'HierarAttDecBlk': - self.batch_size = 2 ** [0, 1, 2, 3, 4][2] - - # TRAINING settings - inactive - self.preproc_methods = ['flip', 'enhance', 'rotate', 'pepper', 'crop'][:4] - self.optimizer = ['Adam', 'AdamW'][1] - self.lr_decay_epochs = [1e5] # Set to negative N to decay the lr in the last N-th epoch. - self.lr_decay_rate = 0.5 - # Loss - self.lambdas_pix_last = { - # not 0 means opening this loss - # original rate -- 1 : 30 : 1.5 : 0.2, bce x 30 - 'bce': 30 * 1, # high performance - 'iou': 0.5 * 1, # 0 / 255 - 'iou_patch': 0.5 * 0, # 0 / 255, win_size = (64, 64) - 'mse': 150 * 0, # can smooth the saliency map - 'triplet': 3 * 0, - 'reg': 100 * 0, - 'ssim': 10 * 1, # help contours, - 'cnt': 5 * 0, # help contours - 'structure': 5 * 0, # structure loss from codes of MVANet. A little improvement on DIS-TE[1,2,3], a bit more decrease on DIS-TE4. - } - self.lambdas_cls = { - 'ce': 5.0 - } - # Adv - self.lambda_adv_g = 10. * 0 # turn to 0 to avoid adv training - self.lambda_adv_d = 3. * (self.lambda_adv_g > 0) - - # PATH settings - inactive - self.data_root_dir = os.path.join(self.sys_home_dir, 'datasets/dis') - self.weights_root_dir = os.path.join(self.sys_home_dir, 'weights') - self.weights = { - 'pvt_v2_b2': os.path.join(self.weights_root_dir, 'pvt_v2_b2.pth'), - 'pvt_v2_b5': os.path.join(self.weights_root_dir, ['pvt_v2_b5.pth', 'pvt_v2_b5_22k.pth'][0]), - 'swin_v1_b': os.path.join(self.weights_root_dir, ['swin_base_patch4_window12_384_22kto1k.pth', 'swin_base_patch4_window12_384_22k.pth'][0]), - 'swin_v1_l': os.path.join(self.weights_root_dir, ['swin_large_patch4_window12_384_22kto1k.pth', 'swin_large_patch4_window12_384_22k.pth'][0]), - 'swin_v1_t': os.path.join(self.weights_root_dir, ['swin_tiny_patch4_window7_224_22kto1k_finetune.pth'][0]), - 'swin_v1_s': os.path.join(self.weights_root_dir, ['swin_small_patch4_window7_224_22kto1k_finetune.pth'][0]), - 'pvt_v2_b0': os.path.join(self.weights_root_dir, ['pvt_v2_b0.pth'][0]), - 'pvt_v2_b1': os.path.join(self.weights_root_dir, ['pvt_v2_b1.pth'][0]), - } - - # Callbacks - inactive - self.verbose_eval = True - self.only_S_MAE = False - self.use_fp16 = False # Bugs. It may cause nan in training. - self.SDPA_enabled = False # Bugs. Slower and errors occur in multi-GPUs - - # others - self.device = [0, 'cpu'][0] # .to(0) == .to('cuda:0') - - self.batch_size_valid = 1 - self.rand_seed = 7 - # run_sh_file = [f for f in os.listdir('.') if 'train.sh' == f] + [os.path.join('..', f) for f in os.listdir('..') if 'train.sh' == f] - # with open(run_sh_file[0], 'r') as f: - # lines = f.readlines() - # self.save_last = int([l.strip() for l in lines if '"{}")'.format(self.task) in l and 'val_last=' in l][0].split('val_last=')[-1].split()[0]) - # self.save_step = int([l.strip() for l in lines if '"{}")'.format(self.task) in l and 'step=' in l][0].split('step=')[-1].split()[0]) - # self.val_step = [0, self.save_step][0] \ No newline at end of file diff --git a/README.md b/README.md index a070a0f..3bd918c 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,16 @@ ___ 示例工作流放置在`ComfyUI-BiRefNet-Hugo/workflow`中
The demo workflow placed in `ComfyUI-BiRefNet-Hugo/workflow` + +加载模型支持两种方式,一种是自动下载远程模型并加载模型,另外一种是加载本地模型。加载本地模型的时候需要把load_local_model设置为true,并把local_model_path设置为本地模型所在路径,例如:H:\ZhengPeng7\BiRefNet
+Loading the model supports two methods: one is to automatically download and load a remote model, and the other is to load a local model. When loading a local model, you need to set 'load_local_model' to true and 'local_model_path' to the path where the local model is located, for example: H:\ZhengPeng7\BiRefNet. + +![](./assets/e21c32bf-ab98-444a-8055-54975ac47da3.png) + +模型下载地址:https://huggingface.co/ZhengPeng7/BiRefNet/tree/main
+Model download address: https://huggingface.co/ZhengPeng7/BiRefNet/tree/main + + ___ 工作流workflow.json的使用
The use of workflow.json @@ -41,6 +51,8 @@ ___ ![](./assets/demo3.gif) +![](./assets/demo4.gif) + ## 社交账号 | Social Account Homepage - Bilibili:[我的B站主页](https://space.bilibili.com/1303099255) @@ -49,20 +61,7 @@ ___ 感谢BiRefNet仓库的所有作者 [ZhengPeng7/BiRefNet](https://github.com/zhengpeng7/birefnet) Thanks to BiRefNet repo owner [ZhengPeng7/BiRefNet](https://github.com/zhengpeng7/birefnet) -``` -library_name: birefnet -tags: - - background-removal - - mask-generation - - Dichotomous Image Segmentation:二分图像分割(DIS),指分割成前景与背景,二个集合,分割出高精度效果。 - - Camouflaged Object Detection:伪装物体检测(COD),偏工程向,旨在识别“无缝”嵌入到周围环境中的物体,例如野生动物保护、军事侦察或者工业自动化。 - - Salient Object Detection:显著性目标检测(SOD),自动检测图像中最具视觉吸引力的部分。 - - pytorch_model_hub_mixin - - model_hub_mixin -repo_url: https://github.com/ZhengPeng7/BiRefNet -pipeline_tag: image-segmentation -license: mit -``` + 部分代码参考了 [ZHO-ZHO-ZHO/ComfyUI-BiRefNet-ZHO](https://github.com/ZHO-ZHO-ZHO/ComfyUI-BiRefNet-ZHO) 感谢! Some of the code references [ZHO-ZHO-ZHO/ComfyUI-BiRefNet-ZHO](https://github.com/ZHO-ZHO-ZHO/ComfyUI-BiRefNet-ZHO) Thanks! diff --git a/__init__.py b/__init__.py index d721463..6b6b94c 100644 --- a/__init__.py +++ b/__init__.py @@ -1,3 +1,4 @@ from .nodes import NODE_CLASS_MAPPINGS, NODE_DISPLAY_NAME_MAPPINGS -__all__ = ['NODE_CLASS_MAPPINGS', 'NODE_DISPLAY_NAME_MAPPINGS'] \ No newline at end of file +WEB_DIRECTORY = "./js" +__all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS","WEB_DIRECTORY"] \ No newline at end of file diff --git a/assets/2de5b085-1125-46f9-8ef3-06706743f182.png b/assets/2de5b085-1125-46f9-8ef3-06706743f182.png index 6d07113..513b3d0 100644 Binary files a/assets/2de5b085-1125-46f9-8ef3-06706743f182.png and b/assets/2de5b085-1125-46f9-8ef3-06706743f182.png differ diff --git a/assets/d0a22b2a-ceb3-4205-9b4e-f6a68e4337c7.png b/assets/d0a22b2a-ceb3-4205-9b4e-f6a68e4337c7.png index 53a1562..211fb89 100644 Binary files a/assets/d0a22b2a-ceb3-4205-9b4e-f6a68e4337c7.png and b/assets/d0a22b2a-ceb3-4205-9b4e-f6a68e4337c7.png differ diff --git a/assets/demo3.gif b/assets/demo3.gif index b2cee1f..2d62fad 100644 Binary files a/assets/demo3.gif and b/assets/demo3.gif differ diff --git a/nodes.py b/nodes.py index 36fc804..0776055 100644 --- a/nodes.py +++ b/nodes.py @@ -4,19 +4,11 @@ from torchvision import transforms import numpy as np from PIL import Image import torch.nn.functional as F -from .BiRefNet_node_config import Config import comfy.model_management as mm - -Config() +import os torch.set_float32_matmul_precision(["high", "highest"][0]) -birefnet = AutoModelForImageSegmentation.from_pretrained( - "ZhengPeng7/BiRefNet", trust_remote_code=True -) - - - transform_image = transforms.Compose( [ transforms.Resize((1024, 1024)), @@ -25,6 +17,11 @@ transform_image = transforms.Compose( ] ) +current_path = os.getcwd() + +## ComfyUI portable standalone build for Windows +model_path = os.path.join(current_path, "ComfyUI"+os.sep+"models"+os.sep+"BiRefNet") + def tensor2pil(image): return Image.fromarray(np.clip(255. * image.cpu().numpy().squeeze(), 0, 255).astype(np.uint8)) @@ -68,8 +65,12 @@ class BiRefNet_Hugo: return { "required": { "image": ("IMAGE",), + "load_local_model": ("BOOLEAN", {"default": False}), "background_color_name": (colors,{"default": "transparency"}), "device": (["auto", "cuda", "cpu", "mps", "xpu", "meta"],{"default": "auto"}) + }, + "optional": { + "local_model_path": ("STRING", {"default":model_path}), } } @@ -80,13 +81,24 @@ class BiRefNet_Hugo: def background_remove(self, image, + load_local_model, device, background_color_name, + *args, **kwargs ): processed_images = [] processed_masks = [] device = get_device_by_name(device) + + if load_local_model: + local_model_path = kwargs.get("local_model_path", model_path) + birefnet = AutoModelForImageSegmentation.from_pretrained(local_model_path,trust_remote_code=True) + else: + birefnet = AutoModelForImageSegmentation.from_pretrained( + "ZhengPeng7/BiRefNet", trust_remote_code=True + ) + birefnet.to(device) for image in image: orig_image = tensor2pil(image) diff --git a/workflow/video_workflow.json b/workflow/video_workflow.json index 6ef5786..df0ea33 100644 --- a/workflow/video_workflow.json +++ b/workflow/video_workflow.json @@ -3,20 +3,32 @@ "last_link_id": 16, "nodes": [ { - "id": 11, - "type": "VHS_LoadVideo", - "pos": [ - 840, - -90 - ], + "id": 13, + "type": "VHS_VideoCombine", + "pos": { + "0": 1830, + "1": -180 + }, "size": [ - 210, - 480 + 360, + 928.4444444444445 ], "flags": {}, - "order": 0, + "order": 2, "mode": 0, "inputs": [ + { + "name": "images", + "type": "IMAGE", + "link": 14, + "label": "图像" + }, + { + "name": "audio", + "type": "AUDIO", + "link": null, + "label": "音频" + }, { "name": "meta_batch", "type": "VHS_BatchManager", @@ -31,122 +43,47 @@ ], "outputs": [ { - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 12 - ], - "shape": 3, - "label": "图像", - "slot_index": 0 - }, - { - "name": "frame_count", - "type": "INT", + "name": "Filenames", + "type": "VHS_FILENAMES", "links": null, "shape": 3, - "label": "帧计数" - }, - { - "name": "audio", - "type": "AUDIO", - "links": null, - "shape": 3, - "label": "音频" - }, - { - "name": "video_info", - "type": "VHS_VIDEOINFO", - "links": null, - "shape": 3, - "label": "视频信息" + "label": "文件名" } ], "properties": { - "Node name for S&R": "VHS_LoadVideo" + "Node name for S&R": "VHS_VideoCombine" }, "widgets_values": { - "video": "6月28日(1).mp4", - "force_rate": 0, - "force_size": "Disabled", - "custom_width": 512, - "custom_height": 512, - "frame_load_cap": 0, - "skip_first_frames": 0, - "select_every_nth": 1, - "choose video to upload": "image", + "frame_rate": 30, + "loop_count": 0, + "filename_prefix": "AnimateDiff", + "format": "video/h265-mp4", + "pix_fmt": "yuv420p10le", + "crf": 22, + "save_metadata": true, + "pingpong": false, + "save_output": true, "videopreview": { "hidden": false, "paused": false, "params": { - "frame_load_cap": 0, - "skip_first_frames": 0, - "force_rate": 0, - "filename": "6月28日(1).mp4", - "type": "input", - "format": "video/mp4", - "select_every_nth": 1 + "filename": "AnimateDiff_00004.mp4", + "subfolder": "", + "type": "output", + "format": "video/h265-mp4", + "frame_rate": 30 }, "muted": false } } }, - { - "id": 1, - "type": "BiRefNet_Hugo", - "pos": [ - 1110, - -60 - ], - "size": { - "0": 210, - "1": 60 - }, - "flags": {}, - "order": 1, - "mode": 0, - "inputs": [ - { - "name": "image", - "type": "IMAGE", - "link": 12, - "slot_index": 0, - "label": "image" - } - ], - "outputs": [ - { - "name": "image", - "type": "IMAGE", - "links": [ - 14 - ], - "slot_index": 0, - "shape": 3, - "label": "image" - }, - { - "name": "mask", - "type": "MASK", - "links": [ - 15 - ], - "slot_index": 1, - "shape": 3, - "label": "mask" - } - ], - "properties": { - "Node name for S&R": "BiRefNet_Hugo" - } - }, { "id": 14, "type": "MaskToImage", - "pos": [ - 1410, - 30 - ], + "pos": { + "0": 1466, + "1": 93 + }, "size": { "0": 210, "1": 30 @@ -169,9 +106,9 @@ "links": [ 16 ], + "slot_index": 0, "shape": 3, - "label": "图像", - "slot_index": 0 + "label": "图像" } ], "properties": { @@ -181,13 +118,13 @@ { "id": 15, "type": "VHS_VideoCombine", - "pos": [ - 1410, - 120 - ], + "pos": { + "0": 1409, + "1": 210 + }, "size": [ 360, - 660 + 928.4444444444445 ], "flags": {}, "order": 4, @@ -254,32 +191,20 @@ } }, { - "id": 13, - "type": "VHS_VideoCombine", - "pos": [ - 1830, - -180 - ], + "id": 11, + "type": "VHS_LoadVideo", + "pos": { + "0": 826, + "1": -90 + }, "size": [ - 360, - 660 + 210, + 466 ], "flags": {}, - "order": 2, + "order": 0, "mode": 0, "inputs": [ - { - "name": "images", - "type": "IMAGE", - "link": 14, - "label": "图像" - }, - { - "name": "audio", - "type": "AUDIO", - "link": null, - "label": "音频" - }, { "name": "meta_batch", "type": "VHS_BatchManager", @@ -294,39 +219,119 @@ ], "outputs": [ { - "name": "Filenames", - "type": "VHS_FILENAMES", + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 12 + ], + "slot_index": 0, + "shape": 3, + "label": "图像" + }, + { + "name": "frame_count", + "type": "INT", "links": null, "shape": 3, - "label": "文件名" + "label": "帧计数" + }, + { + "name": "audio", + "type": "AUDIO", + "links": null, + "shape": 3, + "label": "音频" + }, + { + "name": "video_info", + "type": "VHS_VIDEOINFO", + "links": null, + "shape": 3, + "label": "视频信息" } ], "properties": { - "Node name for S&R": "VHS_VideoCombine" + "Node name for S&R": "VHS_LoadVideo" }, "widgets_values": { - "frame_rate": 30, - "loop_count": 0, - "filename_prefix": "AnimateDiff", - "format": "video/h265-mp4", - "pix_fmt": "yuv420p10le", - "crf": 22, - "save_metadata": true, - "pingpong": false, - "save_output": true, + "video": "6月28日(1).mp4", + "force_rate": 0, + "force_size": "Disabled", + "custom_width": 512, + "custom_height": 512, + "frame_load_cap": 0, + "skip_first_frames": 0, + "select_every_nth": 1, + "choose video to upload": "image", "videopreview": { "hidden": false, "paused": false, "params": { - "filename": "AnimateDiff_00004.mp4", - "subfolder": "", - "type": "output", - "format": "video/h265-mp4", - "frame_rate": 30 + "frame_load_cap": 0, + "skip_first_frames": 0, + "force_rate": 0, + "filename": "6月28日(1).mp4", + "type": "input", + "format": "video/mp4", + "select_every_nth": 1 }, "muted": false } } + }, + { + "id": 1, + "type": "BiRefNet_Hugo", + "pos": { + "0": 1076, + "1": -81 + }, + "size": { + "0": 319.6482238769531, + "1": 154.82546997070312 + }, + "flags": {}, + "order": 1, + "mode": 0, + "inputs": [ + { + "name": "image", + "type": "IMAGE", + "link": 12, + "slot_index": 0, + "label": "图像" + } + ], + "outputs": [ + { + "name": "image", + "type": "IMAGE", + "links": [ + 14 + ], + "slot_index": 0, + "shape": 3, + "label": "图像" + }, + { + "name": "mask", + "type": "MASK", + "links": [ + 15 + ], + "slot_index": 1, + "shape": 3, + "label": "遮罩" + } + ], + "properties": { + "Node name for S&R": "BiRefNet_Hugo" + }, + "widgets_values": [ + false, + "transparency", + "auto" + ] } ], "links": [ @@ -367,10 +372,10 @@ "config": {}, "extra": { "ds": { - "scale": 0.8390545288824037, + "scale": 1.6105100000000008, "offset": [ - -471.7394319558889, - 296.200180526101 + -674.0647486185928, + 271.0286531806558 ] } }, diff --git a/workflow/workflow.json b/workflow/workflow.json index ed4f754..17e5a8c 100644 --- a/workflow/workflow.json +++ b/workflow/workflow.json @@ -2,159 +2,21 @@ "last_node_id": 5, "last_link_id": 4, "nodes": [ - { - "id": 1, - "type": "BiRefNet_Hugo", - "pos": [ - 921, - 256 - ], - "size": { - "0": 210, - "1": 46 - }, - "flags": {}, - "order": 1, - "mode": 0, - "inputs": [ - { - "name": "image", - "type": "IMAGE", - "link": 1, - "label": "image", - "slot_index": 0 - } - ], - "outputs": [ - { - "name": "image", - "type": "IMAGE", - "links": [ - 2 - ], - "shape": 3, - "label": "image", - "slot_index": 0 - }, - { - "name": "mask", - "type": "MASK", - "links": [ - 3 - ], - "shape": 3, - "label": "mask", - "slot_index": 1 - } - ], - "properties": { - "Node name for S&R": "BiRefNet_Hugo" - } - }, - { - "id": 4, - "type": "MaskToImage", - "pos": [ - 922, - 352 - ], - "size": { - "0": 210, - "1": 26 - }, - "flags": {}, - "order": 3, - "mode": 0, - "inputs": [ - { - "name": "mask", - "type": "MASK", - "link": 3, - "label": "遮罩" - } - ], - "outputs": [ - { - "name": "IMAGE", - "type": "IMAGE", - "links": [ - 4 - ], - "shape": 3, - "label": "图像", - "slot_index": 0 - } - ], - "properties": { - "Node name for S&R": "MaskToImage" - } - }, - { - "id": 5, - "type": "PreviewImage", - "pos": [ - 1299, - 410 - ], - "size": [ - 210, - 246 - ], - "flags": {}, - "order": 4, - "mode": 0, - "inputs": [ - { - "name": "images", - "type": "IMAGE", - "link": 4, - "label": "图像" - } - ], - "properties": { - "Node name for S&R": "PreviewImage" - } - }, - { - "id": 3, - "type": "PreviewImage", - "pos": [ - 1295, - 74 - ], - "size": [ - 210, - 246 - ], - "flags": {}, - "order": 2, - "mode": 0, - "inputs": [ - { - "name": "images", - "type": "IMAGE", - "link": 2, - "label": "图像" - } - ], - "properties": { - "Node name for S&R": "PreviewImage" - } - }, { "id": 2, "type": "LoadImage", - "pos": [ - 561, - 254 - ], - "size": [ - 315, - 314 - ], + "pos": { + "0": 561, + "1": 254 + }, + "size": { + "0": 315, + "1": 314 + }, "flags": {}, "order": 0, "mode": 0, + "inputs": [], "outputs": [ { "name": "IMAGE", @@ -180,6 +42,152 @@ "image.webp", "image" ] + }, + { + "id": 3, + "type": "PreviewImage", + "pos": { + "0": 1312, + "1": 140 + }, + "size": [ + 410.6826949448018, + 214.56675819839558 + ], + "flags": {}, + "order": 2, + "mode": 0, + "inputs": [ + { + "name": "images", + "type": "IMAGE", + "link": 2, + "label": "图像" + } + ], + "outputs": [], + "properties": { + "Node name for S&R": "PreviewImage" + } + }, + { + "id": 4, + "type": "MaskToImage", + "pos": { + "0": 933, + "1": 473 + }, + "size": { + "0": 210, + "1": 26 + }, + "flags": {}, + "order": 3, + "mode": 0, + "inputs": [ + { + "name": "mask", + "type": "MASK", + "link": 3, + "label": "遮罩" + } + ], + "outputs": [ + { + "name": "IMAGE", + "type": "IMAGE", + "links": [ + 4 + ], + "slot_index": 0, + "shape": 3, + "label": "图像" + } + ], + "properties": { + "Node name for S&R": "MaskToImage" + } + }, + { + "id": 1, + "type": "BiRefNet_Hugo", + "pos": { + "0": 921, + "1": 256 + }, + "size": [ + 315.4826217026143, + 143.56669716323933 + ], + "flags": {}, + "order": 1, + "mode": 0, + "inputs": [ + { + "name": "image", + "type": "IMAGE", + "link": 1, + "slot_index": 0, + "label": "图像" + } + ], + "outputs": [ + { + "name": "image", + "type": "IMAGE", + "links": [ + 2 + ], + "slot_index": 0, + "shape": 3, + "label": "图像" + }, + { + "name": "mask", + "type": "MASK", + "links": [ + 3 + ], + "slot_index": 1, + "shape": 3, + "label": "遮罩" + } + ], + "properties": { + "Node name for S&R": "BiRefNet_Hugo" + }, + "widgets_values": [ + false, + "transparency", + "auto" + ] + }, + { + "id": 5, + "type": "PreviewImage", + "pos": { + "0": 1316, + "1": 425 + }, + "size": [ + 430.8826461166768, + 261.3667765089424 + ], + "flags": {}, + "order": 4, + "mode": 0, + "inputs": [ + { + "name": "images", + "type": "IMAGE", + "link": 4, + "label": "图像" + } + ], + "outputs": [], + "properties": { + "Node name for S&R": "PreviewImage" + } } ], "links": [ @@ -220,10 +228,10 @@ "config": {}, "extra": { "ds": { - "scale": 1.2100000000000002, + "scale": 1, "offset": [ - -299.9616678351899, - 94.8424540865177 + -172.4824996323017, + 67.43331809554974 ] } },