diff --git a/README.MD b/README.MD index 76c681a..6dba8f0 100644 --- a/README.MD +++ b/README.MD @@ -147,6 +147,7 @@ When this error has occurred, please check the network environment. **If the dependency package error after updating, please double clicking ```repair_dependency.bat``` (for Official ComfyUI Protable) or ```repair_dependency_aki.bat``` (for ComfyUI-aki-v1.x) in the plugin folder to reinstall the dependency packages.
+* Commit [SegformerUltraV3](SegformerUltraV3), [LoadSegformerModel](LoadSegformerModel), [SegformerClothesSetting](SegformerClothesSetting) and [SegformerFashionSetting](SegformerFashionSetting) nodes, Separate the loading of models and settings to save resources when using multiple nodes. * Add multiple languages and increase support for 5 languages: Chinese, French, Japanese, Korean and Russian. This feature producted by [ComfyUI-Globalization-Node-Translation](https://github.com/yamanacn/ComfyUI-Globalization-Node-Translation), thank you to the original author. * Commit [HalfTone](#HalfTone) node, use for halftone processing of images. * Add QuarkNetdisk model download link. @@ -1981,6 +1982,31 @@ Node Options: * tassel: tassel switch. +### SegformerUltraV3 +On the basis of ```SegformerUltraV2```, it has been modified to load models and settings separately, saving resources when using multiple nodes. Please note that the type set must match the model. + +Modified node options: +![image](image/segfromer_ultra_v3_node.jpg) +* segformer_model: Segformer model input, the model is loaded by the ```LoadSegformerModel``` node. +* segformer_setting: Segformer Label setting input. + +### SegformerClothesSetting +![image](image/segformer_clothes_setting_node.jpg) +Set up Segformer Clothes nodes in conjunction with ```Segformer Ultra V3```. The model option has been removed from the ```SegformerClottesPipiline``` node. + + +### SegformerFashionSetting +![image](image/segformer_fashion_pipeline_node.jpg) +Set up Segformer Fashion nodes in conjunction with ```Segformer Ultra V3```. The model option has been removed from the ```SegformerFashionPipiline``` node. + +### LoadSegformerModel +Model loading node compatible with ```Segformer Ultra V3```. + +Node Options: +![image](image/load_segfromer_model_node.jpg) +* model_name: Model selection. +* devicee: Load device selection. + ### MaskEdgeUltraDetail Process rough masks to ultra fine edges. diff --git a/README_CN.MD b/README_CN.MD index b79a5e7..3f6f9c7 100644 --- a/README_CN.MD +++ b/README_CN.MD @@ -128,6 +128,7 @@ os.environ['HF_ENDPOINT'] = 'https://hf-mirror.com' ## 更新说明 **如果本插件更新后出现依赖包错误,请双击运行插件目录下的```install_requirements.bat```(官方便携包),或 ```install_requirements_aki.bat```(秋叶整合包) 重新安装依赖包。 +* 添加 [SegformerUltraV3](SegformerUltraV3), [LoadSegformerModel](LoadSegformerModel), [SegformerClothesSetting](SegformerClothesSetting) 和 [SegformerFashionSetting](SegformerFashionSetting) 节点,将模型与设置分离加载,在使用多个节点时节省资源。 * 添加多语言,除英语外,增加支持5种语言:中文、法语、日语、韩语和俄语。该功能使用[ComfyUI-Globalization-Node-Translation](https://github.com/yamanacn/ComfyUI-Globalization-Node-Translation)制作,感谢原作者。 * 添加 [HalfTone](#HalfTone) 节点,用于对图像进行半色调处理。 * 增加模型下载夸克网盘链接。 @@ -1771,6 +1772,32 @@ RemBgUltra的V2升级版,增加了VITMatte边缘处理方法。 * tassel: 流苏识别。 +### SegformerUltraV3 +在SegformerUltraV2基础上,修改为模型与设置分离加载,在使用多个节点时节省资源。请注意设置的类型必须与模型匹配。 + +修改的节点选项: +![image](image/segfromer_ultra_v3_node.jpg) +* segformer_model: Segformer模型输入,模型由LoadSegformerModel节点加载。 +* segformer_setting: Segformer Label设置输入。 + +### SegformerClothesSetting +![image](image/segformer_clothes_setting_node.jpg) +与 SegformerUltraV3 配套的SegformerClothes设置节点。在SegformerClothesPipiline节点基础上删除了model 选项。 + + +### SegformerFashionSetting +![image](image/segformer_fashion_pipeline_node.jpg) +与 SegformerUltraV3 配套的SegformerFashion设置节点。在SegformerFashionPipiline节点基础上删除了model 选项。 + +### LoadSegformerModel +与 SegformerUltraV3 配套的模型加载节点。 + +节点选项说明: +![image](image/load_segfromer_model_node.jpg) +* model_name: 模型选择。目前有三种模型可供选择segformer b2 clothes, segformer b3 clothes 和 segformer b3 fashion。 +* devicee: 加载设备选择。 + + ### MaskEdgeUltraDetail 处理较粗糙的遮罩使其获得超精细边缘。 ![image](image/mask_edge_ultra_detail_example.jpg) diff --git a/py/segformer_ultra.py b/py/segformer_ultra.py index 6b68672..62f7d5d 100644 --- a/py/segformer_ultra.py +++ b/py/segformer_ultra.py @@ -19,6 +19,24 @@ class SegformerPipeline: SegPipeline = SegformerPipeline() + +# 切割服装 +def get_segmentation_from_model(tensor_image, segformer_model): + + processor = segformer_model["processor"] + model = segformer_model["model"] + + cloth = tensor2pil(tensor_image) + + # 预处理和预测 + inputs = processor(images=cloth, return_tensors="pt") + outputs = model(**inputs) + logits = outputs.logits.cpu() + upsampled_logits = nn.functional.interpolate(logits, size=cloth.size[::-1], mode="bilinear", align_corners=False) + pred_seg = upsampled_logits.argmax(dim=1)[0].numpy() + return pred_seg,cloth + + # 切割服装 def get_segmentation(tensor_image, model_name='segformer_b2_clothes'): cloth = tensor2pil(tensor_image) @@ -516,17 +534,411 @@ class SegformerUltraV2: log(f"{self.NODE_NAME} Processed {len(ret_images)} image(s).", message_type='finish') return (torch.cat(ret_images, dim=0), torch.cat(ret_masks, dim=0),) + +class LS_SegformerClothesSetting: + + def __init__(self): + self.NODE_NAME = 'SegformerClothesSetting' + pass + + # Labels: 0: "Background", 1: "Hat", 2: "Hair", 3: "Sunglasses", 4: "Upper-clothes", + # 5: "Skirt", 6: "Pants", 7: "Dress", 8: "Belt", 9: "Left-shoe", 10: "Right-shoe", + # 11: "Face", 12: "Left-leg", 13: "Right-leg", 14: "Left-arm", 15: "Right-arm", + # 17: "Scarf" + + @classmethod + def INPUT_TYPES(cls): + + return {"required": + { "face": ("BOOLEAN", {"default": False, "label_on": "enabled(脸)", "label_off": "disabled(脸)"}), + "hair": ("BOOLEAN", {"default": False, "label_on": "enabled(头发)", "label_off": "disabled(头发)"}), + "hat": ("BOOLEAN", {"default": False, "label_on": "enabled(帽子)", "label_off": "disabled(帽子)"}), + "sunglass": ("BOOLEAN", {"default": False, "label_on": "enabled(墨镜)", "label_off": "disabled(墨镜)"}), + "left_arm": ("BOOLEAN", {"default": False, "label_on": "enabled(左臂)", "label_off": "disabled(左臂)"}), + "right_arm": ("BOOLEAN", {"default": False, "label_on": "enabled(右臂)", "label_off": "disabled(右臂)"}), + "left_leg": ("BOOLEAN", {"default": False, "label_on": "enabled(左腿)", "label_off": "disabled(左腿)"}), + "right_leg": ("BOOLEAN", {"default": False, "label_on": "enabled(右腿)", "label_off": "disabled(右腿)"}), + "left_shoe": ("BOOLEAN", {"default": False, "label_on": "enabled(左鞋)", "label_off": "disabled(左鞋)"}), + "right_shoe": ("BOOLEAN", {"default": False, "label_on": "enabled(右鞋)", "label_off": "disabled(右鞋)"}), + "upper_clothes": ("BOOLEAN", {"default": False, "label_on": "enabled(上衣)", "label_off": "disabled(上衣)"}), + "skirt": ("BOOLEAN", {"default": False, "label_on": "enabled(短裙)", "label_off": "disabled(短裙)"}), + "pants": ("BOOLEAN", {"default": False, "label_on": "enabled(裤子)", "label_off": "disabled(裤子)"}), + "dress": ("BOOLEAN", {"default": False, "label_on": "enabled(连衣裙)", "label_off": "disabled(连衣裙)"}), + "belt": ("BOOLEAN", {"default": False, "label_on": "enabled(腰带)", "label_off": "disabled(腰带)"}), + "bag": ("BOOLEAN", {"default": False, "label_on": "enabled(背包)", "label_off": "disabled(背包)"}), + "scarf": ("BOOLEAN", {"default": False, "label_on": "enabled(围巾)", "label_off": "disabled(围巾)"}), + } + } + + RETURN_TYPES = ("LS_SEGFORMER_SETTING",) + RETURN_NAMES = ("segformer_clothes_setting",) + FUNCTION = "run_segformer_clothes_setting" + CATEGORY = '😺dzNodes/LayerMask' + + def run_segformer_clothes_setting(self, face, hat, hair, sunglass, + left_leg, right_leg, left_arm, right_arm, left_shoe, right_shoe, + upper_clothes, skirt, pants, dress, belt, bag, scarf, + ): + + pipeline = SegformerPipeline() + labels_to_keep = [0] + if not hat: + labels_to_keep.append(1) + if not hair: + labels_to_keep.append(2) + if not sunglass: + labels_to_keep.append(3) + if not upper_clothes: + labels_to_keep.append(4) + if not skirt: + labels_to_keep.append(5) + if not pants: + labels_to_keep.append(6) + if not dress: + labels_to_keep.append(7) + if not belt: + labels_to_keep.append(8) + if not left_shoe: + labels_to_keep.append(9) + if not right_shoe: + labels_to_keep.append(10) + if not face: + labels_to_keep.append(11) + if not left_leg: + labels_to_keep.append(12) + if not right_leg: + labels_to_keep.append(13) + if not left_arm: + labels_to_keep.append(14) + if not right_arm: + labels_to_keep.append(15) + if not bag: + labels_to_keep.append(16) + if not scarf: + labels_to_keep.append(17) + + setting = {"labels_to_keep": labels_to_keep, "model_name": "segformer_b3_clothes"} + + return (setting,) + +class LS_SegformerFashionSetting: + + def __init__(self): + self.NODE_NAME = 'SegformerFashionSetting' + pass + + @classmethod + def INPUT_TYPES(cls): + return {"required": + { "shirt": ("BOOLEAN", {"default": False, "label_on": "enabled(衬衫、罩衫)", "label_off": "disabled(衬衫、罩衫)"}), + "top": ("BOOLEAN", {"default": False, "label_on": "enabled(上衣、t恤)", "label_off": "disabled(上衣、t恤)"}), + "sweater": ("BOOLEAN", {"default": False, "label_on": "enabled(毛衣)", "label_off": "disabled(毛衣)"}), + "cardigan": ("BOOLEAN", {"default": False, "label_on": "enabled(开襟毛衫)", "label_off": "disabled(开襟毛衫)"}), + "jacket": ("BOOLEAN", {"default": False, "label_on": "enabled(夹克)", "label_off": "disabled(夹克)"}), + "vest": ("BOOLEAN", {"default": False, "label_on": "enabled(背心)", "label_off": "disabled(背心)"}), + "pants": ("BOOLEAN", {"default": False, "label_on": "enabled(裤子)", "label_off": "disabled(裤子)"}), + "shorts": ("BOOLEAN", {"default": False, "label_on": "enabled(短裤)", "label_off": "disabled(短裤)"}), + "skirt": ("BOOLEAN", {"default": False, "label_on": "enabled(裙子)", "label_off": "disabled(裙子)"}), + "coat": ("BOOLEAN", {"default": False, "label_on": "enabled(外套)", "label_off": "disabled(外套)"}), + "dress": ("BOOLEAN", {"default": False, "label_on": "enabled(连衣裙)", "label_off": "disabled(连衣裙)"}), + "jumpsuit": ("BOOLEAN", {"default": False, "label_on": "enabled(连身裤)", "label_off": "disabled(连身裤)"}), + "cape": ("BOOLEAN", {"default": False, "label_on": "enabled(斗篷)", "label_off": "disabled(斗篷)"}), + "glasses": ("BOOLEAN", {"default": False, "label_on": "enabled(眼镜)", "label_off": "disabled(眼镜)"}), + "hat": ("BOOLEAN", {"default": False, "label_on": "enabled(帽子)", "label_off": "disabled(帽子)"}), + "hairaccessory": ("BOOLEAN", {"default": False, "label_on": "enabled(头带)", "label_off": "disabled(头带)"}), + "tie": ("BOOLEAN", {"default": False, "label_on": "enabled(领带)", "label_off": "disabled(领带)"}), + "glove": ("BOOLEAN", {"default": False, "label_on": "enabled(手套)", "label_off": "disabled(手套)"}), + "watch": ("BOOLEAN", {"default": False, "label_on": "enabled(手表)", "label_off": "disabled(手表)"}), + "belt": ("BOOLEAN", {"default": False, "label_on": "enabled(皮带)", "label_off": "disabled(皮带)"}), + "legwarmer": ("BOOLEAN", {"default": False, "label_on": "enabled(腿套)", "label_off": "disabled(腿套)"}), + "tights": ("BOOLEAN", {"default": False, "label_on": "enabled(裤袜)","label_off": "disabled(裤袜)"}), + "sock": ("BOOLEAN", {"default": False, "label_on": "enabled(袜子)", "label_off": "disabled(袜子)"}), + "shoe": ("BOOLEAN", {"default": False, "label_on": "enabled(鞋子)", "label_off": "disabled(鞋子)"}), + "bagwallet": ("BOOLEAN", {"default": False, "label_on": "enabled(手包)", "label_off": "disabled(手包)"}), + "scarf": ("BOOLEAN", {"default": False, "label_on": "enabled(围巾)", "label_off": "disabled(围巾)"}), + "umbrella": ("BOOLEAN", {"default": False, "label_on": "enabled(雨伞)", "label_off": "disabled(雨伞)"}), + "hood": ("BOOLEAN", {"default": False, "label_on": "enabled(兜帽)", "label_off": "disabled(兜帽)"}), + "collar": ("BOOLEAN", {"default": False, "label_on": "enabled(衣领)", "label_off": "disabled(衣领)"}), + "lapel": ("BOOLEAN", {"default": False, "label_on": "enabled(翻领)", "label_off": "disabled(翻领)"}), + "epaulette": ("BOOLEAN", {"default": False, "label_on": "enabled(肩章)", "label_off": "disabled(肩章)"}), + "sleeve": ("BOOLEAN", {"default": False, "label_on": "enabled(袖子)", "label_off": "disabled(袖子)"}), + "pocket": ("BOOLEAN", {"default": False, "label_on": "enabled(口袋)", "label_off": "disabled(口袋)"}), + "neckline": ("BOOLEAN", {"default": False, "label_on": "enabled(领口)", "label_off": "disabled(领口)"}), + "buckle": ("BOOLEAN", {"default": False, "label_on": "enabled(带扣)", "label_off": "disabled(带扣)"}), + "zipper": ("BOOLEAN", {"default": False, "label_on": "enabled(拉链)", "label_off": "disabled(拉链)"}), + "applique": ("BOOLEAN", {"default": False, "label_on": "enabled(贴花)", "label_off": "disabled(贴花)"}), + "bead": ("BOOLEAN", {"default": False, "label_on": "enabled(珠子)", "label_off": "disabled(珠子)"}), + "bow": ("BOOLEAN", {"default": False, "label_on": "enabled(蝴蝶结)", "label_off": "disabled(蝴蝶结)"}), + "flower": ("BOOLEAN", {"default": False, "label_on": "enabled(花)", "label_off": "disabled(花)"}), + "fringe": ("BOOLEAN", {"default": False, "label_on": "enabled(刘海)", "label_off": "disabled(刘海)"}), + "ribbon": ("BOOLEAN", {"default": False, "label_on": "enabled(丝带)", "label_off": "disabled(丝带)"}), + "rivet": ("BOOLEAN", {"default": False, "label_on": "enabled(铆钉)", "label_off": "disabled(铆钉)"}), + "ruffle": ("BOOLEAN", {"default": False, "label_on": "enabled(褶饰)", "label_off": "disabled(褶饰)"}), + "sequin": ("BOOLEAN", {"default": False, "label_on": "enabled(亮片)", "label_off": "disabled(亮片)"}), + "tassel": ("BOOLEAN", {"default": False, "label_on": "enabled(流苏)", "label_off": "disabled(流苏)"}), + } + } + + RETURN_TYPES = ("LS_SEGFORMER_SETTING",) + RETURN_NAMES = ("segformer_fashion_setting",) + FUNCTION = "run_segformer_fashion_setting" + CATEGORY = '😺dzNodes/LayerMask' + + def run_segformer_fashion_setting(self, shirt, top, sweater, cardigan, jacket, vest, pants, + shorts, skirt, coat, dress, jumpsuit, cape, glasses, + hat, hairaccessory, tie, glove, watch, belt, legwarmer, + tights, sock, shoe, bagwallet, scarf, umbrella, hood, + collar, lapel, epaulette, sleeve, pocket, neckline, + buckle, zipper, applique, bead, bow, flower, fringe, + ribbon, rivet, ruffle, sequin, tassel + ): + + pipeline = SegformerPipeline() + labels_to_keep = [0] + if not shirt: + labels_to_keep.append(1) + if not top: + labels_to_keep.append(2) + if not sweater: + labels_to_keep.append(3) + if not cardigan: + labels_to_keep.append(4) + if not jacket: + labels_to_keep.append(5) + if not vest: + labels_to_keep.append(6) + if not pants: + labels_to_keep.append(7) + if not shorts: + labels_to_keep.append(8) + if not skirt: + labels_to_keep.append(9) + if not coat: + labels_to_keep.append(10) + if not dress: + labels_to_keep.append(11) + if not jumpsuit: + labels_to_keep.append(12) + if not cape: + labels_to_keep.append(13) + if not glasses: + labels_to_keep.append(14) + if not hat: + labels_to_keep.append(15) + if not hairaccessory: + labels_to_keep.append(16) + if not tie: + labels_to_keep.append(17) + if not glove: + labels_to_keep.append(18) + if not watch: + labels_to_keep.append(19) + if not belt: + labels_to_keep.append(20) + if not legwarmer: + labels_to_keep.append(21) + if not tights: + labels_to_keep.append(22) + if not sock: + labels_to_keep.append(23) + if not shoe: + labels_to_keep.append(24) + if not bagwallet: + labels_to_keep.append(25) + if not scarf: + labels_to_keep.append(26) + if not umbrella: + labels_to_keep.append(27) + if not hood: + labels_to_keep.append(28) + if not collar: + labels_to_keep.append(29) + if not lapel: + labels_to_keep.append(30) + if not epaulette: + labels_to_keep.append(31) + if not sleeve: + labels_to_keep.append(32) + if not pocket: + labels_to_keep.append(33) + if not neckline: + labels_to_keep.append(34) + if not buckle: + labels_to_keep.append(35) + if not zipper: + labels_to_keep.append(36) + if not applique: + labels_to_keep.append(37) + if not bead: + labels_to_keep.append(38) + if not bow: + labels_to_keep.append(39) + if not flower: + labels_to_keep.append(40) + if not fringe: + labels_to_keep.append(41) + if not ribbon: + labels_to_keep.append(42) + if not rivet: + labels_to_keep.append(43) + if not ruffle: + labels_to_keep.append(44) + if not sequin: + labels_to_keep.append(45) + if not tassel: + labels_to_keep.append(46) + + setting = {"labels_to_keep":labels_to_keep, "model_name":"segformer_b3_fashion"} + + return (setting,) + +class LS_LoadSegformerModel: + + def __init__(self): + self.NODE_NAME = 'LoadSegformerModel' + pass + + @classmethod + def INPUT_TYPES(cls): + model_list = ['segformer_b3_clothes', 'segformer_b2_clothes', 'segformer_b3_fashion'] + device_list = ['cuda', 'cpu'] + return {"required": + { + "model_name": (model_list,), + "device": (device_list,), + } + } + + RETURN_TYPES = ("LS_SEGFORMER_MODEL", ) + RETURN_NAMES = ("segfromer_model", ) + FUNCTION = "load_segformer_model" + CATEGORY = '😺dzNodes/LayerMask' + + def load_segformer_model(self, model_name, device): + + model_folder_path = os.path.join(folder_paths.models_dir, model_name) + try: + model_folder_path = os.path.normpath(folder_paths.folder_names_and_paths[model_name][0][0]) + except: + pass + + processor = SegformerImageProcessor.from_pretrained(model_folder_path) + model = AutoModelForSemanticSegmentation.from_pretrained(model_folder_path) + + segfromer_model = {"processor":processor, "model":model, "device":device, "model_name":model_name} + + log(f"{self.NODE_NAME} Loaded Segformer Model {model_name}.", message_type='finish') + return (segfromer_model,) + +class LS_SegformerUltraV3: + + def __init__(self): + self.NODE_NAME = 'SegformerUltraV3' + pass + + @classmethod + def INPUT_TYPES(cls): + method_list = ['VITMatte', 'VITMatte(local)', 'PyMatting', 'GuidedFilter', ] + return {"required": + { + "image": ("IMAGE",), + "segformer_model": ("LS_SEGFORMER_MODEL",), + "segformer_setting": ("LS_SEGFORMER_SETTING",), + "detail_method": (method_list,), + "detail_erode": ("INT", {"default": 8, "min": 1, "max": 255, "step": 1}), + "detail_dilate": ("INT", {"default": 6, "min": 1, "max": 255, "step": 1}), + "black_point": ("FLOAT", {"default": 0.01, "min": 0.01, "max": 0.98, "step": 0.01, "display": "slider"}), + "white_point": ("FLOAT", {"default": 0.99, "min": 0.02, "max": 0.99, "step": 0.01, "display": "slider"}), + "process_detail": ("BOOLEAN", {"default": True}), + "max_megapixels": ("FLOAT", {"default": 2.0, "min": 1, "max": 999, "step": 0.1}), + } + } + + RETURN_TYPES = ("IMAGE", "MASK",) + RETURN_NAMES = ("image", "mask",) + FUNCTION = "segformer_ultra_v3" + CATEGORY = '😺dzNodes/LayerMask' + + def segformer_ultra_v3(self, image, segformer_model, segformer_setting, + detail_method, detail_erode, detail_dilate, black_point, white_point, + process_detail, max_megapixels, + ): + + device = segformer_model["device"] + model_name = segformer_model["model_name"] + + labels_to_keep = segformer_setting["labels_to_keep"] + labels_model_name = segformer_setting["model_name"] + + ret_images = [] + ret_masks = [] + + if model_name.rsplit('_', 1)[-1] != labels_model_name.rsplit('_', 1)[-1]: # 后缀不一致 + raise TypeError("Segformer Model and Segformer Setting are different.") + + if detail_method == 'VITMatte(local)': + local_files_only = True + else: + local_files_only = False + + for i in image: + pred_seg, cloth = get_segmentation_from_model(i, segformer_model) + i = torch.unsqueeze(i, 0) + i = pil2tensor(tensor2pil(i).convert('RGB')) + orig_image = tensor2pil(i).convert('RGB') + + mask = np.isin(pred_seg, labels_to_keep).astype(np.uint8) + + # 创建agnostic-mask图像 + mask_image = Image.fromarray((1 - mask) * 255) + mask_image = mask_image.convert("L") + brightness_image = ImageEnhance.Brightness(mask_image) + mask_image = brightness_image.enhance(factor=1.08) + _mask = pil2tensor(mask_image) + + detail_range = detail_erode + detail_dilate + if process_detail: + if detail_method == 'GuidedFilter': + _mask = guided_filter_alpha(i, _mask, detail_range // 6 + 1) + _mask = tensor2pil(histogram_remap(_mask, black_point, white_point)) + elif detail_method == 'PyMatting': + _mask = tensor2pil(mask_edge_detail(i, _mask, detail_range // 8 + 1, black_point, white_point)) + else: + _trimap = generate_VITMatte_trimap(_mask, detail_erode, detail_dilate) + _mask = generate_VITMatte(orig_image, _trimap, local_files_only=local_files_only, device=device, + max_megapixels=max_megapixels) + _mask = tensor2pil(histogram_remap(pil2tensor(_mask), black_point, white_point)) + else: + _mask = mask2image(_mask) + + ret_image = RGB2RGBA(orig_image, _mask.convert('L')) + ret_images.append(pil2tensor(ret_image)) + ret_masks.append(image2mask(_mask)) + + log(f"{self.NODE_NAME} Processed {len(ret_images)} image(s).", message_type='finish') + return (torch.cat(ret_images, dim=0), torch.cat(ret_masks, dim=0),) + + + NODE_CLASS_MAPPINGS = { "LayerMask: SegformerB2ClothesUltra": Segformer_B2_Clothes, "LayerMask: SegformerUltraV2": SegformerUltraV2, "LayerMask: SegformerClothesPipelineLoader": SegformerClothesPipelineLoader, "LayerMask: SegformerFashionPipelineLoader": SegformerFashionPipelineLoader, + "LayerMask: SegformerUltraV3": LS_SegformerUltraV3, + "LayerMask: SegformerClothesSetting": LS_SegformerClothesSetting, + "LayerMask: SegformerFashionSetting": LS_SegformerFashionSetting, + "LayerMask: LoadSegformerModel": LS_LoadSegformerModel, } NODE_DISPLAY_NAME_MAPPINGS = { "LayerMask: SegformerB2ClothesUltra": "LayerMask: Segformer B2 Clothes Ultra", "LayerMask: SegformerUltraV2": "LayerMask: Segformer Ultra V2", "LayerMask: SegformerClothesPipelineLoader": "LayerMask: Segformer Clothes Pipeline", - "LayerMask: SegformerFashionPipelineLoader": "LayerMask: Segformer Fashion Pipeline" + "LayerMask: SegformerFashionPipelineLoader": "LayerMask: Segformer Fashion Pipeline", + "LayerMask: SegformerUltraV3": "LayerMask: Segformer Ultra V3", + "LayerMask: SegformerClothesSetting": "LayerMask: Segformer Clothes Setting", + "LayerMask: SegformerFashionSetting": "LayerMask: Segformer Fashion Setting", + "LayerMask: LoadSegformerModel": "LayerMask: Load Segformer Model", } diff --git a/pyproject.toml b/pyproject.toml index ef55413..af8153d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "comfyui_layerstyle" description = "A set of nodes for ComfyUI it generate image like Adobe Photoshop's Layer Style. the Drop Shadow is first completed node, and follow-up work is in progress." -version = "2.0.19" +version = "2.0.20" license = {text = "MIT License"} dependencies = ["numpy", "pillow", "torch", "matplotlib", "Scipy", "scikit_image", "scikit_learn", "opencv-contrib-python", "pymatting", "timm", "colour-science", "transformers", "blend_modes", "huggingface_hub", "loguru"]