commit ZhipuGLM4,ZhipuGLM4V,SegmentAnythingUltraV3,LoadSegmentAnythingModels nodes

This commit is contained in:
chflame163
2024-12-28 12:10:14 +08:00
parent 20db9ad2a8
commit b17bfc5e2d
6 changed files with 265 additions and 3 deletions
+6 -1
View File
@@ -782,10 +782,15 @@ On the basis of SegmentAnythingUltra, the following changes have been made:
* device: Set whether the VitMatte to use cuda.
* max_megapixels: Set the maximum size for VitMate operations.
### <a id="table1">SegmentAnythingUltraV3</a>
Separate model loading from inference nodes to avoid duplicate model loading when using multiple SAM nodes.
![image](image/segment_anything_ultra_v3_example.jpg)
Node Options:
![image](image/segment_anything_ultra_v3_node.jpg)
Same as SegmentAnythingUltra, removed ```sam_comodel``` and ```ground-dino_comodel```, changed them to be obtained from node input.
### <a id="table1">LoadSegmentAnythingModels</a>
Load SegmentAnything models.
+4 -1
View File
@@ -716,8 +716,11 @@ SegmentAnythingUltra的V2升级版,增加了VITMatte边缘处理方法。
### <a id="table1">SegmentAnythingUltraV3</a>
将模型加载与推理节点分离,在使用多个SAM节点时避免重复加载模型。
![image](image/segment_anything_ultra_v3_example.jpg)
节点选项说明:
![image](image/segment_anything_ultra_v3_node.jpg)
选项与SegmentAnythingUltra节点一致,去掉了sam_model和ground_dino_model改为从节点输入获取。
### <a id="table1">LoadSegmentAnythingModels</a>
加载SegmentAnything模型。
Binary file not shown.

After

Width:  |  Height:  |  Size: 337 KiB

