vault backup: 2026-05-04 15:21:55

This commit is contained in:
2026-05-04 15:21:55 +08:00
parent 6a3c075718
commit 7f0d4172dd
8 changed files with 15 additions and 2260 deletions

4
.obsidian/app.json vendored
View File

@@ -1 +1,3 @@
{}
{
"promptDelete": false
}

View File

@@ -4,21 +4,19 @@
"type": "split",
"children": [
{
"id": "bed95db68cbc7968",
"id": "3fa16f0536c3ff30",
"type": "tabs",
"children": [
{
"id": "e6beb8291eaadf9d",
"id": "16cb1b7f13de27e8",
"type": "leaf",
"state": {
"type": "markdown",
"type": "excalidraw",
"state": {
"file": "自动语义分割系统/参考内容/插件功能大全.md",
"mode": "source",
"source": false
"file": "Excalidraw/Drawing 2026-04-22 22.49.50.excalidraw.md"
},
"icon": "lucide-file",
"title": "插件功能大全"
"icon": "excalidraw-icon",
"title": "Drawing 2026-04-22 22.49.50.excalidraw"
}
}
]
@@ -78,8 +76,7 @@
}
],
"direction": "horizontal",
"width": 300,
"collapsed": true
"width": 300
},
"right": {
"id": "e79bfe08f878d433",
@@ -179,7 +176,7 @@
}
],
"direction": "horizontal",
"width": 272.5
"width": 432.5
},
"left-ribbon": {
"hiddenItems": {
@@ -195,14 +192,16 @@
"obsidian-excalidraw-plugin:新建绘图文件": false
}
},
"active": "98c4d568edb73698",
"active": "16cb1b7f13de27e8",
"lastOpenFiles": [
"Excalidraw/Drawing 2026-04-22 22.49.48.excalidraw.md",
"Excalidraw/Drawing 2026-04-22 22.40.08.excalidraw.md",
"自动语义分割系统/参考内容/插件功能大全.md",
"自动语义分割系统/ComfyUI 搭建操作指南.md",
"自动语义分割系统/系统设计.md",
"自动语义分割系统/2026_4_24_视频分割工作流构建-ComfyUI.json",
"自动语义分割系统/2026_4_24_视频分割工作流构建-ComfulUI.json",
"自动语义分割系统/参考内容/视频笔记-ComfyUI SAM2 Easy Tutorial.md",
"自动语义分割系统/参考内容/插件功能大全.md",
"自动语义分割系统/参考内容/安装步骤.md",
"自动语义分割系统/参考内容",
"自动语义分割系统/New Folder",
@@ -212,9 +211,7 @@
"自动语义分割系统/视频笔记-ComfyUI SAM2 Easy Tutorial.md",
"自动语义分割系统/插件功能大全.md",
"自动语义分割系统/安装步骤.md",
"Excalidraw/Drawing 2026-04-22 22.49.48.excalidraw.md",
"Excalidraw/Drawing 2026-04-22 22.49.50.excalidraw.md",
"Excalidraw/Drawing 2026-04-22 22.40.08.excalidraw.md",
"Excalidraw",
"欢迎.md",
"创建链接.md",

View File

@@ -1,679 +0,0 @@
{
"id": "9c953d5b-bd9f-4dd5-b7a1-b9ca4bd07506",
"revision": 0,
"last_node_id": 25,
"last_link_id": 29,
"nodes": [
{
"id": 10,
"type": "VHS_LoadVideo",
"pos": [
-813.3850275312833,
-125.79703269581762
],
"size": [
255.703125,
547.0625
],
"flags": {},
"order": 0,
"mode": 0,
"inputs": [
{
"name": "meta_batch",
"shape": 7,
"type": "VHS_BatchManager",
"link": null
},
{
"name": "vae",
"shape": 7,
"type": "VAE",
"link": null
}
],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
21,
22,
29
]
},
{
"name": "frame_count",
"type": "INT",
"links": null
},
{
"name": "audio",
"type": "AUDIO",
"links": null
},
{
"name": "video_info",
"type": "VHS_VIDEOINFO",
"links": null
}
],
"properties": {
"Node name for S&R": "VHS_LoadVideo",
"ue_properties": {
"widget_ue_connectable": {},
"input_ue_unconnectable": {},
"version": "7.8"
}
},
"widgets_values": {
"video": "MyVideo_1.mp4",
"force_rate": 0,
"custom_width": 0,
"custom_height": 0,
"frame_load_cap": 0,
"skip_first_frames": 0,
"select_every_nth": 10,
"format": "AnimateDiff",
"videopreview": {
"hidden": false,
"paused": false,
"params": {
"filename": "MyVideo_1.mp4",
"type": "input",
"format": "video/mp4",
"force_rate": 0,
"custom_width": 0,
"custom_height": 0,
"frame_load_cap": 0,
"skip_first_frames": 0,
"select_every_nth": 10
}
}
}
},
{
"id": 12,
"type": "PointsEditor",
"pos": [
-471.05468863793067,
312.66627281791796
],
"size": [
1069,
886
],
"flags": {},
"order": 4,
"mode": 0,
"inputs": [
{
"name": "bg_image",
"shape": 7,
"type": "IMAGE",
"link": 12
}
],
"outputs": [
{
"name": "positive_coords",
"type": "STRING",
"links": [
15
]
},
{
"name": "negative_coords",
"type": "STRING",
"links": [
16
]
},
{
"name": "bbox",
"type": "BBOX",
"links": []
},
{
"name": "bbox_mask",
"type": "MASK",
"links": null
},
{
"name": "cropped_image",
"type": "IMAGE",
"links": []
}
],
"properties": {
"Node name for S&R": "PointsEditor",
"imgData": {
"type": "temp",
"filename": "editor_bg_12_1777015796944.webp"
},
"ue_properties": {
"widget_ue_connectable": {},
"input_ue_unconnectable": {},
"version": "7.8"
},
"points": "PointsEditor",
"neg_points": "PointsEditor"
},
"widgets_values": [
"{\"positive\":[{\"x\":629.0395751323676,\"y\":995.7090645534695},{\"x\":947.7400307445249,\"y\":449.92024419943976}],\"negative\":[{\"x\":1377.5594957427968,\"y\":723.0772250324787}]}",
"[{\"x\":629.0395751323676,\"y\":995.7090645534695},{\"x\":947.7400307445249,\"y\":449.92024419943976}]",
"[{\"x\":1377.5594957427968,\"y\":723.0772250324787}]",
"[{}]",
"[{}]",
"xyxy",
2560,
1440,
false,
"",
null
]
},
{
"id": 13,
"type": "VHS_SelectImages",
"pos": [
-462.5699037007894,
52.160206857416284
],
"size": [
224.984375,
163.171875
],
"flags": {},
"order": 3,
"mode": 0,
"inputs": [
{
"name": "image",
"type": "IMAGE",
"link": 21
}
],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
12
]
}
],
"properties": {
"Node name for S&R": "VHS_SelectImages",
"ue_properties": {
"widget_ue_connectable": {},
"input_ue_unconnectable": {},
"version": "7.8"
}
},
"widgets_values": {
"indexes": "0",
"err_if_missing": true,
"err_if_empty": true
}
},
{
"id": 16,
"type": "DownloadAndLoadSAM2Model",
"pos": [
99.48210328319615,
-220.15730679302075
],
"size": [
268.8125,
209.796875
],
"flags": {},
"order": 1,
"mode": 0,
"inputs": [],
"outputs": [
{
"name": "sam2_model",
"type": "SAM2MODEL",
"links": [
14
]
}
],
"properties": {
"Node name for S&R": "DownloadAndLoadSAM2Model",
"ue_properties": {
"widget_ue_connectable": {},
"input_ue_unconnectable": {},
"version": "7.8"
}
},
"widgets_values": [
"sam2.1_hiera_base_plus.safetensors",
"video",
"cuda",
"bf16"
]
},
{
"id": 17,
"type": "Sam2Segmentation",
"pos": [
774.5521151038394,
142.6488611452116
],
"size": [
276.5,
247.171875
],
"flags": {},
"order": 5,
"mode": 0,
"inputs": [
{
"name": "sam2_model",
"type": "SAM2MODEL",
"link": 14
},
{
"name": "image",
"type": "IMAGE",
"link": 22
},
{
"name": "coordinates_positive",
"shape": 7,
"type": "STRING",
"link": 15
},
{
"name": "coordinates_negative",
"shape": 7,
"type": "STRING",
"link": 16
},
{
"name": "bboxes",
"shape": 7,
"type": "BBOX",
"link": null
},
{
"name": "mask",
"shape": 7,
"type": "MASK",
"link": null
}
],
"outputs": [
{
"name": "mask",
"type": "MASK",
"links": [
23,
28
]
}
],
"properties": {
"Node name for S&R": "Sam2Segmentation",
"ue_properties": {
"widget_ue_connectable": {},
"input_ue_unconnectable": {},
"version": "7.8"
}
},
"widgets_values": [
true,
true
]
},
{
"id": 19,
"type": "VHS_LoadVideoPath",
"pos": [
-799.8335715537742,
519.541686479997
],
"size": [
238.140625,
503.359375
],
"flags": {},
"order": 2,
"mode": 0,
"inputs": [
{
"name": "meta_batch",
"shape": 7,
"type": "VHS_BatchManager",
"link": null
},
{
"name": "vae",
"shape": 7,
"type": "VAE",
"link": null
}
],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": []
},
{
"name": "frame_count",
"type": "INT",
"links": null
},
{
"name": "audio",
"type": "AUDIO",
"links": null
},
{
"name": "video_info",
"type": "VHS_VIDEOINFO",
"links": null
}
],
"properties": {
"Node name for S&R": "VHS_LoadVideoPath",
"ue_properties": {
"widget_ue_connectable": {},
"input_ue_unconnectable": {},
"version": "7.8"
}
},
"widgets_values": {
"video": "C:\\Users\\Administrator\\Desktop\\MyVideo_1.mp4",
"force_rate": 0,
"custom_width": 0,
"custom_height": 0,
"frame_load_cap": 0,
"skip_first_frames": 0,
"select_every_nth": 1,
"format": "AnimateDiff",
"videopreview": {
"hidden": false,
"paused": false,
"params": {
"filename": "C:\\Users\\Administrator\\Desktop\\MyVideo_1.mp4",
"type": "path",
"format": "video/mp4",
"force_rate": 0,
"custom_width": 0,
"custom_height": 0,
"frame_load_cap": 0,
"skip_first_frames": 0,
"select_every_nth": 1
}
}
}
},
{
"id": 21,
"type": "VHS_VideoCombine",
"pos": [
1367.7738783623959,
145.29475149708412
],
"size": [
377.125,
655.796875
],
"flags": {},
"order": 8,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 24
},
{
"name": "audio",
"shape": 7,
"type": "AUDIO",
"link": null
},
{
"name": "meta_batch",
"shape": 7,
"type": "VHS_BatchManager",
"link": null
},
{
"name": "vae",
"shape": 7,
"type": "VAE",
"link": null
}
],
"outputs": [
{
"name": "Filenames",
"type": "VHS_FILENAMES",
"links": null
}
],
"properties": {
"Node name for S&R": "VHS_VideoCombine",
"ue_properties": {
"widget_ue_connectable": {},
"input_ue_unconnectable": {},
"version": "7.8"
}
},
"widgets_values": {
"frame_rate": 10,
"loop_count": 0,
"filename_prefix": "AnimateDiff",
"format": "video/nvenc_h264-mp4",
"pix_fmt": "yuv420p",
"bitrate": 10,
"megabit": true,
"save_metadata": true,
"pingpong": false,
"save_output": true,
"videopreview": {
"hidden": false,
"paused": false,
"params": {
"filename": "AnimateDiff_00001.mp4",
"subfolder": "",
"type": "output",
"format": "video/nvenc_h264-mp4",
"frame_rate": 10,
"workflow": "AnimateDiff_00001.png",
"fullpath": "C:\\Users\\Administrator\\Documents\\ComfyUI\\output\\AnimateDiff_00001.mp4"
}
}
}
},
{
"id": 22,
"type": "MaskToImage",
"pos": [
1106.0530422762874,
159.15193917563232
],
"size": [
224.984375,
47.234375
],
"flags": {},
"order": 6,
"mode": 0,
"inputs": [
{
"name": "mask",
"type": "MASK",
"link": 23
}
],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
24
]
}
],
"properties": {
"Node name for S&R": "MaskToImage",
"ue_properties": {
"widget_ue_connectable": {},
"input_ue_unconnectable": {},
"version": "7.8"
}
},
"widgets_values": []
},
{
"id": 25,
"type": "PreviewAnimation",
"pos": [
864.1687382115169,
476.5355159824053
],
"size": [
269.546875,
359.1875
],
"flags": {},
"order": 7,
"mode": 0,
"inputs": [
{
"name": "images",
"shape": 7,
"type": "IMAGE",
"link": 29
},
{
"name": "masks",
"shape": 7,
"type": "MASK",
"link": 28
}
],
"outputs": [],
"title": "Preview Animation 150x2560x1440",
"properties": {
"ue_properties": {
"widget_ue_connectable": {},
"input_ue_unconnectable": {}
},
"Node name for S&R": "PreviewAnimation"
},
"widgets_values": [
10
]
}
],
"links": [
[
12,
13,
0,
12,
0,
"IMAGE"
],
[
14,
16,
0,
17,
0,
"SAM2MODEL"
],
[
15,
12,
0,
17,
2,
"STRING"
],
[
16,
12,
1,
17,
3,
"STRING"
],
[
21,
10,
0,
13,
0,
"IMAGE"
],
[
22,
10,
0,
17,
1,
"IMAGE"
],
[
23,
17,
0,
22,
0,
"MASK"
],
[
24,
22,
0,
21,
0,
"IMAGE"
],
[
28,
17,
0,
25,
1,
"MASK"
],
[
29,
10,
0,
25,
0,
"IMAGE"
]
],
"groups": [],
"config": {},
"extra": {
"ds": {
"scale": 0.6830134553650709,
"offset": [
1095.6627703986526,
514.2415918457224
]
},
"ue_links": [],
"links_added_by_ue": [],
"frontendVersion": "1.42.14",
"VHS_latentpreview": false,
"VHS_latentpreviewrate": 0,
"VHS_MetadataImage": true,
"VHS_KeepIntermediate": true
},
"version": 0.4
}

