feat: 新增 SDMatte 精细抠图节点,实测复现官方效果
基于 SDMatte(vivo 相机研究院,ICCV 2025)的交互式抠图节点, 擅长发丝、绒毛、玻璃、烟雾等常规抠图模型处理不好的边缘。 实现要点: - 严格照搬官方 configs/SDMatte.py 的推理配置(bbox 视觉提示、fp32、1024 分辨率), 不做任何启发式后处理,输出即模型原始 alpha - 内置官方 LongfeiHuang/SDMatte 的配置文件,无需下载 SD 2.1 权重,也无需联网。 官方 load_weight=False 只用 config 搭骨架,全部权重由 checkpoint 覆盖; 原版 SD 2.1 的 config 缺 bbox_time_embed_dim 等三个专有字段,缺字段时直接报错而非猜测 - 同时支持官方 .pth(12.1GB)与社区 .safetensors(5.19GB)。两者模型权重实测 逐像素完全相同,pth 多出的 6.5GB 是 detectron2 的优化器状态;读 pth 时以受限 Unpickler 只解析 model 段,内存占用与 safetensors 相当 - 自动适配 transformers 5.x 移除 text_model 包装层导致的键名漂移, 避免 text_encoder 的 372 个权重被静默丢弃 - 加载后校验 1316 个张量全部对齐,有任何未覆盖/未使用的权重即中止报错 - 默认开启注意力分片,1024 下显存峰值由约 15.5GB 降至 9.1GB,速度反而略快 实测(官方效果图中的羊驼,对比官方公布 alpha):MAD=0.0113。 同图同权重下 ComfyUI-SDMatte 为 MAD=0.0884,相差 7.8 倍,主因是其 aux_input="trimap" —— 官方 aux_input_list 只含 point_mask/bbox_mask/mask, trimap 从未作为视觉提示参与训练,且该分支坐标恒为 [0,0,1,1]、定位信息丢失。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
1e42521fec
commit
e1a575fcda
@@ -23,6 +23,7 @@ Rui-Node🐶 是一个功能丰富的 ComfyUI 节点集合,提供图像处理
|
||||
|
||||
### 🤖 AI模型类
|
||||
- [千问编辑图像生成 / Qwen Edit Image Generation](#4-千问编辑图像生成--qwen-edit-image-generation)
|
||||
- [SDMatte 精细抠图 / SDMatte Interactive Matting](#17-sdmatte-精细抠图--sdmatte-interactive-matting)
|
||||
|
||||
### 📝 文本处理类
|
||||
- [镜头分词器 / Shot Splitter](#5-镜头分词器--shot-splitter)
|
||||
@@ -537,6 +538,151 @@ Rui-Node🐶 是一个功能丰富的 ComfyUI 节点集合,提供图像处理
|
||||
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` | 可选文本描述,留空即官方默认行为 |
|
||||
| `point_radius` | 仅 `point_mask` 生效,默认 35 |
|
||||
|
||||
`prompt_type` 选择:
|
||||
|
||||
| 取值 | 含义 | 适用 |
|
||||
|---|---|---|
|
||||
| `bbox_mask` | 取掩码外接框作为提示 | **默认,官方测试脚本的主路径,通常最稳** |
|
||||
| `mask` | 直接用掩码本身 | 已有较准的粗分割时 |
|
||||
| `point_mask` | 在掩码内随机取 10 个点 | 复现论文的点提示实验 |
|
||||
| `auto_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。
|
||||
|
||||
---
|
||||
|
||||
## 🐕 关于 Rui-Node🐶
|
||||
|
||||
Rui-Node🐶 致力于为 ComfyUI 用户提供实用、高效的节点工具集。🐶 是我们的项目标志,代表着忠诚、友好和可靠。
|
||||
|
||||
Reference in New Issue
Block a user