+130
View File
@@ -0,0 +1,130 @@
# layerstyle advance
from .imagefunc import *
from .segment_anything_func import *
class LS_LoadSAMModels:
def __init__(self):
self.NODE_NAME = 'SegmentAnythingUltra V3'
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"sam_model": (list_sam_model(), ),
"grounding_dino_model": (list_groundingdino_model(),),
},
"optional": {
}
}
RETURN_TYPES = ("LS_SAM_MODELS",)
RETURN_NAMES = ("sam_models", )
FUNCTION = "load_sam_models"
CATEGORY = '😺dzNodes/LayerMask'
def load_sam_models(self, sam_model, grounding_dino_model):
SAM_MODEL = load_sam_model(sam_model)
DINO_MODEL = load_groundingdino_model(grounding_dino_model)
return ({"SAM_MODEL":SAM_MODEL, "DINO_MODEL":DINO_MODEL},)
class LS_SegmentAnythingUltraV3:
def __init__(self):
self.NODE_NAME = 'SegmentAnythingUltra V3'
@classmethod
def INPUT_TYPES(cls):
method_list = ['VITMatte', 'VITMatte(local)', 'PyMatting', 'GuidedFilter', ]
device_list = ['cuda','cpu']
return {
"required": {
"image": ("IMAGE",),
"sam_models": ("LS_SAM_MODELS", ),
"threshold": ("FLOAT", {"default": 0.3, "min": 0, "max": 1.0, "step": 0.01}),
"detail_method": (method_list,),
"detail_erode": ("INT", {"default": 6, "min": 1, "max": 255, "step": 1}),
"detail_dilate": ("INT", {"default": 6, "min": 1, "max": 255, "step": 1}),
"black_point": ("FLOAT", {"default": 0.15, "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}),
"prompt": ("STRING", {"default": "subject"}),
"device": (device_list,),
"max_megapixels": ("FLOAT", {"default": 2.0, "min": 1, "max": 999, "step": 0.1}),
},
"optional": {
}
}
RETURN_TYPES = ("IMAGE", "MASK",)
RETURN_NAMES = ("image", "mask",)
FUNCTION = "segment_anything_ultra_v3"
CATEGORY = '😺dzNodes/LayerMask'
def segment_anything_ultra_v3(self, image, sam_models, threshold,
detail_method, detail_erode, detail_dilate,
black_point, white_point, process_detail, prompt,
device, max_megapixels,
):
if detail_method == 'VITMatte(local)':
local_files_only = True
else:
local_files_only = False
SAM_MODEL = sam_models["SAM_MODEL"]
DINO_MODEL = sam_models["DINO_MODEL"]
ret_images = []
ret_masks = []
for i in image:
i = torch.unsqueeze(i, 0)
i = pil2tensor(tensor2pil(i).convert('RGB'))
_image = tensor2pil(i).convert('RGBA')
boxes = groundingdino_predict(DINO_MODEL, _image, prompt, threshold)
if boxes.shape[0] == 0:
break
(_, _mask) = sam_segment(SAM_MODEL, _image, boxes)
_mask = _mask[0]
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(_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)
_image = RGB2RGBA(tensor2pil(i).convert('RGB'), _mask.convert('L'))
ret_images.append(pil2tensor(_image))
ret_masks.append(image2mask(_mask))
if len(ret_masks) == 0:
_, height, width, _ = image.size()
empty_mask = torch.zeros((1, height, width), dtype=torch.uint8, device="cpu")
return (empty_mask, empty_mask)
log(f"{self.NODE_NAME} Processed {len(ret_masks)} image(s).", message_type='finish')
return (torch.cat(ret_images, dim=0), torch.cat(ret_masks, dim=0),)
NODE_CLASS_MAPPINGS = {
"LayerMask: SegmentAnythingUltra V3": LS_SegmentAnythingUltraV3,
"LayerMask: LoadSegmentAnythingModels": LS_LoadSAMModels,
}
NODE_DISPLAY_NAME_MAPPINGS = {
"LayerMask: SegmentAnythingUltra V3": "LayerMask: SegmentAnythingUltra V3(Advance)",
"LayerMask: LoadSegmentAnythingModels": "LayerMask: Load SegmentAnything Models(Advance)",
}
+124
View File
@@ -0,0 +1,124 @@
# layerstyle advance
import os
import torch
import base64
import requests
from io import BytesIO
from zhipuai import ZhipuAI
import folder_paths
from PIL import Image
from .imagefunc import log, tensor2pil, get_api_key
# apikey申请地址:https://bigmodel.cn/usercenter/proj-mgmt/apikeys
class LS_ZhipuImage:
def __init__(self):
self.NODE_NAME = 'ZhipuGLM4V'
@classmethod
def INPUT_TYPES(cls):
glm_model_list = ["glm-4v-flash", "glm-4v", "glm-4v-plus"]
return {"required":{
"image": ("IMAGE",),
"model": (glm_model_list,),
"user_prompt": ("STRING", {"default": "describe this image", "multiline": True}),
},
"optional": {
}
}
RETURN_TYPES = ("STRING",)
RETURN_NAMES = ("text",)
FUNCTION = "zhipu_glm4v"
CATEGORY = '😺dzNodes/LayerUtility'
def zhipu_glm4v(self, image, model, user_prompt,):
client = ZhipuAI(api_key=get_api_key('zhipu_api_key')) # APIKey
img = tensor2pil(image).convert('RGB')
img_data = BytesIO()
img.save(img_data, format="JPEG")
img_url = base64.b64encode(img_data.getvalue()).decode("utf-8")
messages = [
{"role": "user",
"content": [
{"type": "text",
"text": user_prompt
},
{"type": "image_url",
"image_url": {"url": img_url}
}
]
}
]
response = client.chat.completions.create(
model=model, # 填写需要调用的模型名称
messages=messages
)
ret_message = response.choices[0].message.content
log(f"{self.NODE_NAME} response is: {ret_message}")
return (ret_message,)
class LS_ZhipuText:
def __init__(self):
self.NODE_NAME = 'ZhipuGLM4'
@classmethod
def INPUT_TYPES(cls):
glm_model_list = ["GLM-4-Flash", "GLM-4-FlashX", "GLM-4-Plus", "GLM-4-Long","GLM-4-Air", "GLM-4-AirX"]
return {"required":{
"model": (glm_model_list,),
"user_prompt": ("STRING", {"default": "where is the capital of France?", "multiline": True}),
"history_length": ("INT", {"default": 8, "min": 1, "max": 64, "step": 1}),
},
"optional": {
"history": ("GLM4_HISTORY",),
}
}
RETURN_TYPES = ("STRING", "GLM4_HISTORY",)
RETURN_NAMES = ("text", "history",)
FUNCTION = "zhipu_glm4"
CATEGORY = '😺dzNodes/LayerUtility'
def zhipu_glm4(self, model, user_prompt, history_length, history=None):
client = ZhipuAI(api_key=get_api_key('zhipu_api_key')) # APIKey
if history is not None:
messages = history["messages"]
messages = messages[-history_length *2:]
else:
messages = []
task = {"role": "user", "content": user_prompt}
messages.append(task)
response = client.chat.completions.create(
model=model, # 填写需要调用的模型名称
messages=messages
)
ret_message = response.choices[0].message.content
messages.append({"role": "assistant", "content": ret_message})
log(f"{self.NODE_NAME} response is: {ret_message}")
return (ret_message, {"messages":messages},)
NODE_CLASS_MAPPINGS = {
"LayerUtility: ZhipuGLM4V": LS_ZhipuImage,
"LayerUtility: ZhipuGLM4": LS_ZhipuText,
}
NODE_DISPLAY_NAME_MAPPINGS = {
"LayerUtility: ZhipuGLM4V": "LayerUtility: ZhipuGLM4V(Advance)",
"LayerUtility: ZhipuGLM4": "LayerUtility: ZhipuGLM4(Advance)",
}
+1 -1
View File
@@ -1,7 +1,7 @@
[project]
name = "comfyui_layerstyle_advance"
description = "The nodes detached from ComfyUI Layer Style are mainly those with complex requirements for dependency packages."
version = "2.0.8"
version = "2.0.9"
license = "MIT"
dependencies = ["numpy", "matplotlib", "scikit_image", "scikit_learn", "opencv-contrib-python", "pymatting", "timm", "blend_modes", "transformers", "diffusers", "loguru", "colour-science", "huggingface_hub", "segment_anything", "addict", "omegaconf", "yapf", "wget", "iopath", "mediapipe", "typer_config", "fastapi", "rich", "google-generativeai", "ultralytics", "transparent-background", "accelerate", "onnxruntime", "bitsandbytes", "peft", "protobuf", "hydra-core", "blind-watermark", "qrcode", "pyzbar", "psd-tools", "wandb"]