Files
rui40000-RUI-Nodes/README.md
T
rui40000andClaude Opus 4.8 a1f52de801 feat: Unmult 增加「主体保护」开关,控制是否采纳 subject_mask
subject_mask 的合并逻辑此前已存在,本次补上开关:
- 启用(默认):alpha 取 max(unmult 结果, subject_mask)
- 关闭:即便上游已连线也完全不采纳,等同纯 Unmult
想对比「有无 AI 介入」的差别时拨开关即可,不必拔线。
兼容旧英文名 use_subject_mask。

顺带把黑点/白点 tooltip 里的「(主体保护)」字样去掉 —— 那是描述
参数作用的措辞,和新开关撞名会让人以为是同一功能。

实测(黑底 + 暗色实体,alpha 真值恒为 1,下半近纯黑):
  不接 mask              暗部 alpha 0.080  ← 黑衣黑发被扣穿
  接 mask + 保护启用      暗部 alpha 1.000
  接 mask + 保护关闭      暗部 alpha 0.080,与不接 mask 逐元素一致
即开关确实起作用,且关闭时行为与纯 Unmult 完全等价。

这同时解掉了上次记录的适用边界:黑底 unmult 本质是拿亮度当不透明度,
对实体不成立;现在接一路语义抠图的 alpha 进 subject_mask 即可破解 ——
语义模型负责「哪里是主体」,Unmult 负责「边缘有多透」。README 已按此改写。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-18 15:44:32 +08:00

