commit DrawBBOXMaskV2 node

This commit is contained in:
chflame163
2024-12-16 17:10:14 +08:00
parent 4d35606a39
commit 662f10c151
8 changed files with 532 additions and 10 deletions
+12 -2
View File
@@ -145,6 +145,7 @@ Please try downgrading the ```protobuf``` dependency package to 3.20.3, or set e
**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 [DrawBBOXMaskV2](#DrawBBOXMaskV2) node, can draw rounded rectangle masks.
* Commit [SmolLM2](#SmolLM2), [SmolVLM](#SmolVLM), [LoadSmolLM2Model](#LoadSmolLM2Model) and [LoadSmolVLMModel](#LoadSmolVLMModel) nodes, use SMOL model for text inference and image recognition.
download the model file from [BaiduNetdisk](https://pan.baidu.com/s/1_jeNosYdDqqHkzpnSNGfDQ?pwd=to5b) or [huggingface](https://huggingface.co/chflame163/ComfyUI_LayerStyle/tree/main/ComfyUI/models/smol) and copy to ```ComfyUI/models/smol``` folder.
* Florence2 add support [gokaygokay/Florence-2-Flux-Large](https://huggingface.co/gokaygokay/Florence-2-Flux-Large) and [gokaygokay/Florence-2-Flux](https://huggingface.co/gokaygokay/Florence-2-Flux) models,
@@ -153,7 +154,6 @@ download Florence-2-Flux-Large and Florence-2-Flux folder from [BaiduNetdisk](ht
* Strip some nodes from [ComfyUI Layer Style](https://github.com/chflame163/ComfyUI_LayerStyle) to this repository.
## Description
### <a id="table1">QWenImage2Prompt</a>
@@ -798,7 +798,8 @@ Node Options:
* bbox_select: Select the input box data. There are three options: "all" to select all, "first" to select the box with the highest confidence, and "by_index" to specify the index of the box.
* select_index: This option is valid when bbox_delect is 'by_index'. 0 is the first one. Multiple values can be entered, separated by any non numeric character, including but not limited to commas, periods, semicolons, spaces or letters, and even Chinese.
### <a id="table1">ObjectDetectorYOLOWorld</a>(Obsoleted. If you want to continue using it, you need to manually install the dependency package)
### <a id="table1">ObjectDetectorYOLOWorld</a>
#### (Obsoleted. If you want to continue using it, you need to manually install the dependency package)
Due to potential installation issues with dependency packages, this node has been obsoleted. To use, please manually install the following dependency packages:
```
pip install inference-cli>=0.13.0
@@ -872,6 +873,15 @@ Node Options:
* grow_left: Each BBox expands to the left as a percentage of its width, positive values expand to the left and negative values expand to the right.
* grow_right: Each BBox expands to the right as a percentage of its width, positive values indicate expansion to the right and negative values indicate expansion to the left.
### <a id="table1">DrawBBoxMaskV2</a>
Add rounded rectangle drawing to the [DrawBBoxMask](#DrawBBoxMask) node.
![image](image/draw_bbox_mask_v2_example.jpg)
Add Options:
![image](image/draw_bbox_mask_v2_node.jpg)
* rounded_rect_radius: Rounded rectangle radius. The range is 0-100, and the larger the value, the more pronounced the rounded corners.
* anti_aliasing: Anti aliasing, ranging from 0-16, with larger values indicating less pronounced aliasing. Excessive values will significantly reduce the processing speed of nodes.
### <a id="table1">EVF-SAMUltra</a>
This node is implementation of [EVF-SAM](https://github.com/hustvl/EVF-SAM) in ComfyUI.
+10
View File
@@ -121,6 +121,7 @@ If this call came from a _pb2.py file, your generated code is out of date and mu
## 更新说明
**如果本插件更新后出现依赖包错误,请双击运行插件目录下的```install_requirements.bat```(官方便携包),或 ```install_requirements_aki.bat```(秋叶整合包) 重新安装依赖包。
* 添加 [DrawBBOXMaskV2](#DrawBBOXMaskV2) 节点,可绘制圆角矩形遮罩。
* 添加 [SmolLM2](#SmolLM2), [SmolVLM](#SmolVLM), [LoadSmolLM2Model](#LoadSmolLM2Model) 和 [LoadSmolVLMModel](#LoadSmolVLMModel) 节点,使用smol轻量级本地模型进行文本推理和图片识别。
从[百度网盘](https://pan.baidu.com/s/1_jeNosYdDqqHkzpnSNGfDQ?pwd=to5b) 或 [huggingface](https://huggingface.co/chflame163/ComfyUI_LayerStyle/tree/main/ComfyUI/models/smol) 下载模型文件至```ComfyUI/models/smol```文件夹。
* Florence2 节点支持[gokaygokay/Florence-2-Flux-Large](https://huggingface.co/gokaygokay/Florence-2-Flux-Large) 和 [gokaygokay/Florence-2-Flux](https://huggingface.co/gokaygokay/Florence-2-Flux)模型。
@@ -794,6 +795,15 @@ pip install inference-gpu[yolo-world]>=0.13.0
* grow_left: 每个识别框向左扩展范围,为识别框宽度的百分比。正值为向左扩展,负值为向右扩展。
* grow_right: 每个识别框向右扩展范围,为识别框宽度的百分比。正值为向右扩展,负值为向左扩展。
### <a id="table1">DrawBBoxMaskV2</a>
在[DrawBBoxMask](#DrawBBoxMask) 节点基础上增加圆角矩形绘制。
![image](image/draw_bbox_mask_v2_example.jpg)
新增选项:
![image](image/draw_bbox_mask_v2_node.jpg)
* rounded_rect_radius: 圆角矩形半径,范围0-100,数值越大圆角半径越大。
* anti_alias: 抗锯齿,范围从0-16,数值越大,锯齿越不明显。过高的数值将显著降低节点的处理速度。
### <a id="table1">EVF-SAMUltra</a>
本节点是[EVF-SAM](https://github.com/hustvl/EVF-SAM)在ComfyUI中的实现。
Binary file not shown.

After

Width:  |  Height:  |  Size: 435 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

+25
View File
@@ -748,6 +748,31 @@ def gradient(start_color_inhex:str, end_color_inhex:str, width:int, height:int,
ret_image = ret_image.resize((width, height))
return ret_image
def draw_rounded_rectangle(image:Image, radius:int, bboxes:list, scale_factor:int=2, color:str="white") -> Image:
"""
绘制圆角矩形图像。
image:输入图片
radius: 半径,100为纯椭圆
bboxes: (x1,y1,x2,y2)列表
scale_factor: 放大倍数
:return: 绘制好的pillow图像
"""
if scale_factor < 1 : scale_factor = 1
img = image.resize((image.width * scale_factor, image.height * scale_factor), Image.LANCZOS)
draw = ImageDraw.Draw(img)
for (x1, y1, x2, y2) in bboxes:
r = radius * min(x2-x1, y2-y1) * 0.005
x1, y1, x2, y2 = x1 * scale_factor, y1 * scale_factor, x2 * scale_factor, y2 * scale_factor
# 计算圆角矩形的四个角的圆弧
draw.rounded_rectangle([x1, y1, x2, y2], radius=r * scale_factor, fill=color)
img = img.filter(ImageFilter.SMOOTH_MORE)
img = img.resize((image.width, image.height), Image.LANCZOS)
return img
def draw_rect(image:Image, x:int, y:int, width:int, height:int, line_color:str, line_width:int,
box_color:str=None) -> Image:
draw = ImageDraw.Draw(image)
+91 -7
View File
@@ -1,5 +1,5 @@
# layerstyle advance
import folder_paths
from .imagefunc import *
select_list = ["all", "first", "by_index"]
@@ -179,8 +179,8 @@ class LS_OBJECT_DETECTOR_FL2:
y1_c = height
x2_c = y2_c = 0
for polygon in F_BBOXES["polygons"][0]:
if len(_polygon) < 3:
print('Invalid polygon:', _polygon)
if len(polygon) < 3:
print('Invalid polygon:', polygon)
continue
x1_c = min(x1_c, int(min(polygon[0::2])))
x2_c = max(x2_c, int(max(polygon[0::2])))
@@ -347,8 +347,11 @@ class LS_OBJECT_DETECTOR_YOLOWORLD:
ret_previews = []
ret_bboxes = []
import supervision as sv
try:
import supervision as sv
except ImportError as e:
log(f"{self.NODE_NAME}: {e}", message_type='warning')
return None
model=self.load_yolo_world_model(yolo_world_model, prompt)
for i in image:
@@ -393,14 +396,17 @@ class LS_OBJECT_DETECTOR_YOLOWORLD:
return [category.strip().lower() for category in categories.split(',')]
def load_yolo_world_model(self,model_id: str, categories: str) -> List[torch.nn.Module]:
from inference.models import YOLOWorld as YOLOWorldImpl
try:
from inference.models import YOLOWorld as YOLOWorldImpl
except ImportError as e:
log(f"{self.NODE_NAME}: {e}", message_type='warning')
return None
model = YOLOWorldImpl(model_id=model_id)
categories = self.process_categories(categories)
model.set_classes(categories)
return model
class LS_DrawBBoxMask:
def __init__(self):
@@ -467,8 +473,85 @@ class LS_DrawBBoxMask:
return (torch.cat(ret_masks, dim=0),)
class LS_DrawBBoxMaskV2:
def __init__(self):
self.NODE_NAME = 'Draw BBOX Mask V2'
pass
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"image": ("IMAGE",),
"bboxes": ("BBOXES",),
"grow_top": ("FLOAT", {"default": 0, "min": -10, "max": 10, "step": 0.01}), # bbox向上扩展,按高度比例
"grow_bottom": ("FLOAT", {"default": 0, "min": -10, "max": 10, "step": 0.01}),
"grow_left": ("FLOAT", {"default": 0, "min": -10, "max": 10, "step": 0.01}),
"grow_right": ("FLOAT", {"default": 0, "min": -10, "max": 10, "step": 0.01}),
"rounded_rect_radius": ("INT", {"default": 50, "min": 0, "max": 100, "step": 1}),
"anti_aliasing": ("INT", {"default": 2, "min": 0, "max": 16, "step": 1}),
},
"optional": {
}
}
RETURN_TYPES = ("MASK",)
RETURN_NAMES = ("mask",)
FUNCTION = 'draw_bbox_mask_v2'
CATEGORY = '😺dzNodes/LayerMask'
def draw_bbox_mask_v2(self, image, bboxes, grow_top, grow_bottom, grow_left, grow_right,
rounded_rect_radius, anti_aliasing):
ret_masks = []
for index in range(len(image)):
img = tensor2pil(image[index].unsqueeze(0))
mask = Image.new("L", img.size, color='black')
bboxes_i = bboxes[index]
if grow_top or grow_bottom or grow_left or grow_right:
new_bboxes_i = []
for bbox in bboxes_i:
try:
if len(bbox) == 0:
continue
else:
x1, y1, x2, y2 = bbox
except ValueError:
if len(bbox) == 0:
continue
else:
x1, y1, x2, y2 = bbox[index]
w = x2 - x1
h = y2 - y1
if grow_top:
y1 = int(y1 - h * grow_top)
if grow_bottom:
y2 = int(y2 + h * grow_bottom)
if grow_left:
x1 = int(x1 - w * grow_left)
if grow_right:
x2 = int(x2 + w * grow_right)
if y1 > y2:
y1, y2 = y2, y1
if x1 > x2:
x1, x2 = x2, x1
if y2 - y1 < 1:
y2 += 1
if x2 - x1 < 1:
x2 += 1
new_bboxes_i.append((x1, y1, x2, y2))
bboxes_i = new_bboxes_i
mask = draw_rounded_rectangle(mask, rounded_rect_radius, bboxes_i, anti_aliasing)
ret_masks.append(pil2tensor(mask))
log(f"{self.NODE_NAME} Processed {len(ret_masks)} mask(s).", message_type='finish')
return (torch.cat(ret_masks, dim=0),)
NODE_CLASS_MAPPINGS = {
"LayerMask: BBoxJoin": LS_BBOXES_JOIN,
"LayerMask: DrawBBoxMaskV2": LS_DrawBBoxMaskV2,
"LayerMask: DrawBBoxMask": LS_DrawBBoxMask,
"LayerMask: ObjectDetectorFL2": LS_OBJECT_DETECTOR_FL2,
"LayerMask: ObjectDetectorMask": LS_OBJECT_DETECTOR_MASK,
@@ -478,6 +561,7 @@ NODE_CLASS_MAPPINGS = {
NODE_DISPLAY_NAME_MAPPINGS = {
"LayerMask: BBoxJoin": "LayerMask: BBox Join(Advance)",
"LayerMask: DrawBBoxMaskV2": "LayerMask: Draw BBox Mask V2(Advance)",
"LayerMask: DrawBBoxMask": "LayerMask: Draw BBox Mask(Advance)",
"LayerMask: ObjectDetectorFL2": "LayerMask: Object Detector Florence2(Advance)",
"LayerMask: ObjectDetectorMask": "LayerMask: Object Detector Mask(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.4"
version = "2.0.5"
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"]
+393
View File
@@ -0,0 +1,393 @@
{
"last_node_id": 10,
"last_link_id": 10,
"nodes": [
{
"id": 5,
"type": "LayerMask: LoadFlorence2Model",
"pos": [
-3210.825927734375,
1715.41015625
],
"size": [
368.73028564453125,
58
],
"flags": {},
"order": 0,
"mode": 0,
"inputs": [],
"outputs": [
{
"name": "florence2_model",
"type": "FLORENCE2",
"links": [
3
]
}
],
"properties": {
"Node name for S&R": "LayerMask: LoadFlorence2Model"
},
"widgets_values": [
"base"
],
"color": "rgba(27, 80, 119, 0.7)"
},
{
"id": 4,
"type": "LayerMask: ObjectDetectorFL2",
"pos": [
-3201.633056640625,
1844.1142578125
],
"size": [
378,
150
],
"flags": {},
"order": 2,
"mode": 0,
"inputs": [
{
"name": "image",
"type": "IMAGE",
"link": 4
},
{
"name": "florence2_model",
"type": "FLORENCE2",
"link": 3
}
],
"outputs": [
{
"name": "bboxes",
"type": "BBOXES",
"links": [
6
],
"slot_index": 0
},
{
"name": "preview",
"type": "IMAGE",
"links": [
5
],
"slot_index": 1
}
],
"properties": {
"Node name for S&R": "LayerMask: ObjectDetectorFL2"
},
"widgets_values": [
"car",
"left_to_right",
"all",
"0,"
],
"color": "rgba(27, 80, 119, 0.7)"
},
{
"id": 6,
"type": "PreviewImage",
"pos": [
-2680.909912109375,
1622.822998046875
],
"size": [
373.50555419921875,
261.75958251953125
],
"flags": {},
"order": 4,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 5
}
],
"outputs": [],
"properties": {
"Node name for S&R": "PreviewImage"
},
"widgets_values": []
},
{
"id": 7,
"type": "LayerMask: MaskPreview",
"pos": [
-2269.84716796875,
1622.8236083984375
],
"size": [
354.0278015136719,
257.8196105957031
],
"flags": {},
"order": 5,
"mode": 0,
"inputs": [
{
"name": "mask",
"type": "MASK",
"link": 7
}
],
"outputs": [],
"properties": {
"Node name for S&R": "LayerMask: MaskPreview"
},
"widgets_values": [],
"color": "rgba(27, 80, 119, 0.7)"
},
{
"id": 2,
"type": "LoadImage",
"pos": [
-3583.1455078125,
2019.438232421875
],
"size": [
315,
314
],
"flags": {},
"order": 1,
"mode": 0,
"inputs": [],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
1,
4,
8
],
"slot_index": 0
},
{
"name": "MASK",
"type": "MASK",
"links": null
}
],
"properties": {
"Node name for S&R": "LoadImage"
},
"widgets_values": [
"1280x720car.jpg",
"image"
]
},
{
"id": 9,
"type": "PreviewImage",
"pos": [
-1886.3648681640625,
1981.2880859375
],
"size": [
363.8528137207031,
311.7305603027344
],
"flags": {},
"order": 7,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 10
}
],
"outputs": [],
"properties": {
"Node name for S&R": "PreviewImage"
},
"widgets_values": []
},
{
"id": 8,
"type": "LayerUtility: ImageCombineAlpha",
"pos": [
-2273.5244140625,
2261.54541015625
],
"size": [
295.9768371582031,
46
],
"flags": {},
"order": 6,
"mode": 0,
"inputs": [
{
"name": "RGB_image",
"type": "IMAGE",
"link": 8
},
{
"name": "mask",
"type": "MASK",
"link": 9
}
],
"outputs": [
{
"name": "RGBA_image",
"type": "IMAGE",
"links": [
10
],
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "LayerUtility: ImageCombineAlpha"
},
"widgets_values": [],
"color": "rgba(38, 73, 116, 0.7)"
},
{
"id": 1,
"type": "LayerMask: DrawBBoxMaskV2",
"pos": [
-2681.6484375,
2029.784423828125
],
"size": [
349.97314453125,
198
],
"flags": {},
"order": 3,
"mode": 0,
"inputs": [
{
"name": "image",
"type": "IMAGE",
"link": 1
},
{
"name": "bboxes",
"type": "BBOXES",
"link": 6
}
],
"outputs": [
{
"name": "mask",
"type": "MASK",
"links": [
7,
9
],
"slot_index": 0
}
],
"properties": {
"Node name for S&R": "LayerMask: DrawBBoxMaskV2"
},
"widgets_values": [
0.11,
0.11,
0.06,
0.06,
70,
2
],
"color": "rgba(27, 80, 119, 0.7)"
}
],
"links": [
[
1,
2,
0,
1,
0,
"IMAGE"
],
[
3,
5,
0,
4,
1,
"FLORENCE2"
],
[
4,
2,
0,
4,
0,
"IMAGE"
],
[
5,
4,
1,
6,
0,
"IMAGE"
],
[
6,
4,
0,
1,
1,
"BBOXES"
],
[
7,
1,
0,
7,
0,
"MASK"
],
[
8,
2,
0,
8,
0,
"IMAGE"
],
[
9,
1,
0,
8,
1,
"MASK"
],
[
10,
8,
0,
9,
0,
"IMAGE"
]
],
"groups": [],
"config": {},
"extra": {
"ds": {
"scale": 0.7627768444385546,
"offset": [
4132.421086528808,
-1131.7549496286297
]
}
},
"version": 0.4
}