View File

@@ -1,223 +0,0 @@
---
title: ComfyUI 视频分割系统 - 界面搭建操作指南
date: 2026-04-24
tags:
- comfyUI
- 操作指南
- SAM2
- 工作流搭建
---
# ComfyUI 视频分割系统 - 界面搭建操作指南
> 本指南基于 `2026_4_24_视频分割工作流构建.json` 初稿编写,描述当前已实现的工作流,并标注后续扩展方向。
> 扩展参考资料见 [[参考内容/安装步骤.md]]、[[参考内容/插件功能大全.md]]。
---
## 前置要求
请确保已通过 **ComfyUI Manager** 安装以下节点包:
| 节点包 | 用途 | JSON 中使用的节点 |
|:---|:---|:---|
| `ComfyUI-VideoHelperSuite` | 视频加载、帧提取、视频合成 | `VHS_LoadVideo`, `VHS_SelectImages`, `VHS_VideoCombine`, `PreviewAnimation` |
| `ComfyUI-segment-anything-2` | SAM2 模型加载与分割 | `DownloadAndLoadSAM2Model`, `Sam2Segmentation` |
| `ComfyUI-KJNodes` | 交互式坐标编辑器 | `PointsEditor` |
---
## 当前工作流拓扑
```
[VHS_LoadVideo] ───┬──→ [VHS_SelectImages] ──→ [PointsEditor] ──→ [Sam2Segmentation]
│ │ (index=0) (positive_coords) ↑
│ │ (negative_coords) │
│ │ │
│ └───────────────────────────────────────────────────┘
│ ↑
│ [DownloadAndLoadSAM2Model]
└──→ [PreviewAnimation] ←── [Sam2Segmentation(mask)]
[MaskToImage] ──→ [VHS_VideoCombine]
```
**当前状态**:对视频每一帧使用 **相同的交互式坐标** 进行独立分割(`Sam2Segmentation` 接收完整视频批次)。
**扩展目标**:接入 `Sam2VideoSegmentationAddPoints` + `Sam2VideoSegmentation`,实现真正的**跨帧追踪**。
---
## 第一步:加载视频
1. 右键/双击空白处打开节点菜单
2. 找到 **Video Helper Suite**(紫色摄像机图标)
3. 选择 `Load Video``Load Video (Path)`
4. 参数说明:
- `video`: 选择你的视频文件
- `force_rate`: `0`(保持原帧率)
- `frame_load_cap`: `0`(加载全部帧)
- `select_every_nth`: `10`(每 10 帧取 1 帧,降低处理量)
- `format`: `AnimateDiff`
---
## 第二步:提取第一帧作为交互背景
1. 回到 **Video Helper Suite**,选择 `图像`**`Select Images`**
2. 连接:`VHS_LoadVideo``IMAGE``Select Images``image`
3. 参数:`indexes` = `0`(取第 0 帧)
4. 该帧将作为 `PointsEditor` 的背景图,方便你在原图上点击标注
---
## 第三步交互式坐标生成PointsEditor
1. 搜索:`KJNodes``PointsEditor`
2. 连接:`Select Images``IMAGE``PointsEditor``bg_image`
3. 节点功能:
- 在画布上显示第一帧图像
- **点击图像**生成正选点positive输出到 `positive_coords`
- **按住 Shift 点击**生成反选点negative输出到 `negative_coords`
- 支持框选bbox和裁剪预览
4. 参数说明:
- `width` / `height`: 与视频分辨率一致(如 `2560`, `1440`
- `xyxy`: 坐标格式
5. 输出:`positive_coords`(正选坐标 JSON 字符串)、`negative_coords`(反选坐标 JSON 字符串)
> **这是解决"手动填坐标不直观"问题的关键节点。** 你可以反复点击、调整,每次修改后直接运行,无需重新连线。
---
## 第四步:加载 SAM2 模型
1. 搜索:`SAM2``DownloadAndLoadSAM2Model`
2. 参数:
- `model`: `sam2.1_hiera_base_plus.safetensors`
- `segmentor`: `video`(选择视频模式,为后续扩展做准备)
- `device`: `cuda`
- `precision`: `bf16`
3. 输出:`sam2_model`
---
## 第五步单帧分割广播到全视频Sam2Segmentation
1. 搜索:`SAM2``Sam2Segmentation`
2. 连接:
- `DownloadAndLoadSAM2Model``sam2_model``Sam2Segmentation``sam2_model`
- `VHS_LoadVideo``IMAGE`(完整视频批次)→ `Sam2Segmentation``image`
- `PointsEditor``positive_coords``Sam2Segmentation``coordinates_positive`
- `PointsEditor``negative_coords``Sam2Segmentation``coordinates_negative`
3. 参数:
- `keep_model_loaded`: `true`
- `individual_objects`: `true`
4. 输出:`mask`
> **当前行为**`Sam2Segmentation` 对视频批次中的**每一帧**都使用 `PointsEditor` 生成的同一组坐标进行独立分割。如果目标在视频中有大幅位移,后续帧可能分割不准。
>
> **这正是下一步需要扩展视频追踪的原因。**
---
## 第六步:输出与预览
### 6.1 Mask 转图像
1. 搜索:`mask``MaskToImage`
2. 连接:`Sam2Segmentation``mask``MaskToImage``mask`
3. 输出:`IMAGE`(可视化的 mask 图像批次)
### 6.2 合成视频
1. 搜索:`video``VHS_VideoCombine`
2. 连接:`MaskToImage``IMAGE``VHS_VideoCombine``images`
3. 参数:
- `frame_rate`: `10`(与抽帧间隔匹配)
- `format`: `video/nvenc_h264-mp4`
- `filename_prefix`: `AnimateDiff`
- `save_output`: `true`
### 6.3 实时预览
1. 搜索:`VHS``PreviewAnimation`
2. 连接:
- `VHS_LoadVideo``IMAGE``PreviewAnimation``images`(原视频)
- `Sam2Segmentation``mask``PreviewAnimation``masks`(分割 mask
3. 功能:同时播放原视频和 mask便于逐帧检查分割效果
---
## 第七步:后续扩展方向
当前 JSON 只实现了**逐帧独立分割**。下一步扩展为**真正的视频追踪**
### 扩展 1接入 SAM2 视频追踪核心
在现有链路基础上,将 `Sam2Segmentation` 替换或并行为:
```
[Sam2VideoSegmentationAddPoints] ──→ [Sam2VideoSegmentation] ──→ [MaskToImage]
↑ ↑
[(Down)Load SAM2Model] [(Down)Load SAM2Model]
[PointsEditor(positive_coords)]
```
| 步骤 | 操作 |
|:---|:---|
| 1 | 添加 `Sam2VideoSegmentationAddPoints``image` 接入完整视频批次,`coordinates_positive` 接入 `PointsEditor` |
| 2 | 添加 `Sam2VideoSegmentation``inference_state` 接入上一步输出 |
| 3 | `Sam2VideoSegmentation``mask``MaskToImage` |
| 4 | 此时 `PointsEditor` 的坐标只在第 0 帧生效SAM2 会自动追踪目标运动到后续帧 |
### 扩展 2人工纠正分支Fast Muter
当追踪漂移时,在 `prev_inference_state` 路径上链式追加修正节点:
```
[Sam2VideoSegmentationAddPoints(第0帧)]
↓ inference_state
[Sam2VideoSegmentationAddPoints(第N帧修正, prev_inference_state接入)]
↓ inference_state
[Sam2VideoSegmentation]
```
实现方式:
1. 安装 `rgthree-comfy`
2. 创建第二个 `Sam2VideoSegmentationAddPoints`(修正节点)
3. 默认对该修正节点执行 **Bypass**(右键 → Bypass使其不参与运算
4. 需要修正时,取消 Bypass修改 `frame_index` 和坐标,重新运行
### 扩展 3语义提示自动化
当交互式点击不方便时,接入全自动链路:
```
[Text Prompt] ──→ [Florence2 / Grounding DINO] ──→ [Florence2 Coordinates]
──→ [Sam2Segmentation / Sam2VideoSegmentationAddPoints]
```
---
## 运行前检查清单
- [ ] SAM2 模型已下载到 `ComfyUI/models/sam2/``sam2.1_hiera_base_plus.safetensors`
- [ ] `VHS_LoadVideo` 的视频路径有效
- [ ] `Select Images``indexes` = `0`
- [ ] `PointsEditor` 已生成至少一个 `positive_coords`(点击图像)
- [ ] `Sam2Segmentation``image` 接入的是**视频批次**(来自 `VHS_LoadVideo`
- [ ] `VHS_VideoCombine``frame_rate` 与抽帧间隔匹配
---
## 常见问题
| 问题 | 排查方向 |
|:---|:---|
| `PointsEditor` 点击无反应 | 确保 `bg_image` 已连接且有图像输出;检查节点是否支持当前浏览器 |
| 分割结果全黑/全白 | 检查 `coordinates_positive` 是否传入;确认坐标在图像范围内 |
| 后续帧分割漂移 | **正常现象**(当前是逐帧独立分割,非追踪)。解决:扩展接入 `Sam2VideoSegmentation` |
| 显存不足 | `DownloadAndLoadSAM2Model``precision` 改为 `fp16`,或降低视频分辨率 |
| 视频合成帧率不对 | 确保 `select_every_nth``VideoCombine``frame_rate` 匹配 |

View File

@@ -1,185 +0,0 @@
---
title: ComfyUI 视频分割系统 - 安装与搭建步骤
date: 2026-04-22
tags:
- comfyUI
- 安装步骤
- SAM2
- 工作流搭建
---
# ComfyUI 视频分割系统 - 安装与搭建步骤
## 前置要求
在 ComfyUI 界面中操作前,请确保已通过 **ComfyUI Manager管理扩展功能** 安装以下节点包:
| 节点包 | 作用 |
|-------|------|
| `ComfyUI-VideoHelperSuite` | 视频加载、帧提取、视频合成 |
| `ComfyUI-segment-anything-2` | SAM2 模型加载、图像/视频分割与追踪 |
| `ComfyUI-Impact-Pack` | Grounding DINO 语义检测 |
| `rgthree-comfy` | Fast Muter / Bypass 节点 |
安装后**重启 ComfyUI**。
---
## 搭建步骤(共 10 步)
以下所有节点均通过 **双击画布空白处****右键 → 添加节点** 创建。
### 第 1 步:选择加载节点
1. 右键/双击空白处打开节点菜单
2. 在第二级菜单中找到 **Video Helper Suite**(带有紫色摄像机图标的那一项)
3. 在右侧弹出的第三级菜单中,根据你的需求选择以下任意一个节点:
- **Load Video (Upload)**:如果你想从电脑本地上传一个视频文件
- **Load Video (Path)**:如果你想通过输入电脑上的文件夹路径来读取视频
4. 点击创建节点
5. 节点出现在画布上,把它拖到左上角区域
### 第 2 步:提取第一帧(关键帧)
1. 回到 **Video Helper Suite**(紫色摄像机图标)的第三级菜单
2. 找到 `图像` 分类下的 **`Select Images`**
- 在较新版本的 Video Helper Suite 中,它取代了旧版的 `VHS_SelectFrames` 名称功能完全一致都是通过索引Index从视频流中挑选特定帧
3. (可选抽帧)如果你不想逐帧处理,也可以使用它上方的 **`Select Every Nth Image`**,每隔几帧取一张
4. 连接:`Load Video``IMAGE` 输出 → `Select Images``image` 输入
5. 设置参数:`index = 0`(表示取第一帧)
> 这就是你的关键帧,后续所有分割以此为基础。
### 第 3 步SAM2 模型加载器
- 搜索:`SAM2``(Down)Load SAM2Model`
- 拖到画布**中上方**,作为公共模型源
- 参数设置:
- `model`: `sam2.1_hiera_base_plus.safetensors`
- `segmentor`: 根据用途选择(单图或视频)
- `device`: `cuda`
- `precision`: `fp16`(省显存)
### 第 4 步单帧分割测试Sam2Segmentation
- 搜索:`SAM2``Sam2Segmentation`
- 连接:
- `Select Images`(第一帧)→ `image`
- `(Down)Load SAM2Model``sam2_model`
**选择以下任意一种提示方式填入:**
- **方式 A手绘 Mask最直观强烈推荐**
- 将图像连到 `Preview Image`,右键预览图 → `Open in Mask Editor`
- 用画笔涂抹目标区域Save 后得到 `mask`,连到 `Sam2Segmentation``mask` 输入
- 无需精确坐标,手绘粗略区域即可引导 SAM2 分割
- **方式 B点坐标适合精确控制**
- `coordinates_positive`: 填入正选点坐标(如 `[[0.45, 0.52]]`
- `coordinates_negative`: 填入反选点坐标(可选)
- 坐标获取技巧:先用 `Sam2AutoSegmentation` 跑一下看 `bbox` 参考;或在画图软件中读像素坐标再归一化
- **方式 C检测框**
- `bboxes`: 填入边界框 `[x1, y1, x2, y2]`,可通过 Florence-2 / Grounding DINO 自动生成
- 再加一个 `image``Preview Image`,连到 `Sam2Segmentation``mask` 输出
- **点击右上角「运行」**,先确认第一帧分割正确
- **效果不佳时**:直接修改 mask重画或坐标数值再次运行即可快速迭代
### 第 5 步:视频追踪核心链路
**5.1 Sam2VideoSegmentationAddPoints注入提示**
- 搜索:`SAM2``Sam2VideoSegmentationAddPoints`
- 连接:
- `(Down)Load SAM2Model``sam2_model`
- `Load Video` 的完整图像批次 → `image`
- `coordinates_positive`: 第一帧的正选点坐标
- `coordinates_negative`: 反选点坐标(可选)
- 参数:
- `frame_index`: `0`(在第 0 帧添加标注)
- `object_index`: `0`(单目标默认)
- `prev_inference_state`: 首次追踪时留空
**5.2 Sam2VideoSegmentation执行追踪**
- 搜索:`SAM2``Sam2VideoSegmentation`
- 连接:
- `(Down)Load SAM2Model``sam2_model`
- `Sam2VideoSegmentationAddPoints``inference_state``inference_state`
- 参数:`keep_model_loaded` 推荐开启
- 输出:`mask`(完整视频的分割结果)
### 第 6 步:可视化与保存
| 节点 | 路径 | 用途 |
|------|------|------|
| `MaskToImage` | `image``MaskToImage` | 将 mask 转为可视图像 |
| `Preview Image` | `image``Preview Image` | 预览效果 |
| `Save Image` | `image``Save Image` | 保存 mask 序列 |
| `VHS_VideoCombine` | `video``VHS_VideoCombine` | 合成带遮罩的视频 |
### 第 7 步人工纠正分支RGThree Fast Muter
- 搜索:`rgthree``Fast Muter`
- **核心思路**:利用 `Sam2VideoSegmentationAddPoints``prev_inference_state` 链式追加修正,默认通过 Fast Muter / Bypass 跳过修正节点
- 具体搭建:
1. 新建第二个 `Sam2VideoSegmentationAddPoints`,命名为 "Fix_AddPoints"
2. `prev_inference_state` 接入主链路第一个 AddPoints 的 `inference_state`
3. `image`: 接入 `Load Video` 的完整批次
4. `frame_index`: 问题帧号(如 `45`
5. `coordinates_positive`: 修正后的点坐标
6. 该节点的 `inference_state``Sam2VideoSegmentation`
7. 对该修正节点使用 **Bypass** 或在其坐标输入前加 **`Fast Muter`**,默认关闭
- **默认状态**:修正节点被跳过(红色/关闭),不参与运算
- **需要修正时**:取消 Bypass / Fast Muter 变绿(启用),修改帧号和坐标,重新运行
### 第 8 步:总连线检查
确保以下四点:
- `Sam2VideoSegmentationAddPoints``image` 接入的是**完整视频批次**,不是单帧
- `Sam2VideoSegmentationAddPoints``frame_index` 指向了正确的标注帧
- `Sam2Segmentation`(单帧预览)只吃了 `index=0` 的单帧
- Fast Muter / 修正节点 Bypass 状态符合预期
---
## 建议的执行顺序
不要一次性连完所有节点再运行!按以下顺序验证:
1. **只连第 1~4 步**(到 Preview Image→ 运行 → 确认第一帧分割正确
2. **接入第 5~6 步**VideoSegmentationAddPoints + VideoSegmentation + 输出)→ 运行 → 确认整段视频能跑通
3. **最后加第 7 步**Fast Muter 修正分支)→ 测试一次纠正流程
---
## Fast Muter 实际操作流程
```
首次运行:
Fix_AddPoints 被 Bypass / Fast Muter 关闭
→ 点击「运行」→ 检查 Preview Image
发现第 N 帧错了:
1. 修改 "Fix_AddPoints" 的 frame_index = N
2. 修改 "Fix_AddPoints" 的 coordinates_positive 为正确坐标
3. 取消 Bypass / Fast Muter = 绿色(打开)
4. 再次点击「运行」
5. 系统以第 0 帧 + 第 N 帧为锚点,综合追踪整个视频
修好了:
恢复 Bypass / Fast Muter = 红色(关闭)
→ 保存最终工作流模板
```
---
## 常见问题速查
| 问题 | 排查方向 |
|------|---------|
| 节点呈红色/无法创建 | 节点包未安装或加载失败,检查 ComfyUI 启动日志 |
| SAM2 节点报错显存不足 | 换 `sam2.1_hiera_tiny.safetensors`,或降低视频分辨率,或启用 fp16 |
| 追踪结果全黑/全白 | 检查 `coordinates_positive` 是否正确传入检查坐标格式0~1 vs 像素);确认 `frame_index` 与标注帧一致 |
| Florence-2 / Grounding DINO 无检测结果 | 降低 `threshold`,或简化 prompt如只写 `"person"` |
| 修正后重新追踪无变化 | 确认修正节点已取消 Bypass / Fast Muter 已启用;确认修正节点的 `prev_inference_state` 正确接入上游 |
| 视频输出帧率不对 | 在 `Load Video``VideoCombine` 中统一设置 fps 参数 |

View File

@@ -1,540 +0,0 @@
---
title: ComfyUI 插件功能大全
date: 2026-04-24
tags:
- comfyUI
- 插件
- 节点
- 参考手册
---
# ComfyUI 插件功能大全
> 本文档整理视频语义分割系统中涉及的 5 个核心 ComfyUI 插件的全部节点与功能,便于快速查阅与选型。
---
## 1. ComfyUI-segment-anything-2
**作者**: kijai
**仓库**: https://github.com/kijai/ComfyUI-segment-anything-2
**定位**: SAM2 分割基座,提供单帧分割、全自动分割、视频追踪三大能力。
### 1.1 (Down)Load SAM2Model
| 属性 | 说明 |
|:---|:---|
| **功能** | 从本地加载或自动下载 SAM2 模型权重 |
| **关键参数** | `model`: 如 `sam2.1_hiera_base_plus.safetensors``segmentor`: 单图/视频模式;`device`: cuda/cpu`precision`: fp16/bf16/fp32 |
| **输出** | `sam2_model`(公共模型对象,供下游所有 SAM2 节点复用) |
### 1.2 Sam2Segmentation
| 属性 | 说明 |
|:---|:---|
| **功能** | 标准单帧分割器,支持点/框/mask 多种提示方式 |
| **输入** | `image`, `sam2_model`, `coordinates_positive`, `coordinates_negative`, `bboxes`, `mask` |
| **参数** | `keep_model_loaded`, `individual_objects` |
| **输出** | `mask` |
| **提示方式优先级** | 手绘 Mask最直观> 点坐标 > 检测框 |
### 1.3 Sam2AutoSegmentation
| 属性 | 说明 |
|:---|:---|
| **功能** | "分割一切"模式,无需手动提示,全图自动布点识别所有物体 |
| **关键参数** | `points_per_side`(网格密度,默认 32`pred_iou_thresh`IOU 过滤阈值);`stability_score_thresh`(稳定性阈值,默认 0.95 |
| **医疗场景调优** | 低对比度图像(如手术视频)建议将 `stability_score_thresh` 降至 **0.85~0.90**,并将 `points_per_side` 提高至 **32 或 64**,避免"角落碎块"现象 |
| **输出** | `mask`, `segmented_image`, `bbox` |
### 1.4 Sam2VideoSegmentationAddPoints
| 属性 | 说明 |
|:---|:---|
| **功能** | 视频工作流的"交互站",在特定帧注入点标注,生成/更新视频推理状态 |
| **输入** | `sam2_model`, `image`(视频批次), `coordinates_positive`, `coordinates_negative`, `prev_inference_state` |
| **参数** | `frame_index`(标注帧号);`object_index`(单目标默认 0 |
| **输出** | `sam2_model`, `inference_state` |
| **核心机制** | 通过 `prev_inference_state` 支持**链式追加多帧标注**,是实现人工纠正的关键 |
### 1.5 Sam2VideoSegmentation
| 属性 | 说明 |
|:---|:---|
| **功能** | 视频推理核心引擎,接收带标注的 `inference_state`,执行跨帧自动追踪 |
| **输入** | `sam2_model`, `inference_state` |
| **参数** | `keep_model_loaded`(推荐开启,避免重复加载) |
| **输出** | `mask`(完整视频的分割结果批次) |
### 1.6 Florence2 Coordinates
| 属性 | 说明 |
|:---|:---|
| **功能** | 桥接节点,将 Florence-2 视觉模型的检测输出转换为 SAM2 可识别的坐标格式 |
| **输入** | `data`Florence-2 输出) |
| **参数** | `index`, `batch` |
| **输出** | `center_coordinates`, `boxes` |
| **用途** | 实现"文字搜图并抠图"的全自动语义流程 |
---
## 2. ComfyUI-VideoHelperSuite
**作者**: kosinkadink
**仓库**: https://github.com/kosinkadink/ComfyUI-VideoHelperSuite
**定位**: 视频工作流的核心 I/O 与批处理工具。
### 2.1 I/O 节点
| 节点 | 功能 | 关键参数 |
|:---|:---|:---|
| **Load Video (Upload)** | 将视频文件转换为图像批次 | `force_rate`(强制帧率), `force_size`(强制尺寸), `frame_load_cap`(最大加载帧数), `skip_first_frames`(跳过前 N 帧), `select_every_nth`(抽帧) |
| **Load Video (Path)** | 同上,但通过文件路径读取 | 同上 |
| **Load Image Sequence** | 从子文件夹加载所有图像文件 | `image_load_cap`, `skip_first_images`, `select_every_nth` |
| **Video Combine** | 将图像批次合成为输出视频,支持音频合并 | `frame_rate`, `loop_count`, `filename_prefix`, `format`, `pingpong`, `save_output`, `crf`, `save_metadata`, `pix_fmt` |
| **Load Audio** | 加载独立音频文件 | `seek_seconds`(起始时间) |
### 2.2 Latent / Image 批处理节点
| 节点 | 功能 |
|:---|:---|
| **Split Batch** | 将批次拆分为 A、B 两组(按 `split_index` 分界) |
| **Merge Batch** | 合并两组批次A 在前B 在后),支持尺寸不一致时缩放 |
| **Select Every Nth** | 每 `select_every_nth` 个保留 1 个,其余丢弃 |
| **Get Count** | 获取批次数量 |
| **Duplicate Batch** | 复制批次 |
### 2.3 视频预览与格式
| 功能 | 说明 |
|:---|:---|
| **Animated Previews** | Load Video / Video Combine 等节点提供动画预览,支持 Open / Save / Pause / Hide / Sync |
| **Advanced Previews** | 需手动开启。通过 ffmpeg 实时转码预览,可反映 skip/resize 等参数设置,减少远程带宽占用,支持浏览器无法直接播放的格式 |
| **Video Formats** | 支持通过自定义 JSON 文件添加 ffmpeg 输出格式(如 AV1-WebM可暴露 `crf``pix_fmt` 等参数为 UI 控件 |
---
## 3. ComfyUI-Impact-Pack
**作者**: ltdrdata
**仓库**: https://github.com/ltdrdata/ComfyUI-Impact-Pack
**定位**: 图像增强的超级工具箱,涵盖检测、分割、细节修复、放大、管道、区域采样等。
### 3.1 Detector 节点(检测器)
| 节点 | 功能 |
|:---|:---|
| **SAMLoader (Impact)** | 加载 SAM 模型(支持 SAM2 |
| **ONNXDetectorProvider** | 加载 ONNX 模型,提供 BBOX_DETECTOR |
| **CLIPSegDetectorProvider** | CLIPSeg 包装器,提供 BBOX_DETECTOR |
| **SEGM Detector (combined)** | 分割检测,返回统一 mask |
| **BBOX Detector (combined)** | 边界框检测,返回 mask |
| **SAMDetector (combined)** | SAM 技术提取指定 SEGS 位置的 segment输出统一 mask |
| **SAMDetector (Segmented)** | 同上,但分离输出多个 mask`combined_mask` + `batch_masks` |
| **Simple Detector (SEGS)** | 综合 BBOX + SAM/SEGM 的便捷检测工具 |
| **Simple Detector for Video (SEGS)** | 对视频逐帧检测,生成带批次 mask 的 SEGS |
| **SAM2 Video Detector (SEGS)** | 利用 SAM2 视频追踪技术生成 SEGS需 SAMLoader 选择 SAM2 模型) |
### 3.2 ControlNet / IPAdapter (SEGS)
| 节点 | 功能 |
|:---|:---|
| **ControlNetApply (SEGS)** | 在 SEGS 中应用 ControlNet支持 `segs_preprocessor``control_image` |
| **ControlNetClear (SEGS)** | 清除 SEGS 中已应用的 ControlNet |
| **IPAdapterApply (SEGS)** | 在 SEGS 中应用 IPAdapter |
### 3.3 Mask 操作
| 节点 | 功能 |
| :---------------------------------- | :-------------------- |
| **Pixelwise(SEGS & SEGS)** | 两个 SEGS 像素级与运算 |
| **Pixelwise(SEGS - SEGS)** | SEGS 相减 |
| **Pixelwise(SEGS & MASK)** | SEGS 与 MASK 像素级与运算 |
| **Pixelwise(SEGS & MASKS ForEach)** | SEGS 与 MASK 批次的逐元素与运算 |
| **Pixelwise(MASK & MASK)** | Mask 与运算 |
| **Pixelwise(MASK - MASK)** | Mask 相减 |
| **Pixelwise(MASK + MASK)** | Mask 合并 |
| **Dilate Mask** | Mask 膨胀/腐蚀(负值支持腐蚀) |
| **Gaussian Blur Mask** | Mask 高斯模糊(可用于羽化边缘) |
| **Mask Rect Area** | 通过百分比定义矩形 Mask带预览画布 |
| **Mask Rect Area (Advanced)** | 通过像素值定义矩形 Mask |
### 3.4 Detailer 节点(细节修复)
| 节点 | 功能 |
|:---|:---|
| **Detailer (SEGS)** | 基于 SEGS 对图像进行细节修复/重绘 |
| **Detailer (SEGS) with auto retry** | 同上,若 patch 全黑则自动重试 |
| **DetailerDebug (SEGS)** | 带调试输出,可监控裁剪图与修复后的裁剪图 |
| **FaceDetailer** | 自动检测人脸并进行增强 |
| **FaceDetailer (pipe)** | FaceDetailer 的管道版(支持多轮处理) |
| **MaskDetailer (pipe)** | 对 Mask 区域进行 Detailer 修复的简单 inpaint 节点 |
| **MaskPainter** | 提供 Mask 绘制功能 |
| **ToBinaryMask** | 将含 Alpha 的 mask 二值化为 0/255 |
| **MASK to SEGS** | 将 Mask 转换为 SEGS |
| **MASK to SEGS For Video** | 视频版 Mask 转 SEGSAnimateDiff 兼容) |
| **MediaPipe FaceMesh to SEGS** | 将 MediaPipe FaceMesh 关键点分离为带标签的 SEGS |
### 3.5 SEGS 操作与处理
| 节点 | 功能 |
|:---|:---|
| **SEGSDetailer** | 对 SEGS 进行细节修复(不贴回原图) |
| **SEGSPaste** | 将 SEGS 结果贴回原图(支持 `ref_image_opt` 替换) |
| **SEGSPreview** | 预览 SEGS 内容(可配合 `fallback_image_opt` |
| **SEGSPreview (CNET Image)** | 预览 ControlNetApply (SEGS) 配置的图像 |
| **SEGSToImageList** | SEGS 转 Image List |
| **SEGSToMaskList** | SEGS 转 Mask List |
| **SEGS Filter (label)** | 按标签过滤 SEGS |
| **SEGS Filter (ordered)** | 按大小和位置排序后取范围 |
| **SEGS Filter (range)** | 按大小和位置范围过滤 |
| **SEGS Filter (non max suppression)** | NMS 去重(按 IoU 阈值) |
| **SEGS Filter (intersection)** | 按 IoA 阈值排除与另一组 SEGS 显著重叠的部分 |
| **SEGS Assign (label)** | 为 SEGS 顺序分配标签 |
| **SEGSConcat** | 拼接两组 SEGS |
| **SEGS Merge** | 将多个 SEG 合并为单个 SEG |
| **Picker (SEGS)** | 对话框手动选择特定 SEG |
| **Set Default Image For SEGS** | 为 SEGS 设置默认图像 |
| **Remove Image from SEGS** | 移除 SEGS 中的图像设置 |
| **Make Tile SEGS** | 将图像切分为瓦片形式的 SEGS用于 Tiled Upscale 实验) |
| **Dilate Mask (SEGS)** | 对 SEGS 内的 Mask 进行膨胀/腐蚀 |
| **Gaussian Blur Mask (SEGS)** | 对 SEGS 内的 Mask 进行高斯模糊 |
| **SEGS_ELT Manipulation** | 实验性节点DecomposeSEGS / AssembleSEGS / Edit SEG_ELT / Dilate SEG_ELT 等 |
| **Count Elt in SEGS** | 统计 SEGS 中的元素数量 |
### 3.6 Pipe 节点(管道封装)
| 节点 | 功能 |
|:---|:---|
| **ToDetailerPipe / FromDetailerPipe** | 将 Detailer 所需的多输入打包为 DETAILER_PIPE或解包 |
| **ToBasicPipe / FromBasicPipe** | 将 model/clip/vae/conditioning 打包为 BASIC_PIPE或解包 |
| **EditBasicPipe / EditDetailerPipe** | 替换 Pipe 中的部分元素 |
| **FromDetailerPipe_v2 / FromBasicPipe_v2** | 额外输出原始 Pipe便于链式编辑 |
| **Latent Scale (on Pixel Space)** | 潜空间→像素空间→放大→潜空间 |
| **PixelKSampleUpscalerProvider** | 基于 K-Sampling 的放大器Latent↔Pixel 转换) |
| **PixelTiledKSampleUpscalerProvider** | tiled 版本,避免高分辨率爆显存 |
| **Any PIPE -> BasicPipe** | 将其他套件的兼容 PIPE 转为 BASIC_PIPE |
### 3.7 PK_HOOK迭代放大钩子
| 节点 | 功能 |
|:---|:---|
| **DenoiseScheduleHookProvider** | 迭代过程中逐步调整 denoise |
| **CfgScheduleHookProvider** | 迭代过程中逐步调整 CFG |
| **StepsScheduleHookProvider** | 迭代过程中逐步调整采样步数 |
| **NoiseInjectionHookProvider** | 按 schedule 注入噪声 |
| **UnsamplerHookProvider** | 每轮迭代应用 Unsampler |
| **PixelKSampleHookCombine** | 串联两个 PK_HOOK |
### 3.8 DETAILER_HOOK细节修复钩子
| 节点 | 功能 |
|:---|:---|
| **NoiseInjectionDetailerHookProvider** | 每个 SEGS 处理时注入噪声 |
| **UnsamplerDetailerHookProvider** | 每个循环应用 Unsampler |
| **DenoiseSchedulerDetailerHookProvider** | 循环过程中调整 detailer denoise |
| **CoreMLDetailerHookProvider** | 固定裁剪区域为 CoreML 支持的尺寸 |
| **DetailerHookCombine** | 串联两个 DETAILER_HOOK |
| **SEGSOrderedFilterDetailerHook / SEGSRangeFilterDetailerHook / SEGSLabelFilterDetailerHook** | 将 SEGSFilter 包装为 DETAILER_HOOK |
| **PreviewDetailerHook** | 每个 SEGS 修复完成后提供预览 |
| **VariationNoiseDetailerHookProvider** | 应用 variation seed |
| **CustomSamplerDetailerHookProvider** | 使用自定义采样器 |
| **LamaRemoverDetailerHookProvider** | 在细节修复阶段应用 Lama Remover 去除区域 |
### 3.9 Iterative Upscale迭代放大
| 节点 | 功能 |
|:---|:---|
| **Iterative Upscale (Latent/on Pixel Space)** | 将放大因子拆分为多步,迭代执行潜空间放大 |
| **Iterative Upscale (Image)** | 图像输入版本的迭代放大 |
### 3.10 TwoSamplers双采样器
| 节点 | 功能 |
|:---|:---|
| **TwoSamplersForMask** | mask=0 区域用 base_samplermask=1 区域用 mask_sampler |
| **TwoAdvancedSamplersForMask** | 每步交替在 base 和 mask 区域采样 |
| **KSamplerProvider / KSamplerAdvancedProvider** | KSampler 包装器,用于 TwoSamplers |
| **TiledKSamplerProvider** | Tiled KSampler 包装器 |
| **TwoSamplersForMaskUpscalerProvider** | 将 TwoSamplersForMask 扩展为 Upscaler |
### 3.11 Image Utils
| 节点 | 功能 |
|:---|:---|
| **PreviewBridge (image)** | 配合 Clipspace MaskEditor 的图像桥接节点 |
| **PreviewBridge (latent)** | 配合 Clipspace MaskEditor 的 Latent 桥接节点(支持 mask 读写) |
| **ImageSender / ImageReceiver** | 同 `link_id` 的图像自动收发 |
| **LatentSender / LatentReceiver** | 同 `link_id` 的 Latent 自动收发LatentSender 内含 PreviewLatent |
### 3.12 Switch 节点
| 节点 | 功能 |
|:---|:---|
| **Switch (image,mask) / Switch (latent) / Switch (SEGS)** | 按 selector 选择指定输入输出 |
| **Switch (Any)** | 任意类型输入的通用 Switch |
| **Inversed Switch (Any)** | 单输入多输出的反向 Switch |
### 3.13 Wildcards动态提示词
| 节点 | 功能 |
|:---|:---|
| **ImpactWildcardProcessor** | 处理 `__wildcard-name__``{a\|b\|c}` 动态语法,支持 populate/fixed 模式 |
| **ImpactWildcardEncode** | 同上,额外支持 LoRA 加载(如 `<lora:...>`)和 LBW 语法 |
### 3.14 Regional Sampling区域采样
| 节点 | 功能 |
|:---|:---|
| **RegionalPrompt** | 将 mask 与采样器绑定为 REGIONAL_PROMPTS |
| **CombineRegionalPrompts** | 合并多个 REGIONAL_PROMPTS |
| **RegionalSampler** | 基础采样器 + 区域提示分步采样(支持 overlap_factor 混合) |
| **RegionalSamplerAdvanced** | 高级版,支持按 step 控制 |
### 3.15 Impact KSampler
| 节点 | 功能 |
|:---|:---|
| **KSampler (pipe)** | pipe 版 KSampler |
| **KSampler (advanced/pipe)** | pipe 版 KSamplerAdvanced |
| **GITSScheduler Func Provider** | 为 GITSScheduler 提供调度函数 |
| **Impact Scheduler Adapter** | 解决 scheduler widget 转 input 后的兼容问题 |
### 3.16 Batch / List 工具
| 节点 | 功能 |
|:---|:---|
| **Image Batch to Image List / Image List to Image Batch** | 图像批次与列表互转 |
| **Make Image List / Make Image Batch** | 多图像合成列表/批次 |
| **Masks to Mask List / Mask List to Masks / Make Mask List / Make Mask Batch** | Mask 版本同上 |
| **Flatten Mask Batch** | 将 Mask 批次压平为单个 Mask |
| **Make List (Any)** | 创建任意值列表 |
| **Select Nth Item (Any list)** | 选择列表第 N 项(越界返回最后一项) |
### 3.17 Logics实验性逻辑控制
| 节点 | 功能 |
|:---|:---|
| **ImpactCompare / ImpactConditionalBranch / ImpactConditionalBranchSelMode** | 条件分支 |
| **ImpactInt / ImpactBoolean / ImpactMinMax / ImpactNeg** | 基础运算 |
| **ImpactValueSender / ImpactValueReceiver** | 值收发 |
| **ImpactImageInfo** | 获取图像信息 |
| **ImpactIsNotEmptySEGS / ImpactIfNone** | 空值/None 判断 |
| **Queue Trigger / Queue Trigger (Countdown)** | 自动插入队列(循环辅助) |
| **Sleep** | 等待指定秒数 |
| **Set Widget Value** | 设置指定节点的 widget 值 |
| **Set Mute State** | 设置指定节点的 mute 状态 |
| **Control Bridge** | 根据 mode/behavior 修改控制节点状态并插入新队列 |
| **Remote Boolean / Remote Int (on prompt)** | 在 prompt 开始时强制设置指定 node_id 的 widget 值 |
### 3.18 HuggingFace 节点
| 节点 | 功能 |
|:---|:---|
| **HF Transformers Classifier Provider** | 加载 HuggingFace transformers 分类模型 |
| **SEGS Classify** | 利用分类器对 SEGS 进行分类过滤(支持 `label > number` 表达式) |
### 3.19 其他节点
| 节点 | 功能 |
|:---|:---|
| **Impact Scheduler Adapter** | scheduler 间接连接适配器 |
| **StringListToString** | 字符串列表转字符串 |
| **WildcardPromptFromString** | 从字符串创建带标签的 wildcard配合 MakeTileSEGS |
| **String Selector** | 选择字符串的某部分(支持 `#` 分隔的多行模式) |
| **Combine Conditionings / Concat Conditionings** | Conditioning 合并/拼接 |
| **Negative Cond Placeholder** | FLUX.1 等无 Negative Conditioning 模型的占位符 |
| **Execution Order Controller** | 强制控制节点执行顺序 |
| **List Bridge** | 确保列表数据在转发前已收集完成 |
### 3.20 交互式功能(非节点)
| 功能 | 说明 |
| :--------------------------------------- | :------------------------------------------------------------------------------------- |
| **Interactive SAM Detector (Clipspace)** | 右键含 MASK 和 IMAGE 输出的节点 → `Open in SAM Detector``Impact SAM Detector`,交互式生成 SAM Mask |
| **模型混用检测** | 自动检测并报告 SDXL Base/Refiner/SD1.x/SD2.x 模型与 clip 混用错误 |
---
## 4. rgthree-comfy
**作者**: rgthree
**仓库**: https://github.com/rgthree/rgthree-comfy
**定位**: 让 ComfyUI 更舒适的综合优化包,提供大量实用节点和全局体验改进。
### 4.1 核心节点
| 节点 | 功能 | 亮点 |
|:---|:---|:---|
| **Seed** | 直观的种子控制(类似 A1111 | 支持 -1 随机、固定值、-2/-3 递增递减;图像元数据可存储种子 |
| **Reroute** | 改进版路由节点 | 支持多方向、多尺寸、可调整宽高和连接布局 |
| **Bookmark (🔖)** | 画布书签导航 | 按快捷键瞬间跳转到指定位置,支持自定义 zoom 级别和多键组合 |
| **Context / Context Big** | 通用数据流管道 | 将 model/clip/vae/conditioning/image 等打包传递Context 与 Context Big 互相兼容;支持 Ctrl+拖拽自动连接 |
| **Image Comparer** | 图像对比 | 两张图叠加对比,支持 Slide滑动和 Click点击模式 |
| **Image Inset Crop** | 图像内嵌裁剪 | 支持按像素值或百分比裁剪 |
| **Display Any** | 后端文本数据显示 | 执行后显示几乎所有文本数据 |
| **Power Lora Loader** | 多 LoRA 批量加载 | 一键添加多个 LoRA支持独立开关、强度调节、快速排序/删除 |
| **Power Prompt** | 增强提示词输入 | 下拉菜单选择 embeddings/LoRA支持保存提示片段连接 MODEL 可自动解析 `<lora:...>` 标签 |
| **Power Prompt - Simple** | Power Prompt 去 LoRA 版 | 用于 negative prompt |
| **SDXL Power Prompt - Positive / Simple** | SDXL 专用版 | 分离 text_g / text_l 输入 |
| **SDXL Config** | SDXL 参数配置 | 也可用于非 SDXL |
| **Context Switch / Context Switch Big** | 分支选择 | 自动选择第一个非空的 Context 输入,配合 Muter 实现零浪费分支 |
| **Any Switch** | 通用分支选择 | 对任意类型选择第一个非空输入 |
| **Power Primitive** | 原语转换输出 | 输出 STRING/INT/FLOAT/BOOLEAN支持输入类型自动转换 |
| **Power Puter** | 多功能代码解析器 | 多行代码解析输出,支持简单运算(`a + b`)、图像维度提取(`a.shape[2]`)、甚至访问 prompt 中的其他节点数据 |
### 4.2 Mute / Bypass 控制节点
| 节点 | 功能 |
|:---|:---|
| **Fast Muter** | 快速静音面板,一键 toggle 所有连接的节点Mute 模式) |
| **Fast Bypasser** | 同上,但执行 Bypass 而非 Mute |
| **Fast Groups Muter** | 自动收集当前工作流所有 Group一键 Mute/Enable 整个组 |
| **Fast Groups Bypasser** | 同上,但执行 Bypass |
| **Fast Actions Button** | 半自动化按钮,点击时执行预设动作(如 Seed 随机化、使用上次种子);支持快捷键触发 |
| **Node Collector** | 清理 noodle接受任意输入节点并转发建议只连到 Fast Muter/Bypasser |
| **Mute / Bypass Repeater** | 将其 Mute/Bypass/Active 状态分发给所有连接的输入节点(或同组内所有节点) |
| **Mute / Bypass Relay** | 与 Repeater 配合,监听输入节点的状态变化并中继给 Repeater |
| **Random Unmuter** | 队列执行时随机取消静音一个输入(并立即静音回去),用于抽卡分支 |
### 4.3 其他节点
| 节点 | 功能 |
|:---|:---|
| **Label** | 纯视觉浮动标签,支持自定义字体、颜色、背景、角度、透明度;支持 Pin 固定 |
### 4.4 全局改进与功能(非节点)
| 功能 | 说明 |
|:---|:---|
| **Progress Bar** | 顶部极简进度条,显示队列大小、当前执行进度、多步骤节点进度 |
| **Queue Selected Output Nodes** | 右键输出节点 → 仅执行选中输出节点路径,跳过工作流其余部分 |
| **Auto-Nest Subdirectories** | 长 combo 列表(如 Load Checkpoint自动按顶层子目录折叠分组 |
| **Quick Mute/Bypass in Group Headers** | 组标题右上角显示 Mute/Bypass 图标,一键 toggle |
| **Import Individual Node Widgets (Drag & Drop)** | 拖拽历史图像/JSON 时,仅覆盖同 ID 同类型节点的 widgets如只导入 seed 或 prompt |
| **Copy Image** | 右键节点图像 → 复制到剪贴板 |
| **Link Fixer** | 访问 `/rgthree/link_fixer` 检查并修复工作流中的断链;加载工作流时自动检测并控制台报告 |
---
## 5. ComfyUI-KJNodes
**作者**: kijai
**仓库**: https://github.com/kijai/ComfyUI-KJNodes
**定位**: 实用工具、模型优化和体验增强的杂项集合,依赖极少。
### 5.1 Set / Get 节点系统(核心)
KJNodes 的 Set/Get 是 ComfyUI 中替代长 noodle 的经典方案,现已全面升级为 Nodes 2.0 架构。
| 功能 | 说明 |
|:---|:---|
| **SetNode / GetNode** | 将任意类型的数据流虚拟化Set 节点接收输入并命名Get 节点通过同名引用远程获取数据 |
| **子图支持 (Subgraph)** | Set 节点在父图中可见于所有子图Get 节点会向上遍历祖先图查找匹配的 Set |
| **Convert link to Set/Get** | 右键任意连线中点 → 转换为 Set/Get 对 |
| **Convert to links** | 右键 Set/Get 节点 → 恢复为直接连线 |
| **Convert outputs to Set/Get** | 批量将选中节点的所有输出转为 Set/Get 对(画布右键菜单或 Ctrl+Shift+S/G |
| **快捷键** | Ctrl+Shift+S添加 Set、Ctrl+Shift+G添加 Get、Ctrl+Shift+L强制显示所有虚拟连线 |
| **Shift+Middle-click** | Shift+中键点击输出槽创建 SetNode点击输入槽创建 GetNode |
| **Add paired GetNode** | 右键 SetNode → 自动添加同名配对的 GetNode |
| **Double-click Get to jump** | 双击 GetNode 自动居中并选中其对应的 SetNode |
| **Show links setting** | never / selected / always 控制虚拟连线显示时机 |
| **Type inference** | Set 节点输入未连接但输出已连接时,自动推断并采用目标类型和颜色 |
| **Paste rename coordination** | 粘贴 Set+Get 对时Get 自动跟随 Set 的重命名 |
### 5.2 其他实用节点
根据仓库描述KJNodes 还包含各类零散的实用工具节点,文档主要在节点描述和 tooltip 中。已知功能包括模型优化相关节点和各类 QoLQuality of Life辅助节点。
---
## 6. cg-use-everywhere (CG Use Everywhere / UE Nodes)
**作者**: chrisgoringe
**仓库**: https://github.com/chrisgoringe/cg-use-everywhere
**定位**: 无线数据广播系统。通过类型自动匹配将数据发送到所有需要它的节点,彻底消除长 noodle。
### 6.1 核心节点
| 节点 | 功能 | 亮点 |
|:---|:---|:---|
| **Anything Everywhere** | 接收一个或多个输入,自动广播到工作流中所有同类型的**未连接、非 widget 输入** | 复杂工作流中可将 MODEL/CLIP/VAE/CONDITIONING 一键分发到所有需要的地方 |
| **Prompts Everywhere** | 专门处理 positive / negative prompt 的双输入广播 | 内置 regex 自动匹配 `prompt/positive``neg/negative`,无需手动命名 |
| **Combo Clone** | 复制指定 widget 的选项列表和名称,用于广播 COMBO下拉菜单类型 | 解决 COMBO 类型无法直接连线的问题 |
### 6.2 Any Node Broadcasting任意节点广播
自 v7.4 起,**任意节点**均可通过右键菜单 `Add UE broadcasting` 开启广播模式。开启后,该节点的所有输出等效于连到了一个隐藏的 `Anything Everywhere` 节点。
- 从 v7.5 起,可精细控制**哪些输出参与广播**per-output granularity
- 广播节点左上角会显示圆圈标识
### 6.3 数据发送控制Restrictions
双击节点 body 或右键菜单可打开限制面板,控制数据只发送到指定位置:
| 限制类型 | 说明 |
|:---|:---|
| **Node title regex** | 正则匹配接收节点的标题 |
| **Input name regex** | 正则匹配接收输入槽的名称 |
| **Group name regex** | 正则匹配接收节点所在组的名称 |
| **Group** | 仅发送到同一组(或不同组)内的节点 |
| **Colour** | 仅发送到同色(或异色)节点 |
| **Repeated Types** | 当多个同类型输入连到 UE 节点时,通过输入槽名称匹配(`match start` / `match end` / `regex match`)来消歧 |
| **Priority** | 手动设置优先级,解决多广播源冲突 |
| **Send To Any** | 允许向 `Any` 类型输入发送数据 |
### 6.4 接收端控制
- **右键节点 → `UE Connectable Inputs`**:绿色条表示该输入可接收 UE 数据
- **`Reject UE links`**:强制拒绝所有 UE 连接
- **Widget 灰显**:当 widget 正通过 UE 接收数据时,该 widget 会变灰(不可编辑)
### 6.5 冲突解决与可视化
| 视觉标识 | 含义 |
|:---|:---|
| 🟢 绿色圆圈 | 广播节点,无额外限制 |
| 🟡 黄色圆圈 | 广播节点,有限制条件 |
| **粗体** 圆圈 | 当前正在发送数据 |
| 黑色光环 + glow | 输入槽可接收 UE 连接 |
| ❌ 红色叉号 | 两个同优先级广播源冲突,该输入未连接 |
| 红色虚拟连线 | 冲突时的候选连接可视化 |
- **画布右键** → 开关 UE 虚拟连线显示
- **Settings** → 控制连线动画形式(移动点 / 脉冲 glow / 两者)
### 6.6 与 KJNodes Set/Get 的对比
| 特性 | KJNodes Set/Get | CG Use Everywhere |
|:---|:---|:---|
| **连接方式** | 命名匹配Set → Get 同名) | 类型自动匹配 + 可选限制 |
| **设置成本** | 需手动创建 Set 和 Get 节点 | 一个节点广播全部 |
| **控制粒度** | 精确到具体连接 | 通过 regex/组/颜色批量控制 |
| **子图支持** | 原生支持子图边界穿透 | 支持子图内广播 |
| **最佳场景** | 需要精确知道数据流向时 | 快速简化复杂工作流(如 MODEL/CLIP/VAE 分发) |
---
## 7. 跨插件协作速查表
| 常见任务 | 推荐节点组合 |
|:---|:---|
| **视频加载 + 抽帧** | VideoHelperSuite `Load Video``Select Every Nth` |
| **第一帧交互式分割** | VideoHelperSuite `Select Images` → SAM2 `Sam2Segmentation`(手绘 mask 或坐标) |
| **全自动分割一切** | SAM2 `Sam2AutoSegmentation` |
| **视频追踪** | SAM2 `Sam2VideoSegmentationAddPoints``Sam2VideoSegmentation` |
| **中途纠正追踪漂移** | 第二个 `Sam2VideoSegmentationAddPoints``prev_inference_state` 链式接入)+ rgthree `Fast Muter` 控制 |
| **检测人脸并增强** | Impact `FaceDetailer` |
| **按 Mask 分区重绘** | Impact `TwoSamplersForMask``RegionalSampler` |
| **多 LoRA 快速切换** | rgthree `Power Lora Loader` + `Fast Muter` |
| **图像对比验收** | rgthree `Image Comparer` |
| **长 noodle 整理** | KJNodes `Set/Get`、rgthree `Context` / `Reroute` 或 cg-use-everywhere `Anything Everywhere` |
| **仅执行部分分支** | rgthree `Queue Selected Output Nodes``Context Switch` + `Fast Muter` |
| **按标签过滤 SEGS** | Impact `SEGS Filter (label)` |
| **批量检测 + 分类** | Impact `Simple Detector (SEGS)``HF Transformers Classifier``SEGS Classify` |
| **视频合成输出** | VideoHelperSuite `Video Combine` |
---
> **使用提示**ComfyUI-Impact-Pack 的许多节点使用通配类型wildcard type实现任意输入/输出连接。在 ComfyUI 官方正式支持动态类型之前,虽然功能正常,但类型校验可能会产生误报的错误信息,可安全忽略。

View File

@@ -1,121 +0,0 @@
---
title: "视频笔记ComfyUI Segment Anything V2 Easy Tutorial"
date: 2026-04-24
tags:
- comfyUI
- SAM2
- 视频分割
- 教程笔记
source:
platform: YouTube
url: https://www.youtube.com/watch?v=Zx9AQMA9zbI
channel: Tutorials View
duration: "8:23"
---
# 视频笔记ComfyUI Segment Anything V2 Easy Tutorial
## 视频基本信息
| 项目 | 内容 |
|:---|:---|
| **标题** | ComfyUI Segment Anything V2 Easy Tutorial Video Image Segment |
| **频道** | [Tutorials View](https://www.youtube.com/channel/UCneOmV-ve3Tm9Fn52e9bRnQ) |
| **链接** | https://www.youtube.com/watch?v=Zx9AQMA9zbI |
| **时长** | 8 分 23 秒 |
| **语言** | 英语 / 韩语(双语字幕) |
| **工作流下载** | YouTube 频道会员专属 |
## 视频核心主题
> "AI recognizes movement and automatically separates the desired area without a separate tracking process."
本视频演示如何使用 **ComfyUI + Segment Anything 2 (SAM2)** 实现:
1. **图像分割** — 单帧交互式分割(点/框标注)
2. **视频分割** — AI 自动识别运动并追踪目标,**无需传统手动追踪流程**
3. **工作流特点** — 简单、免费、适合初学者
## 涉及工具与插件
视频描述中明确列出的依赖:
| 工具/插件 | 用途 | 仓库 |
|:---|:---|:---|
| **ComfyUI** | 核心运行平台 | https://github.com/comfyanonymous/ComfyUI |
| **ComfyUI-Manager** | 插件管理器 | https://github.com/ltdrdata/ComfyUI-Manager |
| **ComfyUI-Segment Anything-2** | SAM2 分割模型 | https://github.com/facebookresearch/segment-anything-2 |
| **ComfyUI-Cg-use-everywhere** | 无线数据广播(简化连线) | https://github.com/chrisgoringe/cg-use-everywhere |
> **注意**:视频描述中的 SAM2 链接指向了 Meta 官方仓库。在实际 ComfyUI 使用中,通常需要安装封装好的节点包(如 `ComfyUI-segment-anything-2` by kijai才能在 ComfyUI 中调用 SAM2。
## 工作流程推断(基于主题与已知节点)
由于无法直接观看视频画面,以下是根据视频标题、描述及 SAM2 通用工作流推断的核心步骤:
### Step 1环境准备
- 通过 **ComfyUI-Manager** 安装所需节点包
- 下载 SAM2 模型权重(`sam2_hiera_base_plus.pt``sam2.1_hiera_base_plus.safetensors`
### Step 2单帧分割第一帧标注
- 加载图像或视频的第一帧
- 使用 **点标注****框标注** 指定目标区域
- SAM2 生成分割 Mask
### Step 3视频追踪核心卖点
- SAM2 的 **视频追踪能力** 自动将第一帧的分割结果传播到整个视频
- **无需手动逐帧追踪** — AI 通过运动识别自动跟踪目标对象的形变和移动
- 这是 SAM2 相比传统 rotoscoping / 逐帧蒙版工作的革命性优势
### Step 4输出与合成
- 输出每帧的分割 Mask 序列
- 合成带透明通道的抠像结果
- 可进一步用于背景替换、特效合成等
## 与系统设计的对应关系
本视频演示的内容与我们 [[自动语义分割系统/系统设计.md]] 中规划的架构高度一致:
| 视频演示 | 系统设计文档 |
|:---|:---|
| 单帧交互分割(点/框标注) | 第 1 章:单帧交互分割 |
| AI 自动运动追踪 | 第 2 章:视频前后追踪分割 |
| 简单工作流 | 第 4 章ComfyUI 节点拓扑 |
| 无需手动追踪 | 第 6 章SAM2 视频追踪原理 |
## 关键节点对应(推测)
基于 `ComfyUI-segment-anything-2` 节点包,视频中可能使用的节点:
```
[Load Video] ──→ [Sam2VideoSegmentationAddPoints] ──→ [Sam2VideoSegmentation] ──→ [Preview/Save]
│ ↑
│ [(Down)Load SAM2Model]
│ ↑
│ [coordinates_positive](点标注)
└──→ [Sam2Segmentation](单帧预览测试,可选)
```
## 学习要点
1. **SAM2 的核心优势**:不只是单图分割,而是**时序一致性追踪**。传统方法需要手动追踪每一帧SAM2 通过记忆机制自动传播。
2. **零成本追踪**:无需购买 After Effects、Nuke 等商业软件的追踪插件。
3. **工作流简洁**ComfyUI 的节点化设计使得整个流程可视化、可复用。
## 建议后续操作
1. **安装插件**:通过 ComfyUI Manager 搜索并安装 `ComfyUI-segment-anything-2`
2. **下载模型**:将 SAM2 模型放入 `ComfyUI/models/sam2/` 目录
3. **复现工作流**:参考本视频的工作流结构,结合我们的 [[自动语义分割系统/安装步骤.md]] 搭建自己的分割管线
4. **对比测试**:尝试同一视频分别用 SAM2 自动追踪 vs 手动逐帧 Mask评估时间节省和质量差异
## 相关文档
- [[自动语义分割系统/系统设计.md]]
- [[自动语义分割系统/安装步骤.md]]
- [[自动语义分割系统/ComfyUI 搭建操作指南.md]]
- [[自动语义分割系统/插件功能大全.md]]
---
> **免责声明**:本笔记基于视频公开元数据(标题、描述)及 SAM2 通用知识推断整理。如需精确复现视频中的工作流,建议直接观看原视频或加入频道会员获取官方工作流文件。

View File

@@ -1,496 +0,0 @@
---
title: ComfyUI 视频语义分割系统设计
date: 2026-04-22
tags:
- comfyUI
- SAM2
- 视频分割
- 语义分割
- 系统设计
---
# ComfyUI 视频语义分割系统设计
## 1. 设计目标
通过对视频单帧进行交互式语义分割(点/框/文本提示),利用视频追踪能力将分割结果传播到整个视频序列,并支持人工修正与迭代优化,最终实现对完整视频的自动化语义分割。
## 2. 核心功能
| 功能模块 | 说明 |
|---------|------|
| 单帧交互分割 | 支持点标注(正/负)、框标注、语义文本提示 |
| 双向视频追踪 | 以关键帧为锚点,向前/向后追踪目标对象 |
| 人工修正回环 | 对追踪过程中的错误帧进行人工修正,重新触发追踪 |
| 批量输出 | 输出每帧分割掩码Mask Sequence及合成视频 |
## 3. 技术架构
```mermaid
flowchart TB
subgraph Input["输入层"]
V[视频文件]
FP[第一帧 / 关键帧]
SP[语义提示词]
end
subgraph Interaction["交互分割层"]
P[点标注: 正选/反选]
B[框标注]
T[语义提示: Grounding DINO / CLIP]
SAM2_IMG[SAM2 Image Encoder + Decoder]
end
subgraph Tracking["视频追踪层"]
SAM2_VID[SAM2 Video Predictor]
FWD[前向追踪]
BWD[后向追踪]
MEM[记忆库: 多帧特征缓存]
end
subgraph Correction["修正回环层"]
CHECK[人工质检]
FIX[修正帧标注]
RE_TRACK[重新追踪]
end
subgraph Output["输出层"]
MASK[掩码序列]
COMP[合成视频]
MAT[抠像结果]
end
V --> FP
FP --> P & B & T
P & B & T --> SAM2_IMG
SAM2_IMG --> SAM2_VID
SAM2_VID --> FWD & BWD
FWD & BWD --> MEM
MEM --> CHECK
CHECK -->|发现问题| FIX
FIX --> RE_TRACK
RE_TRACK --> SAM2_VID
CHECK -->|确认无误| MASK
MASK --> COMP & MAT
```
## 3.1 模型选型
| 组件 | 推荐模型 | 作用 |
|------|---------|------|
| 图像分割基座 | **SAM2** (Segment Anything Model 2) | 提供单帧分割与视频追踪能力 |
| 语义 grounding | Grounding DINO / YOLO-World | 将文本提示转为检测框 |
| 特征缓存 | SAM2 Memory Attention | 跨帧特征传播与目标记忆 |
| 后处理 | 形态学滤波 / 时序一致性约束 | 消除帧间抖动与空洞 |
## 4. ComfyUI 节点设计
### 4.1 节点拓扑图
```mermaid
flowchart LR
subgraph 输入
LoadVideo["🎬 Load Video (Path + FPS)"]
FramePicker["🔍 Frame Picker (选帧)"]
end
subgraph 提示生成
PointPrompt["📍 Point Prompt (points + labels)"]
BoxPrompt["📦 Box Prompt (xyxy)"]
TextPrompt["💬 Text Prompt (语义)"]
Grounding["🎯 Grounding DINO / YOLO-World"]
end
subgraph SAM2核心
SAM2Loader["⚙️ SAM2 Model Loader"]
SAM2Image["🖼️ SAM2 Image Predictor"]
SAM2Video["🎞️ SAM2 Video Predictor"]
SAM2AddMask[" SAM2 Add Mask Hint"]
end
subgraph 追踪控制
TrackForward["⏩ Track Forward"]
TrackBackward["⏪ Track Backward"]
TrackRange["🔀 Track Range (双向)"]
end
subgraph 修正与输出
MaskViewer["👁️ Mask Viewer / 人工检查"]
MaskFix["✏️ Manual Mask Correction"]
MaskToVideo["🎬 Mask Sequence to Video"]
Composite["🎨 Composite (原图 + Mask)"]
SaveMasks["💾 Save Mask Sequence"]
end
LoadVideo --> FramePicker
FramePicker --> SAM2Image
PointPrompt & BoxPrompt --> SAM2Image
TextPrompt --> Grounding --> BoxPrompt
SAM2Loader --> SAM2Image & SAM2Video
SAM2Image --> SAM2Video
SAM2Video --> TrackForward & TrackBackward
TrackForward & TrackBackward --> MaskViewer
MaskViewer -->|OK| SaveMasks
MaskViewer -->|Fix| MaskFix
MaskFix --> SAM2AddMask --> SAM2Video
SaveMasks --> MaskToVideo & Composite
```
### 4.2 节点详细说明
#### 4.2.1 输入节点
**`LoadVideo`**
- 输入: 视频路径 (mp4/avi/mov)
- 输出: 图像批次 (image batch), 帧率, 总帧数, 元数据
- 参数: `start_frame`, `end_frame`, `skip_frame` (抽帧)
**`FramePicker`**
- 功能: 从视频批次中选择一帧作为关键帧
- 参数: `frame_index` (默认 0, 即第一帧)
- 输出: 单张图像 + 对应的批次索引
#### 4.2.2 提示节点
**`PointPrompt`**
- 输入: 图像坐标列表 `[(x1,y1), (x2,y2), ...]`
- 参数: `labels` (1=正选前景, 0=反选背景)
- 输出: 结构化 prompt 对象
**`BoxPrompt`**
- 输入: 边界框 `[[x1,y1,x2,y2], ...]`
- 支持多框同时输入
- 可与 PointPrompt 混合使用
**`TextPrompt`**
- 输入: 自然语言描述,如 `"a person wearing red hat"`
- 依赖: Grounding DINO / YOLO-World 节点前置转换
- 输出: 自动生成的 BoxPrompt
#### 4.2.3 SAM2 核心节点
**`SAM2ModelLoader`**
- 加载 SAM2 模型权重:
- `sam2_hiera_tiny.pt` (轻量/预览)
- `sam2_hiera_small.pt` (平衡)
- `sam2_hiera_base_plus.pt` (高精度)
- `sam2_hiera_large.pt` (最佳质量)
- 输出: model 对象
**`SAM2ImagePredictor`**
- 功能: 对单帧生成分割掩码
- 输入: image, model, point_prompt / box_prompt / mask_prompt
- 输出: mask (1,H,W), 置信度分数, logits
- 参数: `multimask_output` (是否输出多候选 mask)
**`SAM2VideoPredictor`**
- 功能: 初始化视频追踪状态
- 输入: model, video_frames (image batch), initial_frame_index, initial_mask
- 内部逻辑:
1. 对视频所有帧预计算图像编码 (Image Encoder)
2. 在初始帧注入 mask 作为记忆
3. 构建时空记忆库
- 输出: video_state 对象
**`SAM2AddMaskHint`**
- 功能: 在指定帧追加/修正 mask 提示,用于人工修正回环
- 输入: video_state, frame_index, new_mask
- 输出: 更新后的 video_state
#### 4.2.4 追踪节点
**`TrackForward`**
- 输入: video_state, start_frame, end_frame
- 逻辑: 从 start_frame 的记忆向后续帧传播
- 输出: mask_sequence (从 start 到 end 的掩码序列)
**`TrackBackward`**
- 输入: video_state, start_frame, end_frame
- 逻辑: 从 start_frame 的记忆向前序帧反向传播
- 输出: mask_sequence
**`TrackRange (双向追踪)`**
- 封装 TrackForward + TrackBackward
- 以关键帧为中心,自动向两端传播
- 输出: 完整视频的 mask_sequence
#### 4.2.5 修正与输出节点
**`MaskViewer`**
- 功能: 可视化 mask 叠加结果,支持逐帧检查
- 显示: 原图 + 半透明 mask + 边界轮廓
- 交互: 标记问题帧索引
**`ManualMaskCorrection`**
- 输入: 原图, 当前错误 mask
- 功能: 提供简易画板,人工涂鸦修正 mask
- 输出: 修正后的 mask
- 触发: 修正后的 mask 通过 `SAM2AddMaskHint` 重新注入追踪流程
**`MaskSequenceToVideo`**
- 输入: mask_sequence (batch of masks)
- 参数: `color_map`, `alpha`, `fps`
- 输出: 合成视频文件
**`CompositeMask`**
- 输入: 原视频帧, mask_sequence
- 功能: 生成绿幕/透明通道/高亮边框等合成效果
- 输出: 合成后的图像批次
**`SaveMaskSequence`**
- 输入: mask_sequence
- 输出: 按帧保存的 PNG (8-bit 灰度或 1-bit 掩码)
- 可选: 保存为 numpy `.npy` 数组供下游使用
## 5. 工作流程 (Workflow)
### 5.1 标准流程:第一帧标注 + 双向追踪
```mermaid
sequenceDiagram
actor User
participant UI as ComfyUI
participant V as 视频输入
participant S2 as SAM2
participant T as 追踪器
participant Out as 输出
User->>V: 上传视频
V->>UI: 提取帧序列
User->>UI: 选择第 0 帧
User->>UI: 点/框/文本标注目标
UI->>S2: 生成初始 mask
S2->>UI: 返回分割结果预览
User->>UI: 确认初始分割
UI->>T: 初始化 Video Predictor + 注入初始 mask
par 前向追踪
T->>T: 从第0帧 → 最后一帧
and 后向追踪
T->>T: 从第0帧 → 第0帧 (若首帧则无)
end
T->>UI: 返回完整 mask sequence
User->>UI: 逐帧检查结果
alt 发现问题
User->>UI: 在帧 N 进行人工修正
UI->>S2: 注入修正 mask
UI->>T: 从帧 N 重新双向追踪
T->>UI: 更新 mask sequence
else 无问题
UI->>Out: 输出最终掩码 + 合成视频
end
```
### 5.2 中途关键帧修正流程
当视频较长或目标发生严重形变/遮挡时,可在中间帧插入新的关键帧进行修正:
1. **运行标准流程** 获取初版 mask sequence
2. **人工检查** 发现帧 `[N, N+k]` 区间出现追踪漂移
3. **暂停追踪**,在帧 `N` 进行交互式重新标注(点/框修正)
4. **以帧 N 为新锚点**,分别执行:
- `TrackForward`: N → N+k (覆盖原错误区间)
- `TrackBackward`: N → 0 (可选,若前面也有问题)
5. **合并 mask sequence**: 用新追踪结果替换原错误区间
6. **输出最终序列**
## 6. 关键技术细节
### 6.1 SAM2 视频追踪原理
SAM2 的视频分割基于**流式记忆机制**
1. **图像编码**: 每帧独立通过 Hiera Image Encoder 提取视觉特征
2. **记忆注意力**: 当前帧的解码通过 Memory Attention 模块查询历史记忆
3. **记忆库组成**:
- **对象记忆**: 先前帧的高分辨率 mask 嵌入
- **位置记忆**: 帧间时空位置编码
- **指针记忆**: 最近帧的特征缓存
4. **传播方式**: 逐帧顺序传播,当前帧的分割结果成为下一帧的记忆提示
### 6.2 双向追踪策略
```
视频帧: [0] [1] [2] ... [N-1] [N] [N+1] ... [T]
^关键帧 K
|
┌───────────┴───────────┐
▼ ▼
后向追踪 前向追踪
K → K-1 → ... → 0 K → K+1 → ... → T
```
- **单关键帧**: 默认第一帧,向两端传播
- **多关键帧**: 长视频可分段设置多个关键帧,各自追踪后合并
### 6.3 修正回环机制
```python
# 伪代码示意
def iterative_video_segmentation(video, prompts):
# 1. 初始分割
keyframe = video[0]
mask_0 = sam2_image_predict(keyframe, prompts)
# 2. 初始化视频追踪
state = sam2_video_init(video)
state.add_mask(frame_idx=0, mask=mask_0)
# 3. 双向追踪
masks = track_bidirectional(state, anchor=0)
# 4. 人工修正回环
while True:
bad_frames = human_inspect(masks)
if not bad_frames:
break
fix_frame = bad_frames[0]
new_prompt = human_correct(video[fix_frame], masks[fix_frame])
new_mask = sam2_image_predict(video[fix_frame], new_prompt)
# 重新注入并局部追踪
state.add_mask(frame_idx=fix_frame, mask=new_mask)
masks = track_bidirectional(state, anchor=fix_frame)
return masks
```
### 6.4 语义提示链路
文本提示需先转换为空间位置信息,再输入 SAM2
```
用户输入: "the black cat on the sofa"
Grounding DINO / YOLO-World
检测框: [x1, y1, x2, y2] + 置信度
SAM2 Box Prompt
分割 Mask
```
若检测结果不准确,用户可手动调整检测框或直接切换为点标注模式。
## 7. 数据流定义
### 7.1 节点间数据格式
| 数据类型 | 格式 | 说明 |
|---------|------|------|
| `IMAGE` | `torch.Tensor` (B,H,W,C) uint8/float32 | 图像批次ComfyUI 原生格式 |
| `MASK` | `torch.Tensor` (B,1,H,W) float32 | 二值或概率掩码 |
| `SAM2_MODEL` | 自定义对象 | 含 image_encoder, memory_attention, mask_decoder |
| `SAM2_STATE` | 自定义对象 | 视频追踪状态,含特征缓存与记忆库 |
| `POINTS` | `List[Tuple[int,int]]` | 坐标列表 |
| `LABELS` | `List[int]` | 1=前景, 0=背景 |
| `BOXES` | `Tensor[N,4]` | xyxy 格式检测框 |
| `MASK_SEQ` | `List[Tensor[1,H,W]]` | 帧序列对应的掩码列表 |
### 7.2 输入输出规范
**输入**
- 视频文件: 支持常见格式 (mp4, mov, avi, mkv)
- 分辨率建议: ≤1080p (SAM2 对高分辨率显存敏感)
- 帧率: 按需抽帧,非必要不逐帧 (如 30fps 视频可抽 5-10fps)
**输出**
- Mask 序列: 每帧一个 PNG 灰度图,文件名 `frame_{:05d}.png`
- 合成视频: 带透明通道的 RGBA 视频或叠加遮罩的预览视频
- 元数据: JSON 记录每帧的分割类别、置信度、人工修正标记
## 8. 异常处理与边界情况
| 场景 | 策略 |
|------|------|
| 目标遮挡 > 50% 帧 | 依赖记忆库推断,若失败则提示人工标注 |
| 目标出画再入画 | SAM2 可能丢失目标,需在重新出现时设置新关键帧 |
| 多目标分割 | 每目标独立 mask支持批量追踪 |
| 光线剧烈变化 | 时序一致性后处理,或中间帧修正 |
| 显存不足 | 自动启用半精度 (fp16) / 梯度检查点 / 降低分辨率 |
| 追踪漂移累积 | 分段设置关键帧,限制单次追踪长度 |
## 9. 系统扩展性
### 9.1 未来可扩展方向
1. **自动关键帧检测**: 基于光流或特征差异自动建议关键帧位置
2. **多目标并行追踪**: 同时追踪多个语义对象,输出独立 mask 通道
3. **在线学习**: 利用人工修正样本微调分割模型
4. **实时预览**: 降低分辨率快速追踪预览,确认后再全分辨率输出
5. **与 3D 结合**: 输出 mask 用于 NeRF/3DGS 的前景分离
### 9.2 节点生态集成
| 现有 ComfyUI 生态 | 用途 |
|------------------|------|
| ComfyUI-VideoHelperSuite | 视频加载/保存/帧处理 |
| ComfyUI-SAM2 / WAS Node Suite | SAM2 基础封装 |
| ComfyUI-Impact-Pack (Detector) | Grounding DINO / YOLO 接入 |
| ComfyUI-Advanced-ControlNet | 时序一致性约束 |
| ComfyUI-Frame-Interpolation | 帧间 mask 插值补全 |
## 10. 部署与运行建议
### 10.1 硬件要求
| 配置 | 推荐规格 |
|------|---------|
| GPU | NVIDIA RTX 4090 / A100 (24GB+ VRAM) |
| RAM | 32GB+ |
| 存储 | SSD视频与中间特征缓存较大 |
### 10.2 软件依赖
```text
pytorch >= 2.0
cuda >= 11.8
sam2 (Meta 官方仓库)
comfyui (最新版)
opencv-python
imageio-ffmpeg
```
### 10.3 性能优化
- **预编码缓存**: 视频所有帧的图像特征只需编码一次,建议缓存到磁盘
- **分块追踪**: 长视频分段处理,避免显存持续增长
- **fp16 推理**: SAM2 支持半精度,显存占用减半,精度损失极小
- **关键帧密度**: 根据目标运动速度动态调整,慢速运动 2-5s 一帧,快速/形变 0.5-1s 一帧
---
## 附录ComfyUI 工作流 JSON 结构示意
```json
{
"last_node_id": 42,
"last_link_id": 89,
"nodes": [
{ "id": 1, "type": "LoadVideo", ... },
{ "id": 2, "type": "FramePicker", ... },
{ "id": 10, "type": "SAM2ModelLoader", "inputs": { "model_name": "sam2_hiera_base_plus.pt" } },
{ "id": 20, "type": "PointPrompt", ... },
{ "id": 25, "type": "SAM2ImagePredictor", ... },
{ "id": 30, "type": "SAM2VideoPredictor", ... },
{ "id": 35, "type": "TrackRange", ... },
{ "id": 40, "type": "MaskViewer", ... },
{ "id": 41, "type": "SaveMaskSequence", ... }
],
"links": [
[1, 0, 2, 0, "IMAGE"],
[2, 0, 25, 0, "IMAGE"],
[10, 0, 25, 1, "SAM2_MODEL"],
[20, 0, 25, 2, "POINTS"],
[25, 0, 30, 0, "MASK"],
[30, 0, 35, 0, "SAM2_STATE"],
[35, 0, 40, 0, "MASK_SEQ"],
[40, 0, 41, 0, "MASK_SEQ"]
]
}
```
---
> **备注**: 本系统核心依赖 SAM2 的视频追踪能力。若 ComfyUI 生态中 SAM2 节点尚未完全支持 video predictor 的全部特性(如记忆注入、双向追踪),需基于 [facebookresearch/segment-anything-2](https://github.com/facebookresearch/segment-anything-2) 官方实现进行 ComfyUI 节点封装。