1264 lines
63 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Rui-Node🐶 - ComfyUI 图像处理节点集
Rui-Node🐶 是一个功能丰富的 ComfyUI 节点集合,提供图像处理、文本处理、AI 模型集成和遮罩处理等多种功能。
## 📦 安装方法
1. 将此文件夹复制到 ComfyUI 的 `custom_nodes` 目录中
2. 安装依赖:`pip install -r requirements.txt`
3. 重启 ComfyUI
## 📋 节点目录
### 🎨 图像调节类
- [调整饱和度 / Saturation Adjustment](#1-调整饱和度--saturation-adjustment)
- [图像翻转 / Image Flip](#2-图像翻转--image-flip)
- [颜色匹配器 / Color Matcher](#13-颜色匹配器--color-matcher)
- [素材拆分 / Sprite Splitter](#14-素材拆分--sprite-splitter)
- [素材拆分(带透明通道) / Sprite Splitter RGBA](#15-素材拆分带透明通道--sprite-splitter-rgba)
- [满屏文字水印 / Full-Screen Text Watermark](#21-满屏文字水印--full-screen-text-watermark)
- [像素化 / Pixelate](#24-像素化--pixelate)
- [八方向序列拆分 / 8-Direction Sprite Split](#25-八方向序列拆分--8-direction-sprite-split)
- [半透明抠图 / Unmult Matting](#27-半透明抠图--unmult-matting)
### 📁 文件存储与加载类
- [按路径加载图像 / Load Image By Path](#3-按路径加载图像--load-image-by-path)
- [加载图像(带文件名) / Load Image With Name](#16-加载图像带文件名--load-image-with-name)
### 🤖 AI模型类
- [千问编辑图像生成 / Qwen Edit Image Generation](#4-千问编辑图像生成--qwen-edit-image-generation)
- [SDMatte 精细抠图 / SDMatte Interactive Matting](#17-sdmatte-精细抠图--sdmatte-interactive-matting)
- [ZenMux API 连接 / ZenMux API Connector](#18-zenmux-api-连接--zenmux-api-connector)
- [越光 API 连接 / YueGuang API Connector](#26-越光-api-连接--yueguang-api-connector)
- [FeyNobg 抠图 / FeyNobg Matting](#22-feynobg-抠图--feynobg-matting)
- [Lucida 抠图 / Lucida Matting](#23-lucida-抠图--lucida-matting)
### 📝 文本处理类
- [镜头分词器 / Shot Splitter](#5-镜头分词器--shot-splitter)
- [对白提取器 / Dialogue Extractor](#6-对白提取器--dialogue-extractor)
- [页面旁白删除器 / Page Narration Remover](#7-页面旁白删除器--page-narration-remover)
- [文本列表制作器 / Text List Creator](#8-文本列表制作器--text-list-creator)
- [转化为utf-8编码 / Convert to UTF-8](#11-转化为utf-8编码--convert-to-utf-8)
- [Markdown转图片 / Markdown To Image](#19-markdown转图片--markdown-to-image)
- [多行文本框(原样输出) / Text Box (Raw)](#20-多行文本框原样输出--text-box-raw)
### 🎭 遮罩处理类
- [遮罩筛选 / Mask Selector](#9-遮罩筛选--mask-selector)
- [遮罩预览 / Mask Preview](#10-遮罩预览--mask-preview)
---
## 📖 节点详细说明
### 1. 调整饱和度 / Saturation Adjustment
**分类**: `Rui-Node🐶/图像调节🎨`
**功能描述**:
调整图像的色彩饱和度,可以创建黑白图像或增强色彩鲜艳度。
**输入参数**:
- `image` (IMAGE): 输入图像
- `saturation` (FLOAT): 饱和度调整系数
- 默认值: 1.0
- 范围: 0.0 ~ 5.0
- 步长: 0.1
- 说明:
- 0.0 = 完全无饱和度(黑白图像)
- 1.0 = 原始饱和度(不变)
- >1.0 = 增加饱和度
**输出**:
- `IMAGE`: 调整后的图像
**使用场景**:
- 将彩色图像转换为黑白
- 增强图像色彩表现力
- 降低过于鲜艳的色彩
---
### 2. 图像翻转 / Image Flip
**分类**: `Rui-Node🐶/图像调节🎨`
**功能描述**:
对图像进行水平或垂直翻转操作。
**输入参数**:
- `image` (IMAGE): 输入图像
- `flip_direction` (选择): 翻转方向
- 选项: "水平" 或 "垂直"
- 默认值: "水平"
**输出**:
- `IMAGE`: 翻转后的图像
**使用场景**:
- 镜像翻转图像
- 创建对称效果
- 调整图像方向
---
### 3. 按路径加载图像 / Load Image By Path
**分类**: `Rui-Node🐶/文件存储与加载📁`
**功能描述**:
从指定的文件路径加载图像文件,支持绝对路径输入。
**输入参数**:
- `image_path` (STRING): 图像文件的完整路径
- 默认值: "E:\\ComfyUIModels\\input\\10\\1.png"
- 支持格式: PNG、JPG、JPEG 等常见图像格式
**输出**:
- `IMAGE`: 加载的图像
**特殊处理**:
- 如果文件不存在,返回 512x512 的黑色默认图像
- 自动将非 RGB 图像转换为 RGB 模式
**使用场景**:
- 从外部路径加载特定图像
- 批量处理指定目录的图像
- 加载非 ComfyUI 默认输入目录的图像
---
### 4. 千问编辑图像生成 / Qwen Edit Image Generation
**分类**: `Rui-Node🐶/AI模型🤖`
**功能描述**:
使用阿里云千问(Qwen)编辑模型 API 进行 AI 图像生成,支持多种控制模式。
**输入参数**:
- `image1` ~ `image4` (IMAGE): 最多 4 张输入图像作为参考
- `api_key` (STRING): 阿里云 API 密钥
- `base_url` (STRING): API 基础 URL
- 默认值: "https://dashscope.aliyuncs.com/api/v1/services/aigc/text2image-generation/generation"
- `seed` (INT): 随机种子
- 默认值: -1(随机生成)
- 范围: -1 ~ 2147483647
- `control_mode` (选择): 控制模式
- 选项: reference, sketch, scribble, pose, canny, depth, hed, mlsd, normal, seg
- 默认值: "reference"
- `width` (INT): 输出图像宽度
- 默认值: 1024
- 范围: 512 ~ 2048
- 步长: 8
- `height` (INT): 输出图像高度
- 默认值: 1024
- 范围: 512 ~ 2048
- 步长: 8
**输出**:
- `IMAGE`: AI 生成的图像
**使用场景**:
- AI 辅助图像创作
- 基于参考图生成新图像
- 多模态图像控制生成
---
### 5. 镜头分词器 / Shot Splitter
**分类**: `Rui-Node🐶/文本处理📝`
**功能描述**:
将包含多个分镜描述的脚本文本拆分成独立的分镜列表,支持按范围筛选导出。
**输入参数**:
- `input_text` (STRING): 输入的多分镜描述脚本(多行文本)
- 格式要求: 使用 `<SHOT_XXX>...</SHOT_XXX>` 标签包裹每个分镜
- `start_shot_num` (INT, 可选): 开始导出的分镜编号
- 默认值: 0(从第一个开始)
- 范围: 0 ~ 100
- `shot_count` (INT, 可选): 导出的分镜数量
- 默认值: 0(导出全部)
- 范围: 0 ~ 100
**输出**:
- `shot_descriptions` (LIST): 拆分后的分镜描述列表
- `summary` (STRING): 总结信息
**文本格式示例**:
```
<SHOT_1>
第一个镜头的描述内容
</SHOT_1>
<SHOT_2>
第二个镜头的描述内容
</SHOT_2>
```
**使用场景**:
- 分镜脚本拆分
- 批量处理分镜描述
- 选择性导出特定范围的分镜
---
### 6. 对白提取器 / Dialogue Extractor
**分类**: `Rui-Node🐶/文本处理📝`
**功能描述**:
从分镜描述文本中自动提取旁白/对白内容。
**输入参数**:
- `input_text` (STRING): 输入的分镜描述文本(多行文本)
**输出**:
- `dialogues` (LIST): 提取的旁白/对白列表
- `summary` (STRING): 总结信息
**识别模式**:
- 支持格式 1: `旁白:[对白内容]`
- 支持格式 2: `旁白:对白内容`
- 自动识别 `<SHOT_XXX>` 标签中的旁白
**使用场景**:
- 从分镜脚本中提取对白
- 批量收集旁白文本
- 准备配音文本
---
### 7. 页面旁白删除器 / Page Narration Remover
**分类**: `Rui-Node🐶/文本处理📝`
**功能描述**:
删除文本中所有以"页面旁白:"或"页面旁白:"开头的整行内容。
**输入参数**:
- `input_text` (STRING): 原始文本(多行文本)
**输出**:
- `clean_text` (STRING): 移除页面旁白行后的文本
**处理规则**:
- 自动识别并删除以"页面旁白:"或"页面旁白:"开头的行
- 忽略行首行尾的空白字符
- 保留其他所有内容
**使用场景**:
- 清理脚本中的页面旁白
- 文本预处理
- 提取纯净对白内容
---
### 8. 文本列表制作器 / Text List Creator
**分类**: `Rui-Node🐶/文本处理📝`
**功能描述**:
将多个独立的文本段落组织成列表形式输出。
**输入参数**:
- `text1` (STRING, 必需): 第一段文本(多行文本)
- `text2` ~ `text5` (STRING, 可选): 第 2~5 段文本(多行文本)
**输出**:
- `text_list` (LIST): 文本列表(Python 列表格式)
- `summary` (STRING): 总结信息
**处理规则**:
- 自动过滤空文本
- 去除每段文本首尾的空白字符
- 保留内部段落结构
**使用场景**:
- 组织多段文本为列表
- 批量文本处理准备
- 文本分组管理
---
### 9. 遮罩筛选 / Mask Selector
**分类**: `Rui-Node🐶/遮罩处理🎭`
**功能描述**:
对输入的多个遮罩进行排序并选择特定遮罩,同时输出剩余遮罩的合并结果。
**输入参数**:
- `masks` (MASK): 输入的遮罩(可包含多个遮罩)
- `sort_method` (选择): 排序方法
- 选项:
- "按面积排序 / By Area": 按遮罩面积从大到小排序
- "从左到右 / Left to Right": 按遮罩质心 X 坐标升序排序
- "从上到下 / Top to Bottom": 按遮罩质心 Y 坐标升序排序
- 默认值: "按面积排序 / By Area"
- `index` (INT): 选择的遮罩编号(1-based 索引)
- 默认值: 1
- 最小值: 1
- 说明: 如果超出范围会自动夹取到有效范围
**输出**:
- `选中遮罩 / Selected` (MASK): 选中的单个遮罩
- `剩余遮罩 / Remaining` (MASK): 其他遮罩的合并结果
- `信息 / Info` (STRING): JSON 格式的详细信息
- `total_masks`: 遮罩总数
- `selected_index`: 选中编号
- `sort_method`: 排序方式
- `selected_area`: 选中遮罩的像素面积
- `selected_center`: 选中遮罩的质心坐标 [x, y]
- `index_clamped`: 编号是否越界被修正
**使用场景**:
- 从多个检测结果中选择特定目标
- 分离主体和背景遮罩
- 基于大小或位置筛选遮罩
---
### 10. 遮罩预览 / Mask Preview
**分类**: `Rui-Node🐶/遮罩处理🎭`
**功能描述**:
将遮罩以半透明彩色形式叠加显示在图像上,方便直观查看遮罩覆盖区域。节点自带预览功能,同时输出合成后的图像。
**输入参数**:
- `image` (IMAGE): 作为底图的原始图像
- `mask` (MASK): 需要可视化的遮罩
- `mask_color` (选择): 遮罩显示颜色
- 默认值: 红色 / Red
- 选项: 红色、绿色、蓝色、黄色、青色、品红、白色
- `opacity` (FLOAT, 可选): 不透明度
- 默认值: 0.5
- 范围: 0.0 ~ 1.0
- 步长: 0.05
**输出**:
- `图像 / Image` (IMAGE): 合成了半透明彩色遮罩的图像
**特性**:
- 自动处理遮罩与图像的尺寸差异
- 节点界面直接显示预览效果
- 支持批量处理
- 7种预设颜色可选
- 可调节不透明度
**使用场景**:
- 检查分割结果的准确性
- 调试遮罩处理流程
- 多遮罩对比(使用不同颜色)
- 制作遮罩可视化图
---
### 11. 转化为utf-8编码 / Convert to UTF-8
**分类**: `Rui-Node🐶/文本处理📝`
**功能描述**:
删除输入字符串中所有非 UTF-8 编码字符(如孤立的代理对),确保输出的字符串符合 UTF-8 编码规范。
**输入参数**:
- `input_text` (STRING): 需要处理的原始字符串(支持多行)
**输出**:
- `filtered_text` (STRING): 过滤后的符合 UTF-8 规范的字符串
- `log` (STRING): 处理日志,包含移除字符的详细信息和统计总结
**使用场景**:
- 清理可能包含非法字符的文本数据
- 确保文本在保存或传输时的编码安全性
- 调试文本编码问题
---
### 12. OpenAI API 连接 / OpenAI API Connector
**分类**: `Rui-Node🐶/AI模型🤖`
**功能描述**:
连接 OpenAI 或兼容 API(如 DeepSeek、Moonshot 等),进行文本生成或多模态图像理解,支持最多 6 张图像同时输入。
**输入参数**:
- `api_url` (STRING): API 接口地址
- 默认值: "https://api.openai.com/v1/chat/completions"
- `api_key` (STRING): API 密钥
- `model` (STRING): 模型名称
- 默认值: "gpt-4o"
- `system_prompt` (STRING): 系统提示词
- `user_prompt` (STRING): 用户提示词
- `seed` (INT): 随机种子,用于控制生成的随机性
- `image_1` ~ `image_6` (IMAGE, 可选): 最多 6 张输入图像
- 说明: 用户有几张图就连接几个输入口,无需手动 Batch
- 规则: 节点内部会自动逐张处理每个输入图像,分别编码后发送到 API
- 优势: 不要求所有图像尺寸一致,512×512 和 511×768 之类的混合输入也可直接使用
- `temperature` (FLOAT, 可选): 采样温度
- 默认值: 0.3
- 范围: 0.0 ~ 2.0
- `max_tokens` (INT, 可选): 最大输出 token 数
- 默认值: 500
- 范围: 1 ~ 8192
- `detail` (选择, 可选): 图像分析细节等级
- 选项: low, high, auto
- 默认值: auto
- `image_max_size` (INT, 可选): 单张图像最长边缩放上限
- 默认值: 1024
- 范围: 256 ~ 4096
- 说明: 超过该尺寸的图像会在发送前按比例缩小,以减少 token 消耗与请求体积
- `proxy_url` (STRING, 可选): HTTP/HTTPS 代理地址
- 示例: `http://127.0.0.1:7890`
**输出**:
- `text` (STRING): 模型生成的文本内容
**使用场景**:
- 调用 LLM 进行文本生成
- 使用 Vision 模型进行单图或多图联合理解
- 连接本地或第三方兼容 OpenAI 协议的 API
- 对多张参考图做综合分析、比对与总结
---
### 13. 颜色匹配器 / Color Matcher
**分类**: `Rui-Node🐶/图像调节🎨`
**功能描述**:
将目标图像的颜色分布匹配到参考图像的颜色分布,支持多种匹配算法和混合调节。
**输入参数**:
- `reference_image` (IMAGE): 作为颜色参考的图像
- `moving_image` (IMAGE): 需要改变颜色的目标图像
- `match_method` (选择): 匹配算法
- 选项: "histogram" (直方图匹配), "mean_std" (均值标准差匹配), "none" (无匹配)
- 默认值: "histogram"
- `blend_factor` (FLOAT): 混合系数
- 默认值: 1.0
- 范围: 0.0 ~ 1.0
- 步长: 0.01
- 说明: 控制原图和匹配后图像的混合比例,1.0为完全使用匹配后图像
**输出**:
- `颜色匹配后图像` (IMAGE): 颜色调整后的图像
- `匹配信息` (STRING): 记录了使用的匹配方式以及混合系数的日志信息
**使用场景**:
- 统一多张图像的色调风格
- 将素材无缝融合进背景
- 图像色彩风格迁移
---
### 14. 素材拆分 / Sprite Splitter
**分类**: `Rui-Node🐶/图像调节🎨`
**功能描述**:
从白色/浅色背景的合图(Sprite Sheet)中自动拆分出每个独立的美术元素,通过连通区域检测进行裁剪,并将每个独立元素作为图像列表输出。
**输入参数**:
- `图像` (IMAGE): 输入的带有透明通道的合图图像(RGBA格式)
- `最小面积过滤(像素数)` (INT): 最小面积过滤
- 默认值: 100
- 范围: 1 ~ 50000
- 说明: 面积小于此值(像素数)的连通区域将被过滤,避免拆分出噪点碎片。
- `裁剪边距` (INT): 裁剪边距
- 默认值: 2
- 范围: 0 ~ 50
- 说明: 每个元素裁剪时在包围盒外额外保留的像素边距。
- `排序方式` (选择): 排序方式
- 选项: "从左到右-从上到下", "从上到下-从左到右", "面积从大到小", "面积从小到大"
- 默认值: "从左到右-从上到下"
- `seed` (INT): 随机种子
- 默认值: 0
- 说明: 仅用于强制重新执行节点,不影响实际拆分结果。适用于线上部署时强制刷新缓存。
**输出**:
- `图像列表` (IMAGE): 拆分后的多张图像列表,透明区域会用白色填充输出。
**使用场景**:
- 游戏素材合图切分
- 批量图标提取
- 白底素材自动裁剪
---
### 15. 素材拆分(带透明通道) / Sprite Splitter RGBA
**分类**: `Rui-Node🐶/图像调节🎨`
**功能描述**:
与标准素材拆分节点功能相同,但保留并额外输出 Alpha 透明通道,适用于需要透明背景的美术素材提取。
**输入参数**:
- 输入参数与 [素材拆分 / Sprite Splitter](#14-素材拆分--sprite-splitter) 完全一致。
**输出**:
- `图像列表` (IMAGE): 拆分后的多张 RGB 图像列表
- `遮罩列表` (MASK): 对应的多张 Alpha 透明通道遮罩列表,1.0代表不透明,0.0代表透明
**使用场景**:
- 提取带透明背景的游戏角色、道具素材
- 搭配 `JoinImageWithAlpha` 等节点生成透明 PNG 图像
---
### 16. 加载图像(带文件名) / Load Image With Name
**分类**: `Rui-Node🐶/文件存储与加载📁`
**功能描述**:
基础功能与 ComfyUI 原生的 "Load Image" 节点完全一致,支持从 ComfyUI 的 `input` 目录中选择图像,并支持拖拽上传。区别在于本节点额外提供了一个字符串输出端口,用于输出图像的文件名。
**输入参数**:
- `image` (下拉选择): 从 `input` 目录中选择图像文件,或通过按钮上传
**输出**:
- `IMAGE`: 图像数据
- `MASK`: 图像的 Alpha 通道遮罩
- `filename` (STRING): 图像的文件名(不包含后缀,例如上传了 `test_image.png`,则输出 `test_image`)
**使用场景**:
- 批量处理图像时,希望以原文件名保存处理后的结果
- 需要将当前图像的文件名作为提示词或其他参数传递给下游节点
- 建立更规范的自动化工作流
---
## 🔧 依赖库
主要依赖库包括:
- `torch`: PyTorch 深度学习框架
- `numpy`: 数值计算
- `Pillow (PIL)`: 图像处理
- `requests`: HTTP 请求(用于 API 调用)
完整依赖请查看 `requirements.txt`
## 📝 注意事项
1. 所有节点都兼容 ComfyUI 的标准图像处理流程
2. 图像格式统一为 BHWC(批次、高度、宽度、通道)
3. 图像值范围为 0.0 ~ 1.0 的浮点数
4. 使用 AI 模型节点需要配置有效的 API 密钥
5. 文本处理节点支持多行文本输入
6. 所有节点名称采用中英双语显示
7. 遮罩处理节点自动处理尺寸不匹配问题
### 17. SDMatte 精细抠图 / SDMatte Interactive Matting
基于 [SDMatte](https://github.com/vivoCameraResearch/SDMatte)(vivo 相机研究院,ICCV 2025)的交互式抠图节点。
擅长发丝、绒毛、玻璃、烟雾等常规抠图模型处理不好的边缘。
包含两个节点:
| 节点 | 作用 |
|---|---|
| **SDMatte 加载器** | 载入权重,构建网络并常驻显存 |
| **SDMatte 精细抠图** | 用视觉提示(框/掩码/点)驱动模型输出 alpha |
#### 模型准备
把权重放到 `ComfyUI/models/SDMatte/` 下即可,两种格式任选其一:
- `SDMatte_plus.pth` — 官方发布,12.1GB,[LongfeiHuang/SDMatte](https://huggingface.co/LongfeiHuang/SDMatte)
- `SDMatte_plus.safetensors` — 社区转换,5.19GB,[1038lab/SDMatte](https://huggingface.co/1038lab/SDMatte)
> **这两个文件的模型权重逐比特完全相同**,不必纠结选哪个。
> 已实测比对全部 1316 个张量:键名、形状、精度(均为 F32)、数值全部一致,无一例外。
> 官方 pth 是 detectron2 的训练检查点,顶层为 `{"model", "trainer", "iteration"}`,
> 多出的约 6.9GB 是 `trainer` 里的优化器状态与梯度缩放器,推理不参与。
> 换用 pth **不会带来任何质量提升**。本节点两种格式都支持,读 pth 时只解析 `model` 段,
> 内存占用与 safetensors 相当。
**不需要下载 Stable Diffusion 2.1 的权重。** SDMatte 虽以 SD 2.1 为骨架,但官方推理配置
(`configs/SDMatte.py` 中 `load_weight=False`)只用配置文件搭出网络结构,全部权重随后由
SDMatte 检查点覆盖。官方 HuggingFace 仓库本身也只发布 `.pth` 加若干 `config.json`,
不含任何 SD 权重。所需配置已随本节点一起分发,开箱即用、无需联网。
#### 参数说明
**SDMatte 加载器**
| 参数 | 说明 |
|---|---|
| `ckpt_name` | `models/SDMatte/` 下的权重文件 |
| `precision` | `fp32`(默认,与官方测试配置一致)/ `fp16`(省显存,但 SD 2.1 的 VAE 半精度下易溢出) |
| `device` | `auto` / `cpu` |
| `attention_slicing` | 默认开启。1024 下显存峰值从约 **15.5GB 降到 9.1GB**,实测速度反而略快,输出差异仅 1e-6 量级 |
> 显存参考(fp32 @ 1024,实测于 RTX 5090):开分片约 **9.1GB**,关分片约 **15.5GB**。
> 12GB 显存的卡请保持分片开启。
**SDMatte 精细抠图**
| 参数 | 说明 |
|---|---|
| `mask` | 指示抠哪个目标的提示掩码,**不必精确**,粗略覆盖主体即可 |
| `prompt_type` | 视觉提示类型,见下表 |
| `inference_size` | 默认 `1024`,与官方测试一致 |
| `is_transparent` | 玻璃、纱、烟雾等透明物体**务必打开** |
| `caption` | 目标物体的英文描述。**仅 `SDMatte.pth` 有效,`SDMatte_plus.pth` 请留空**,见下文 |
| `point_radius` | 仅 `point_mask` 生效。每个点晕开的高斯 sigma,默认 35 |
| `seed` | 仅 `point_mask` 生效(10 个点是随机取的) |
`prompt_type` 选择:
| 取值 | 含义 | 适用 |
|---|---|---|
| `bbox_mask` | 取掩码外接框作为提示 | **默认,官方测试脚本的主路径,通常最稳** |
| `mask` | 直接用掩码本身 | 已有较准的粗分割时 |
| `point_mask` | 在掩码内随机取 10 个点 | **仅 `SDMatte.pth` 支持**,见下文 |
| `auto_mask` | 不给定位信息 | 画面只有单一主体 |
#### ⚠ 两个权重的能力不同(实测)
官方 README 里,**SDMatte** 与 **SDMatte\***(即 `SDMatte_plus`)的训练集不同:
前者含 **RefMatte**(指代表达式抠图数据集,点提示与文本提示的来源),
后者用 **COCO-Matte** 替换了它。这导致 plus 版**不具备点提示与文本指代能力**:
| | `SDMatte.pth` | `SDMatte_plus.pth` |
|---|---|---|
| `bbox_mask` / `mask` / `auto_mask` | ✅ | ✅ |
| `point_mask` | ✅ MAD 0.0135 | ❌ **输出全黑**(max 仅 0.079) |
| `caption` 语义 | ✅ 填对小幅提升 | ❌ 无作用,填了反而更差 |
`caption` 实测(羊驼图,MAD 越低越好):
| caption | `SDMatte` | `SDMatte_plus` |
|---|---|---|
| `""`(留空) | 0.01120 | **0.01135** ← 最好 |
| `"alpaca"`(语义正确) | **0.01072** ← 最好 | 0.01160 ← 最差 |
| `"tree"`(语义错误) | 0.01111 | 0.01119 |
在 `SDMatte` 上,语义正确的描述确实更准;在 `plus` 上语义完全失效甚至反向,
说明它只是给 cross-attention 注入了噪声扰动,并非在理解文本。
**结论**:用 `SDMatte_plus.pth` 时保持 `caption` 留空、`prompt_type` 用 `bbox_mask`;
想用点提示或文本指代,请换 `SDMatte.pth`。节点在 `point_mask` 输出接近全黑时会打印警告。
#### 典型接法
```
加载图像 ──────────────┬──> SDMatte 精细抠图 ──> alpha (MASK)
│ ▲ └──> cutout (IMAGE)
任意分割节点 ──> mask ──┘ │
SDMatte 加载器 ───────────────────┘
```
`mask` 可以来自任何粗分割来源(SAM、rembg、手绘遮罩皆可)——SDMatte 的职责正是把粗糙边缘细化。
#### 实测数据
用官方效果图中的羊驼原图(绒毛边缘)跑本节点,与官方给出的 GT alpha 对比:
| 指标 | 数值 |
|---|---|
| MAD(平均绝对误差) | 0.0113 |
| MSE | 0.0026 |
| SAD | 0.807 千像素 |
(GT 取自官方效果图截图,含有损压缩与水印,故存在固有误差下限。)
各配置对输出的实际影响(透明玻璃杯,差异像素指偏差 > 0.05 的占比):
| 对照项 | 平均差 | 差异像素占比 |
|---|---|---|
| `inference_size` 1024 vs 512 | 0.082 | 32.4% |
| `is_transparent` 关 vs 开 | 0.059 | 25.0% |
| 官方 `[F,T,F]` vs 误用 `[T,T,T]` 条件分配 | 0.026 | 18.8% |
结论:**分辨率影响最大,建议保持 1024**;抠透明物体时 `is_transparent` 必须打开。
#### 与 ComfyUI-SDMatte 的横向实测
同一张图、同一份权重、同一台机器,对跑 [ComfyUI-SDMatte](https://github.com/flybirdxx/ComfyUI-SDMatte)
与本节点,以官方公布的 alpha 为参照:
| 实现 | 配置 | MAD ↓ |
|---|---|---|
| **本节点** | 官方 `configs/SDMatte.py`,bbox 提示,fp32 | **0.0113** |
| ComfyUI-SDMatte | 默认(trimap 提示 + `mask_refine`) | 0.0884 |
| ComfyUI-SDMatte | 关闭 `mask_refine` | 0.0885 |
**相差 7.8 倍**,且其输出肉眼可见地发灰、边缘晕开。
主因是**视觉提示类型**:官方 `configs/SDMatte.py` 固定 `aux_input="bbox_mask"`,
而其 `aux_input_list` 只含 `point_mask` / `bbox_mask` / `mask` —— **trimap 从未作为视觉提示参与训练**。
ComfyUI-SDMatte 传 `aux_input="trimap"`,把模型推到了没训练过的输入模式上,
且该分支的 `trimap_coords` 恒为 `[0,0,1,1]`,定位信息全部丢失。
开不开它的 `mask_refine` 几乎不影响这一结论(0.0884 vs 0.0885),说明问题不在后处理。
#### 实现要点
若与其它 SDMatte 实现效果对不上,按影响从大到小排查:
1. **视觉提示类型**(影响最大)。必须用官方训练过的 `bbox_mask` / `mask` / `point_mask`,
并传入真实的归一化坐标。用 trimap 当视觉提示是模型没见过的用法。
2. **UNet 配置来源**。SDMatte 在标准 SD 2.1 的 UNet 配置上额外定义了
`bbox_time_embed_dim` / `point_embeddings_input_dim` / `bbox_embeddings_input_dim` 三个字段。
误用原版 SD 2.1 的 `config.json` 会缺这些字段,只能猜默认值,猜错则相应权重被
`strict=False` 静默丢弃。本节点直接分发官方配置,并在缺字段时**直接报错而非猜测**。
3. **transformers 版本**。官方权重用 transformers 4.x 保存,`CLIPTextModel` 内部裹了一层
`text_model`;transformers 5.x 起该层被移除,导致 text_encoder 的 372 个权重键名对不上、
被整体静默丢弃、停留在随机初始化。本节点会按当前环境自动增删该前缀。
4. **条件分配**。官方 `use_encoder_hidden_states_list=[False, True, False]` 决定 UNet
下采样/中间/上采样三段各接收哪种条件,漏传会退化成 `[True, True, True]`。
实测单独影响不大(羊驼 MAD 0.01135 → 0.01148),透明物体上更明显。
5. **权重对齐校验**。本节点在加载后校验键的完整性,一旦有权重未被覆盖或未被使用就**中止并报错**。
这类问题不会让模型崩溃,只会让输出质量悄悄下降,是最难排查的一类,因此宁可停下也不放行。
6. 全程 fp32、1024 分辨率,且**不做任何启发式后处理**(不做阈值裁剪、对比度拉伸之类的"优化"),
输出即模型原始 alpha。
---
### 18. ZenMux API 连接 / ZenMux API Connector
**分类**: `Rui-Node🐶/AI模型🤖`
**功能描述**:
连接 [ZenMux](https://zenmux.ai) 聚合平台(OpenAI 兼容协议),一个节点即可调用其收录的**所有文本类模型**(Anthropic、OpenAI、Google、DeepSeek、Qwen 等 20 家厂商、130+ 模型)。支持文本生成与多模态图像理解(最多 6 张图)。
**特色功能**:
- **价格直接标在选项上**: 每个模型后缀形如 `[入$0.2/M 出$1.25/M]`,即输入/输出每百万 token 的美元价格,选型时一目了然
- **快速筛选**: 模型列表按「厂商/模型名」排序聚类,同厂商模型天然相邻;在下拉的搜索框输入厂商前缀(如 `qwen/`、`anthropic/`)即可只看该厂商的模型
- **离线可用的模型清单**: 模型与价格来自随包分发的 `zenmux/models_snapshot.json`;价格有变动时运行 `python zenmux/build_snapshot.py` 即可重新拉取更新
- **旧工作流兼容**: 价格快照更新后,旧工作流里保存的带旧价格标签仍能正确解析出模型 id,不会失效
- **单次消耗统计**: `usage_stats` 输出本次运行的 token 用量、输出字数与费用换算(按快照单价计算,汇率可调),格式:
```
token消耗,输入:1234,输出:567
输出文字数量:328
模型类型:openai/gpt-5.4-nano [入$0.2/M 出$1.25/M]
价格换算,美元:0.000955,人民币:0.006876
```
- **自动参数兼容**: 部分模型弃用或不支持某些采样参数(如 `claude-sonnet-5` 弃用 `temperature`、gpt-5 reasoning 系要求 `max_completion_tokens`)。节点会在收到相关 400 错误时**自动剔除或改名该参数并重试**,无需手动调整;剔除动作会打印到 ComfyUI 控制台。正常请求不受影响、无额外开销。
**输入参数**:
- `api_key` (STRING): ZenMux 平台的 API Key(在 zenmux.ai 控制台获取)
- `model` (选择): 模型(带价格标注),默认 `openai/gpt-5.4-nano`
- `system_prompt` (STRING): 系统提示词
- `user_prompt` (STRING): 用户提示词
- `seed` (INT): 随机种子
- `temperature` (FLOAT, 可选): 采样温度,默认 0.7,范围 0.0 ~ 2.0
- `top_p` (FLOAT, 可选): 核采样阈值,默认 1.0
- `max_tokens` (INT, 可选): 最大输出 token 数,默认 1024
- `image_1` ~ `image_6` (IMAGE, 可选): 多模态图像输入(所选模型需支持 image 输入)
- `detail` (选择, 可选): 图像分析细节等级,auto/low/high
- `image_max_size` (INT, 可选): 发送前图像最长边缩放上限,默认 1024
- `base_url` (STRING, 可选): API 地址,默认 `zenmux.ai/api/v1`(无需写 `https://`,节点会自动补全)
- `proxy_url` (STRING, 可选): HTTP/HTTPS 代理地址,如 `127.0.0.1:7890`
- `usd_to_cny` (FLOAT, 可选): 美元兑人民币汇率,默认 7.2,用于 `usage_stats` 的人民币换算,可按当日牌价调整
**输出**:
- `text` (STRING): 模型生成的文本内容
- `model_id` (STRING): 实际调用的模型 id(如 `openai/gpt-5.4-nano`),便于下游记录
- `usage_stats` (STRING): 单次运行的 token 消耗、输出文字数量(按字符计,含标点)与费用统计(四行文本,格式见上);请求失败时记为 0 消耗,token 数缺失或单价未知的项显示 `?`
**使用场景**:
- 一个 Key 试遍多家厂商的模型,横向对比效果与成本
- 按预算选型:价格就写在下拉列表里,直接挑便宜的
- 调用 Claude / GPT / Gemini / DeepSeek 等做文本生成或图像理解
---
### 19. Markdown转图片 / Markdown To Image
**分类**: `Rui-Node🐶/文本处理📝`
**功能描述**:
输入 Markdown 文本,输出按阅读器级排版渲染的图片(IMAGE)。视觉规范对标 GitHub / Typora:标题层级字号(2.0/1.5/1.25/1.0/0.875/0.85 倍正文)、H1/H2 底部分隔线、引用左竖条、代码块圆角底色 + 等宽字体 + 语言标签、表格圆角外框 + 表头加粗底色 + 斑马纹 + 列对齐、任务清单勾选框、彩色 Emoji。纯 PIL 实现,无额外依赖。
**支持的 Markdown 语法**:
标题 `#`~`######`、段落(单换行即硬换行)、**粗体**、*斜体*、`行内代码`、~~删除线~~、[链接]()、有序/无序/嵌套列表、任务清单 `- [x]`、引用 `>`(可嵌套)、围栏代码块、表格(`:---:` 对齐语法)、分割线 `---`;表格与正文中的 Emoji 以系统彩色字体渲染。
**输入参数**:
- `markdown` (STRING): Markdown 文本
- `size_preset` (选择): 常用尺寸快选(1080×1440 / 1080×1920 / 1080×1080 / 1920×1080 / A4 等),选 `custom` 时使用下方宽高
- `width` / `height` (INT): 精确尺寸(64~8192px,`custom` 时生效)
- `font` (选择): 字体,列表来自 `Ruinode/font` 目录(ttf/otf/ttc 均可,放入后刷新页面即出现在下拉;同族粗体文件如 `msyhbd` 会自动配对用于渲染粗体,无粗体文件时描边模拟)
- `theme` (选择): 浅色 / 深色 / 米色三套阅读器配色
- `body_size`、`h1_size` ~ `h6_size` (STRING, 可选): 各级字号,`auto`(默认)按输出尺寸二分搜索「恰好优雅填满画布」的字号,各级也可分别填数字精确指定
- `letter_spacing` (STRING, 可选): 字间距像素,默认 `auto`
- `line_spacing` (STRING, 可选): 行高倍数(如 `1.8`),默认 `auto`(正文 1.65)
- `max_chars_per_line` (STRING, 可选): 单行文字字数上限,达到即换行;默认 `auto`(按像素宽自然换行)
**输出**:
- `image` (IMAGE): 渲染结果,固定为所选宽高;内容超高时按现有字号裁剪并在控制台提示
**使用场景**:
- 将 LLM 输出的 Markdown(如 ZenMux 节点的 text)直接转成可分享的长图
- 生成小红书 / 公众号风格的图文卡片、A4 打印稿
- 工作流内把结构化报告(含表格、代码)落成图像资产
**⚠️ 重要:不要用 WAS 的「Text Multiline」节点喂 Markdown**
WAS Node Suite 的「Text Multiline」会把 `#` 开头的行**当注释删除**,标题行会凭空消失,还会做动态提示词替换。请改用本套件的 [多行文本框(原样输出)](#20-多行文本框原样输出--text-box-raw),或直接在本节点的 `markdown` 输入框里粘贴文本。
---
### 20. 多行文本框(原样输出) / Text Box (Raw)
**分类**: `Rui-Node🐶/文本处理📝`
**功能描述**:
把输入的多行文本**一字不动**输出为 STRING:不删注释行、不做动态提示词/通配符/token 替换。专门用来安全承载 Markdown、代码等格式敏感文本(WAS 的「Text Multiline」会把 `#` 开头的行当注释吃掉,喂 Markdown 时标题会消失)。
**输入参数**:
- `text` (STRING): 多行文本
**输出**:
- `text` (STRING): 与输入完全一致的文本
**使用场景**:
- 为 [Markdown转图片](#19-markdown转图片--markdown-to-image) 提供含 `#` 标题的原样文本
- 存放任何不希望被上游文本节点"加工"的内容
---
### 21. 满屏文字水印 / Full-Screen Text Watermark
**分类**: `Rui-Node🐶/图像调节🎨`
**功能描述**:
给输入图像铺满一层平铺的文字水印,常用于版权标注、样图防盗、批量打标。文字按**交错网格**平铺,整体旋转后从中心裁切与原图等大的区域,因此任意旋转角度下四角也都被水印覆盖,不留空白。支持中英文混排与多行文案(用换行分隔),逐字符绘制以支持字间距。批量图像逐张处理。
**输入参数**:
- `image` (IMAGE): 输入图像
- `text` (STRING, 多行): 水印文案,支持换行分隔的多行文本
- `font` (选择): 字体,列表来自 `Ruinode/font` 目录(ttf/otf/ttc,放入后刷新页面即出现,与 Markdown 节点共用同一套字体扫描)
- `font_size` (INT): 文字大小(像素),默认 48,范围 8~500
- `angle` (FLOAT): 水印整体旋转角度(度),默认 30,范围 -180~180
- `density` (FLOAT): 水印密度,综合控制**行间距与同行水印之间的间距**,值越大越密,默认 1.0,范围 0.1~5.0
- `letter_spacing` (INT): 字间距,单条文案内相邻字符的额外间距(像素,可为负),默认 0,范围 -20~200
- `opacity` (FLOAT): 水印透明程度,0=完全透明(原样返回),100=完全不透明,默认 35,范围 0~100
- `color` (STRING): 水印文字颜色,支持 `#RRGGBB` / `#RGB` / `"r,g,b"` / 常见英文色名(white、red、yellow…),默认 `#FFFFFF`
**输出**:
- `image` (IMAGE): 叠加水印后的图像
**使用场景**:
- 给出图 / 样片加满屏防盗水印
- 批量素材统一打上版权或"仅供参考"标注
---
### 22. FeyNobg 抠图 / FeyNobg Matting
**分类**: `Rui-Node🐶/抠图✂️`
**功能描述**:
全自动去背景抠图,**不需要任何提示**,输入图像直接输出 alpha。模型为 feyn 开源的 [FeyNobg](https://huggingface.co/feyninc/FeyNobg)(Apache-2.0),在 BiRefNet(CAAI AIR 2024)基础上扩展:Swin-Large 主干 + 梯度注意力 / 图像块注入 / 多尺度输入三项增强,原生 1024×1024 推理,权重约 1.05GB。
**与 [SDMatte 精细抠图](#17-sdmatte-精细抠图--sdmatte-interactive-matting) 的分工**:
- **FeyNobg**:全自动、一步出图、速度快,适合批量去背景(画面主体明确时首选)
- **SDMatte**:需要框/掩码提示指定目标,适合画面里有多个主体、要精确抠其中一个
**模型准备**:
首次运行会自动从 HuggingFace 下载到 `ComfyUI/models/nobg/FeyNobg`(约 1.05GB)。也可手动下载 `config.json`、`preprocessor_config.json`、`model.safetensors` 放入该目录。
**输入参数**:
- `image` (IMAGE): 输入图像
- `model_name` (选择): `models/nobg` 下的模型目录,未找到时自动下载
- `resolution` (选择): 推理分辨率,默认 **1024**(模型原生训练分辨率)。调低省显存但边缘变粗;调高不一定更好,可能出现结构断裂
- `precision` (选择): `fp32`(默认)/ `fp16`。**实测两者输出一致**(同图 alpha 均值均为 0.657),fp16 显存减半且明显更快,推荐优先用 fp16
- `device` (选择): `auto` / `cpu`
- `alpha_threshold` (FLOAT, 可选): 前景判定阈值,默认 0.5。见下方「主体半透明发灰怎么救」
- `alpha_softness` (FLOAT, 可选): 阈值两侧过渡带宽度,默认 **1.0 = 完全不处理**
- `keep_aspect_ratio` (BOOLEAN, 可选): 保持宽高比(等比缩放 + 边缘延展补边),默认关闭
- `invert_mask` (BOOLEAN, 可选): 反转 alpha,默认前景为白
**输出**:
- `alpha` (MASK): 抠图 alpha,值域 [0,1]
- `cutout` (IMAGE): 去背景图(黑底)。需要透明 PNG 时,把 `alpha` 接到 `JoinImageWithAlpha` 一类节点
**实测数据**(1139×1280 人物插画,RTX 显卡):
| 配置 | 耗时 | 前景占比 |
|:-----|-----:|--------:|
| fp32 @1024 | 12.4s(含首次加载) | 0.659 |
| fp16 @1024 | 2.4s | 0.659 |
| fp32 @768 | 2.2s | 0.656 |
发丝、飘带、细链条等高频细节均能完整分离,边缘为自然的半透明过渡而非硬边。
**主体「整片半透明发灰」怎么救**:
模型对拿不准的区域会输出 0.5 上下的中间值,表现为整个人物/物体呈半透明。模型本身**没有**开放任何控制该行为的参数(`use_gradient_attention` 等是训练时固化的架构参数,推理期不可调),因此节点在后处理层提供了一对色阶参数:
| alpha_threshold | alpha_softness | 效果 |
|:---------------:|:--------------:|:-----|
| 0.5 | 1.0 | **默认**,原样输出,一个像素都不动 |
| 0.35 | 0.3 | **推荐**,半透明像素占比 1.49% → 0.31%(降 79%),主体均值几乎不变 |
| 0.5 | 0.0 | 硬二值化,锯齿硬边,抠头发/玻璃慎用 |
原理是以 `threshold` 为中心、`softness` 为宽度取一段区间线性拉伸到 [0,1]:区间以下压成全透明,以上提成全不透明,区间内保留平滑过渡。默认参数下该区间恰好是 [0,1],等于恒等变换。
两点边界必须说明:
- **只对已有一定响应的区域有效**。模型压根没认出来的地方 alpha 接近 0,再降阈值也救不回来——那属于语义判断差异(BiRefNet-General 倾向保留画面全部前景,FeyNobg 更强调「找主要主体」),需要换模型或改用 SDMatte 指定目标。
- `softness` 越小,发丝等**真实**半透明细节损失越多,是一对权衡。
**长图形变**:模型固定吃 1024×1024,默认把图直接拉伸成正方形(与官方训练方式一致)。手机截图这类 1:2 以上的长图横向会被压到一半,可开 `keep_aspect_ratio` 改为等比缩放 + 边缘延展补边、推理后裁掉补边。实测 2.36:1 的图半透明占比 0.1192 → 0.1041。该选项与训练分布不同,属试验性,常规比例建议保持关闭。
**实现说明**(两个坑,都已在节点内处理):
1. **预处理依赖**:上游 `nobg` 的预处理模块继承 `transformers>=5.4` 的 `TorchvisionBackend`,而 ComfyUI 常见环境仍是 transformers 4.x,直接引入会报 `No module named 'transformers.image_processing_backends'`。本节点内嵌了 nobg 推理子集(`feynobg/`)并**重写了预处理**,数值规格与官方逐项对齐(1024 双线性抗锯齿缩放 + ImageNet 标准化;后处理先 sigmoid 再缩放),**无需升级 transformers**。同时绕开了上游 `AutoModel` 里会联网查 tags 的 `model_info()`,保证离线可用。
2. **权重键名不兼容(更隐蔽)**:FeyNobg 的权重用 transformers 5.x 导出,其 `SwinBackbone` 的模块命名与 4.x 不同(`bb.swin.*` 多一层、attention 从 `self.query/key/value` 重构为 `q/k/v_proj`、前馈层 `mlp.fc1/fc2` 对应 `intermediate.dense`/`output.dense`)。若不处理,958 个参数只有 405 个能对上,**整个 backbone 形同随机初始化——模型照样跑完不报错,但输出的 alpha 几乎全黑**(实测 max 0.02、mean 0.000)。节点内做了键名重映射(按环境自动判断是否需要),并**严格校验**:除确定性 buffer `relative_position_index` 与 backbone 末端未使用的 `bb.layernorm` 外,任何缺失/多余都直接报错中止,绝不接受静默劣化的结果。
---
### 23. Lucida 抠图 / Lucida Matting
**分类**: `Rui-Node🐶/抠图✂️`
**功能描述**:
全自动去背景,不需要任何提示。模型为 [Lucida](https://huggingface.co/egeorcun/lucida)(MIT),是 [BiRefNet_HR](https://huggingface.co/ZhengPeng7/BiRefNet_HR) 的微调版,训练目标是攻克多数开源抠图模型的短板:**伪装物体、透明材质(玻璃)、文字与 Logo、VFX 光效、插画**。权重约 885MB(220M 参数,Swin-Large 主干)。
作者在 203 图 9 类别基准上的 MAE(越低越好):
| 类别 | Lucida | 商业参考 |
|:-----|-------:|--------:|
| 文字 / Logo 保留 | **0.0091** | 0.0123 |
| 插画 | **0.0092** | — |
| 伪装物体 | **0.0270** | — |
| 印刷设计 / 贴纸 | **0.0235** | — |
| 总体 | **0.0257** | — |
**模型准备**:
首次运行自动下载到 `ComfyUI/models/lucida/lucida.safetensors`。也可手动下载仓库的 `model.safetensors`,改名为 `lucida.safetensors` 放入该目录。
**输入参数**:
- `image` (IMAGE): 输入图像
- `model_name` (选择): `models/lucida` 下的权重文件,未找到时自动下载
- `precision` (选择): `fp16`(默认)/ `fp32`
- `device` (选择): `auto` / `cpu`
- `alpha_threshold` / `alpha_softness` (FLOAT, 可选): 遮罩色阶,默认 (0.5, 1.0) 为恒等变换。用法同 [FeyNobg 节点](#22-feynobg-抠图--feynobg-matting)
- `keep_aspect_ratio` (BOOLEAN, 可选): 保持宽高比,默认关闭
- `invert_mask` (BOOLEAN, 可选): 反转 alpha
**输出**:
- `alpha` (MASK) / `cutout` (IMAGE,黑底)
**⚠ 没有分辨率选项**:模型内部 `Config.size=1024` 且 decoder 走 patch split,与 1024 输入绑定,因此不像 FeyNobg 那样可调分辨率。
**三个抠图节点怎么选**:
| 节点 | 特点 | 适用 |
|:-----|:-----|:-----|
| **Lucida** | 全自动,把半透明材质也算前景 | 文字/Logo、插画、玻璃、发光特效、伪装物体 |
| **FeyNobg** | 全自动,只找主要主体 | 常规主体照片,要求背景剥离干净 |
| **SDMatte** | 需框/掩码提示 | 画面里多个主体、只抠其中一个 |
**实测对比**(同图、同参数,本仓库两个全自动节点):
| 测试图 | Lucida 前景占比 | FeyNobg 前景占比 |
|:-------|---------------:|----------------:|
| 动漫插画(人物 + 云 + 栏杆) | 0.391 | 0.098 |
| 游戏场景图 | 0.395 | 0.378 |
| 人物插画 | 0.315 | 0.336 |
第一张图差异最大,肉眼核对后确认**不是精度高低,而是「前景」的定义不同**:FeyNobg 只抠出人物,云与栏杆全部排除;Lucida 除人物外还把**半透明的云判为前景**(灰度 alpha)并保留了栏杆——这与它专门训练透明材质的目标一致。所以两者是互补关系:要干净剥离主体用 FeyNobg,要保住文字/玻璃/光效等半透明元素用 Lucida。**建议在自己的素材上实测再定**,示例工作流已把两者并联便于对照。
⚠ `alpha_softness` 调小会把玻璃、发光这类**真实**半透明一并压实,而这正是 Lucida 的强项,务必按素材取舍。
**实现说明**:
模型代码(`birefnet.py` / `BiRefNet_config.py`,2250 行)内嵌在 `lucida/` 子包,**不使用 `trust_remote_code`**——那会在运行时从 HuggingFace 拉取并执行远程 Python 代码,ComfyUI 场景下既不该联网也不该执行随时可变的远程代码;内嵌后版本固定、可离线、可审计。构造时传 `bb_pretrained=False`,避免联网下载 Swin 的 ImageNet 预训练权重。预处理规格与 BiRefNet 系一致,直接复用 FeyNobg 节点那份已验证实现。权重加载同样做**严格校验**(除窗口尺寸推出的确定性 buffer 外,任何失配直接报错中止)。
---
### 24. 像素化 / Pixelate
**分类**: `Rui-Node🐶/图像调节🎨`
**功能描述**:
把普通图像转成**能直接当素材用的像素画**。与"马赛克滤镜"的区别在于:滤镜只是把画面涂成方块、输出仍是原尺寸大图;而像素游戏要的是**真实小分辨率、颜色数受控、边缘硬朗**的 sprite。纯 numpy/PIL 实现,无额外依赖、无需模型权重。
**三种模式**:
| 模式 | 用途 |
|:-----|:-----|
| 按目标宽度 | 普通图/照片/插画 → 像素画,给输出宽度即可(高度按比例自动算)|
| 按像素块大小 | 每 N×N 原像素合成一个像素,已知放大倍数时最精确 |
| **自动检测网格** | 探测图中隐含的像素网格并还原——**专治 AI 生成的伪像素图** |
第三种是重点:SD/Flux 生成的"像素风"图往往是 1024×1024,看着像素风,实际网格歪斜、边缘带抗锯齿、颜色成千上万,直接进引擎会糊。
**输入参数**:
- `image` (IMAGE) / `mask` (MASK, 可选): 接抠图节点的 alpha 会按同一网格降采样并二值化成硬边
- `mode` / `target_width` / `pixel_size`: 见上表
- `downsample` (选择): `主导色 dominant`(默认,取块内最多的颜色,**不会凭空造出新颜色**)/ `median` / `mean`(会糊边) / `center`
- `palette` (选择): `不量化` / `自适应 k-means`(CIELAB 空间聚类)/ `自适应 median cut` / `PICO-8 (16色)` / `Game Boy (4色绿)` / `黑白 1-bit` / `灰阶 4·8·16 级`
- `palette_size` (INT): 自适应调色板的颜色数。8~16 复古感强,32~64 细节更多
- `dither` (选择): `无` / `Bayer 2×2·4×4·8×8` / `Floyd-Steinberg` / `随机噪声`
- `output_scale` (INT): **1 = 真实像素尺寸(导出素材必须用 1)**;>1 仅为在 ComfyUI 里看清,放大是整数倍纯复制不插值
- `dither_strength` / `mask_threshold` / `seed` (可选)
**输出**: `image` (IMAGE) / `mask` (MASK) / `info` (STRING,含检测到的网格与置信度)
**方案选型(研究后的结论)**:
[Pixel Snapper](https://hugo-dz.itch.io/pixel-snapper)(Sprite Fusion,MIT)解决的是「伪像素图 → 完美像素图」,思路是检测网格 + 按主导色重采样;而「普通图 → 像素画」是另一个问题,核心在降采样方式与调色板量化。本节点把两条路做进同一节点,算法为自研实现。网格检测按公开研究的要点处理了两类经典误判:
- **谐波(八度)错误**:2s 与 s 得分往往接近,容易把 2 倍大小当真值 → 取得最高分后回查其真约数(octave killer)
- **内容周期冒充像素周期**:画面里重复的纹理/花纹也形成周期 → 真网格对相位极其敏感、内容周期则不敏感,把「最佳相位与最差相位的分差」并入评分(anti-phase)
评分用**单元内方差**而非相邻像素差分:差分对模糊极敏感,而 AI 伪像素图的边界都带抗锯齿,尖峰被摊平后压不住内容周期(开发中实测:4 像素的网格被判成 24~28)。改用组内方差后,过大的 s 会因单元跨越多个真实色块导致方差爆掉而被天然压制。
**实测数据**:
| 测试项 | 结果 |
|:-------|:-----|
| 干净放大图(k=2~16,各 3 组) | **27/27 全对,零八度错误** |
| 退化图(模糊+噪点,模拟 AI 伪像素图) | 10/15 |
| 非方形网格(9×6)、相位偏移 (3,5) | 全部正确 |
| 普通插画(无网格) | 正确判定为"未检出" |
| **端到端还原**(32×32 放大 10 倍 + 模糊噪点) | **还原回 32×32,与真值 MAE 0.0049** |
| 完美像素校验(8× 放大抽样 == 1× 输出) | **True**(整数倍纯复制,无插值) |
⚠ 自动检测对干净放大图几乎必中,对模糊严重的图约 2/3 命中率。`info` 输出会给出检测到的网格与置信度,结果不对时改用「按像素块大小」手动指定即可。
---
### 25. 八方向序列拆分 / 8-Direction Sprite Split
**分类**: `Rui-Node🐶/图像调节🎨`
**功能描述**:
用于 **8 方向行走动画** 制作管线:把每帧都排布着 8 个朝向的雪碧图序列,一次拆成 8 条各自独立、可直接成片的动画序列,并完成方向编号与分组。
**完整管线与分工**:
| 步骤 | 由谁完成 |
|:-----|:---------|
| 角色图 → 八方向静态图 | GPTimage2 / Holopix Universal Edit 等 |
| 静态图 → 循环行走视频 | Seedance 首尾帧等 |
| 视频 → 序列帧 | 从文件读用 VHS「Load Video」;**接在视频生成节点后面用原生「Get Video Components」** |
| 抽帧(降帧率)| VHS「Select Every Nth Image」|
| 抠图(提供语义级 alpha)| Lucida / BiRefNet 等 |
| **拆分 + 编号 + 分组 + 8 队列输出** | **本节点** |
| 8 组透明 PNG 序列帧 | `SaveImage`(4 通道输入会自动存成 RGBA)|
| 8 个透明 webm | VHS「Video Combine」,`format=video/webm` + `pix_fmt=yuva420p` |
整条链路只有拆分环节是缺失的,其余全部复用成熟实现。
**两个示例工作流**:
- [八方向行走动画.json](example_workflow/八方向行走动画.json):从**已有视频文件**出发(VHS Load Video)
- [角色图到八方向行走动画(一体化).json](example_workflow/角色图到八方向行走动画(一体化).json):**从角色图一路到成品**,把生图、生视频、拆分、导出串成一条链
一体化工作流的关键是打通 `VIDEO → IMAGE`:视频生成节点输出的是 ComfyUI 的 `VIDEO` 类型,而 VHS「Load Video」只能从文件读、接不上。用 ComfyUI **原生的「Get Video Components」**(`image/video` 分类)即可,输入 VIDEO、输出 images/audio/fps,不需要装任何额外插件。
⚠️ **帧率两处必须匹配**:Seedance 出的是 24fps,抽帧间隔与输出帧率要对应,否则 webm 播放速度不对。
`select_every_nth=3` ↔ `frame_rate=8`;要 12fps 就用 `2` ↔ `12`;要全量 24fps 就用 `1` ↔ `24`。
**输入参数**:
- `images` (IMAGE): 视频转出的序列帧
- `masks` (MASK, 可选): **上游抠图节点的遮罩,强烈建议接上**(见下方「透明通道怎么来」)
- `grid_cols` / `grid_rows` / `empty_cells`: 网格布局。3×3 中间留空即 `empty_cells=4`(序号行优先、从 0 开始)
- `direction_names` (STRING): 按「跳过空格后的先后顺序」命名,默认 `SW,S,SE,W,E,NW,N,NE`,对应行 1 面向观众、行 3 背对观众的排布
- `bg_mode` / `bg_threshold`: 透明通道来源,见下
- `edge_shrink` / `decontaminate`: 治白边,见下
- `fragment_threshold` (FLOAT): 清掉面积不足主体这一比例的连通碎片
- `expand_beyond_cell` (BOOLEAN): **务必开启**,允许角色超出格子边界
- `auto_crop` / `crop_padding`: 按内容裁剪
**透明通道怎么来(关系到成品质量,别用默认凑合)**:
| bg_mode | 原理 | 代价 |
|:--------|:-----|:-----|
| **已带透明通道**(默认推荐)| 用上游 Lucida / FeyNobg 的语义级 alpha | 需要跑模型 |
| 白底转透明 | 纯颜色阈值 + 边缘连通性 | **角色身上的白衣服会被啃出破洞** |
| 不处理 | 输出不透明(仍按角色范围裁剪不切断)| — |
颜色阈值法的死穴在于它按「离白色多远」估 alpha,白衬衫本身就接近白、alpha 天生偏低,一旦收边压白边,衬衫就被啃穿。实测同一素材、同等白边水平下:
| 方案 | 白边强度 | 主体被啃面积 |
|:-----|--------:|-----------:|
| 颜色阈值法(收边 0.35)| 0.0261 | 0.0373 |
| **Lucida alpha(收边 0.2)** | **0.0256** | **0.0242(少 35%)** |
Lucida 一次就能识别整张雪碧图的全部 8 个角色(各格前景占比 0.18~0.24,中间空格 0.002),肉眼比对:模型 alpha 的白衬衫完好,阈值法的衬衫上布满背景色斑块。
**治白边的两个参数**:
- `edge_shrink`(主力):把边缘那圈「几乎全是背景」的半透明像素收掉。白底素材的边缘像素本就掺了白,不收掉贴到深色背景就发白。实测白边强度:**0 → 0.048;0.2 → 0.026;0.5 → 0.016**。配模型 alpha 用 0.15~0.25,配阈值法要 0.35 以上
- `decontaminate`(辅助):颜色反溢出,按 `观察色 = 前景×a + 白×(1-a)` 反解真正的前景色。**单独用只改善约 3%**(因为观察色本身已经太白,反解出来还是白),必须和收边配合
**输出**: `dir_1` ~ `dir_8` (IMAGE,**4 通道 RGBA**) + `info` (STRING)
**锚点对齐:让 8 个方向尺寸统一、切换朝向不跳**
做游戏素材时这一步是刚需。不开对齐时,每个方向各按自己的内容裁剪,8 个方向出 8 种尺寸,角色在各自画面里的位置也不一致——游戏里切换朝向角色就会跳一下。人工做法是「一帧一帧手动对位置」,本节点把它自动化了:
| 参数 | 说明 |
|:-----|:-----|
| `align_mode` | 锚点对齐·统一画布(默认)/不对齐 |
| `anchor_type` | **脚底中心**(默认)/包围盒底边中心/包围盒中心 |
| `align_scope` | **逐帧对齐·脚底钉死**(默认)/按方向统一平移 |
**为什么锚点取「脚底中心」而不是包围盒中心**:角色站在地面上,脚底才是它在世界里的位置;而斗篷、披风、手杖会把包围盒拽向一侧。所以 y 取最低的不透明行,x 取**底部窄带的水平质心**——那些外挂物基本不会垂到脚底,走路时两脚一前一后,窄带质心正好落在两脚之间,也就是人真正站立的点。
**实测**(97 帧真实素材):
| | 输出尺寸 | 各方向锚点散布 | 同方向跨帧位移 |
|:---|:---|---:|---:|
| 不对齐 | 8 种各不相同 | x **48.9px** / y **27px** | — |
| 按方向统一平移 | 统一 267×372 | x 7.1px / y 4px | 13~23px(保留摆动)|
| **逐帧对齐(默认)** | **统一 284×367** | **x 0.76px / y 0px** | ~1px |
默认选逐帧对齐,是因为行走循环本就该原地播放、位移交给游戏代码,sprite 内部不该有整体漂移;而 AI 生成的视频往往有(实测同方向跨帧漂移达 22px)。角色本就该有前后摆动的动作(挥剑、跳跃)则改用「按方向统一平移」。
`info` 输出会给出**统一画布尺寸、锚点坐标、以及 Unity/Godot 的归一化 pivot**(左下为原点),例如:
```
统一画布 267×372,锚点(脚底中心)位于 (144.5, 346.0)
Unity/Godot 归一化 pivot(左下为原点):(0.5411, 0.0699)
```
把那个 pivot 填进引擎的 Sprite 设置,8 个方向就能共用同一套坐标。
**三个关键设计**:
1. **用固定网格而非连通区域拆分**(本仓库的[素材拆分](#14-素材拆分--sprite-splitter)节点)。连通区域按包围盒排序,角色走动时位置浮动,一旦跨过排序行界方向就会错乱——上百帧里错一帧整条动画就废了;且每个 sprite 按各自 bbox 裁剪、尺寸不一,无法合成视频。固定网格没有这两个问题。(连通区域拆分依然更适合单张静态合图,两者各有用途。)
2. **白底转透明用边缘连通性判断**。角色常穿白衣服,按亮度阈值一刀切会把白衬衫一起掏空。这里只把**与画面边缘相连**的白色判为背景,被角色包围的白色一律保留。
3. **裁剪框取全序列并集**。逐帧各自裁剪会导致尺寸不一且角色在帧间跳动;取并集则整条序列尺寸一致、位置连贯。
**实测**(97 帧 834×1112 的真实素材):
| 项目 | 结果 |
|:-----|:-----|
| 拆分耗时 | 约 4 秒,8 方向 × 97 帧 |
| 输出尺寸 | 150×335 ~ 206×326,方向内完全一致 |
| 方向稳定性 | 跨帧内容重心极差 0.5~12 px(走路摆动的正常范围,无跳变)|
| 碎片清理效果 | E 方向 172×370 → 150×335,重心极差 8.0 → **0.5 px** |
| webm 透明 | 导出后回读**透明像素占比 0.635**,与素材一致 |
⚠️ **验证 webm 透明时容易被误导**:alpha 存放在 WebM 的独立边带里,`ffprobe` 看主流会显示 `yuv420p`,用 ffmpeg 默认解码回读也会得到全不透明——这是**内置 vp9 解码器不处理 alpha 边带**所致,并非文件丢了透明。需显式加 `-c:v libvpx-vp9` 解码才能读到。播放器与 Unity/Godot 走的是 libvpx,能正确读取。
---
### 26. 越光 API 连接 / YueGuang API Connector
**分类**: `Rui-Node🐶/AI模型🤖`
**功能描述**:
通过越光(Nebula)聚合平台调用其收录的文本类模型。OpenAI 兼容协议,chat 端点 `https://llm.ai-nebula.com/v1/chat/completions`。参数、输出与容错行为与 [ZenMux 节点](#18-zenmux-api-连接--zenmux-api-connector) 保持一致,便于两者互换。
**模型清单(25 个,价格单位 USD / 百万 token)**:
| 厂商 | 模型 | 输入 | 输出 |
|:-----|:-----|-----:|-----:|
| OpenAI | gpt-5.6-sol | 4.75 | 5.00 |
| | gpt-5.6-terra | 2.375 | 2.50 |
| | gpt-5.6-luna | 0.95 | 1.00 |
| | gpt-4.1 / gpt-4.1-mini | 2.00 / 0.40 | 8.00 / 1.60 |
| | gpt-4o / gpt-4o-mini | 2.50 / 0.15 | 10.00 / 0.60 |
| | o4-mini / o3-mini | 1.10 | 4.40 |
| Anthropic | claude-opus-5 | 5.00 | 5.00 |
| | claude-opus-4-7 / 4-6 | 15.00 | 75.00 |
| | claude-sonnet-5 | 2.00 | 2.00 |
| | claude-sonnet-4-6 | 3.00 | 15.00 |
| | claude-haiku-4-5-20251001 | 0.80 | 4.00 |
| | claude-fable-5 | 3.00 | 15.00 |
| DeepSeek | deepseek-v4-pro | 2.19 | 8.76 |
| | **deepseek-v4-flash**(默认)| **0.10** | **0.30** |
| | deepseek-r1-250528 | 0.55 | 2.19 |
| | deepseek-v3-250324 | 0.27 | 1.10 |
| Kimi | kimi-k3 | 2.86 | 2.86 |
| | kimi-k2.7-code / k2.6 / k2.5 / k2-thinking | 1.00 | 4.00 |
**输入参数**: 与 ZenMux 节点相同——`api_key`、`model`(下拉带价签)、`system_prompt`、`user_prompt`、`seed`,以及可选的 `temperature`、`top_p`、`max_tokens`、`image_1`~`image_6`、`detail`、`image_max_size`、`base_url`、`proxy_url`、`usd_to_cny`。
**输出**: `text` / `model_id` / `usage_stats`(五行:token 消耗、输出字数、厂商、模型与单价、美元与人民币费用)
**与 ZenMux 节点的三点差异**:
1. **模型清单内置,不做在线快照**。越光没有可枚举的模型接口,清单与价格来自官方规范文档,直接写在 `yueguang/model_registry.py` 里——少一个联网环节,也不会因拉取失败导致下拉变空。价格变动时改那张表即可。
2. **model id 不带厂商前缀**(是 `gpt-4o` 而非 `openai/gpt-4o`)。下拉里同厂商靠排序聚在一起,搜索时输 `gpt` / `claude` / `deepseek` / `kimi` 过滤。
3. 默认模型是全表最便宜的 `deepseek-v4-flash`($0.10/$0.30),官方示例也用它,默认值便宜可避免误触发时产生意外费用。
**沿用的实战经验**:
- `base_url` 默认值**不带 `://`**——ComfyUI 前端会吞掉文本框里的协议片段(本仓库为此修过多次),协议由后端自动补全
- **自适应参数重试**:部分模型弃用 `temperature`、或要求用 `max_completion_tokens` 取代 `max_tokens`,命中这类 400 时会剔除/改名后自动重试,正常请求零额外开销
- `VALIDATE_INPUTS` 宽松放行:价格表更新后旧工作流里保存的标签不再逐字匹配,但只要能解析出 model id 就放行,不会让整个工作流失效
---
### 27. 半透明抠图 / Unmult Matting
**分类**: `Rui-Node🐶/抠图✂️`
**功能描述**:
纯数学去底,等效 After Effects 的 Unmult。纯色背景上的合成图满足 `C = αF + (1-α)B`,背景色 B 已知时可**反解**出前景色 F 与透明度 α。不需要模型推理,速度快、结果是精确解,且能真实保留半透明层次——**这是语义抠图模型给不了的**。
**输入参数**:
- `image` (IMAGE): 待去底图像,支持批量(序列帧/视频帧逐帧处理)
- `bg_color` (STRING): 要去除的背景色,`#RRGGBB`。常用 `#000000` / `#FFFFFF` / `#00FF00` / `#FF00FF`
- `黑点` (FLOAT, 滑块): 低于此值的 alpha 归零,用于清除背景残留噪点。调太高会丢边缘细节
- `白点` (FLOAT, 滑块): 高于此值的 alpha 归一,用于让主体更实。调太低会让边缘硬化
- `主体保护` (BOOLEAN): 是否采纳 `subject_mask`。**关闭时即便已连线也完全不采纳**,等同纯 Unmult——想对比「有无 AI 介入」时拨这个开关即可,不必拔线
- `subject_mask` (MASK, 可选): 接抠图节点输出的 alpha,节点执行 `max(unmult_α, subject_mask)` 合并
后两项用中文参数名 + `display: slider`,界面上就是两条滑块,与 LayerStyle 的 BiRefNet Ultra 观感一致。函数内部用 `**kwargs` 接收(中文名不能直接做函数形参),并兼容旧的 `alpha_low`/`alpha_high` 调用。
**输出**: `rgba_image` (IMAGE,4 通道) / `alpha` (MASK)
**实测(构造已知合成图反推,验证还原精度)**:
| 场景 | alpha 平均误差 | 前景色平均误差 |
|:-----|-------------:|-------------:|
| 发光素材 @ 黑底 | **0.0000** | **0.0000** |
| 发光素材 @ 白底 | **0.0000** | **0.0000** |
| 发光素材 @ 绿幕 | **0.0000** | **0.0000** |
数学上是精确解,三种底色都能完美还原。
**⚠ 适用边界与破解办法**:
| 素材 | 纯 Unmult | 接 `subject_mask` 后 |
|:-----|:---------|:--------------------|
| 光效、火焰、烟雾、粒子、UI 特效 | ✅ 最佳选择,半透明层次完整保留 | 一般不需要 |
| 绿幕/品红等**与素材反差大**的底色 | ✅ 实体素材也能扣干净 | 一般不需要 |
| **黑底 + 暗色实体** | ❌ **暗部会被当成背景扣掉** | ✅ **已解决** |
实测同一个实体素材(alpha 真值恒为 1,下半部分接近纯黑):
| 条件 | 暗部还原 alpha |
|:-----|-------------:|
| 黑底,不接 mask | **0.080** ← 黑头发、深色衣服、鞋子被扣穿 |
| 黑底,接 mask 且「主体保护」启用 | **1.000** ✅ |
| 黑底,接 mask 但「主体保护」关闭 | 0.080(与不接完全一致,开关确实生效)|
| 绿幕,不接 mask | 0.940 ✓ 本来就正常 |
根因是黑底 unmult 本质在用"亮度当不透明度",这对发光物成立、对实体不成立。**破法是接一路语义抠图(Lucida / FeyNobg / BiRefNet)的 alpha 进 `subject_mask`**:主体区域强制不透明,主体之外仍走 Unmult 的精确半透明。两者各取所长——语义模型负责"哪里是主体",Unmult 负责"边缘有多透"。
**四个抠图节点怎么选**:
| 节点 | 原理 | 适用 |
|:-----|:-----|:-----|
| **Unmult** | 纯数学反解 | 纯色底的光效/火焰/粒子;绿幕素材 |
| **Lucida** | 语义模型 | 文字/Logo、插画、玻璃、伪装物体 |
| **FeyNobg** | 语义模型 | 常规主体照片,要求背景剥离干净 |
| **SDMatte** | 语义模型 + 提示 | 画面里多个主体、只抠其中一个 |
---
## 🐕 关于 Rui-Node🐶
Rui-Node🐶 致力于为 ComfyUI 用户提供实用、高效的节点工具集。🐶 是我们的项目标志,代表着忠诚、友好和可靠。
## 📄 许可证
本项目遵循开源协议,欢迎使用和贡献。
---
**Happy Creating with Rui-Node🐶!** 🎨✨