Files
rui40000-RUI-Nodes/example_workflow/八方向行走动画.json
T
rui40000andClaude Opus 4.8 2a6fd42c57 fix: 治理抠图白边——推荐改用模型 alpha,新增收边与颜色反溢出
用户反馈边缘一圈白边。诊断:按 alpha 分层统计 RGB 均值,
alpha 0.05~0.3 的边缘像素 RGB 高达 0.989(角色本体只有 0.363),
证实边缘掺了背景白 —— 我只设了 alpha 却没动 RGB。

新增两个参数:
- decontaminate 颜色反溢出,按 观察色=前景×a+白×(1-a) 反解前景色
- edge_shrink 把边缘那圈几乎全是背景的半透明像素收掉

实测白边强度(合成到深绿底,量主体外缘3像素环带比背景亮多少):
  都关闭 0.0483 / 只反溢出 0.0466 / 只收边 0.0283 / 两者 0.0261 / 狠收边 0.0164
即:收边是主力(-41%),反溢出单独几乎无效(-3.5%)——因为观察色
本身就太白,反解出来还是白。这点如实写进 tooltip 与 README。

但收边暴露了颜色阈值法的死穴:它按「离白色多远」估 alpha,
白衬衫接近白、alpha 天生偏低,收边会把衬衫啃出破洞(肉眼可见背景
透过衣服)。这不是调参能解决的,故改推荐语义级抠图:

- bg_mode 默认改为「已带透明通道(推荐·上游接抠图节点)」,
  选项名直接把取舍写进去,旧选项名保留在 _BG_ALIAS 里做兼容
- edge_shrink 默认 0.2(配模型 alpha 够用;配阈值法需 0.35+)
- 示例工作流插入 Lucida 节点:加载视频 → Lucida → 拆分(masks 输入)

实测 Lucida 一次识别整张雪碧图全部 8 个角色(各格前景占比 0.18~0.24,
中间空格 0.002);同等白边水平下主体被啃面积比阈值法少 35%,白衬衫完好。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-30 10:23:54 +08:00

1163 lines
20 KiB
JSON
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.
{
"id": "5f8c3d21-7b94-4e06-a1d8-9c2e4b7f350a",
"revision": 0,
"last_node_id": 20,
"last_link_id": 19,
"nodes": [
{
"id": 1,
"type": "VHS_LoadVideo",
"pos": [
-2680,
340
],
"size": [
340,
480
],
"flags": {},
"order": 0,
"mode": 0,
"inputs": [],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
1,
2
]
},
{
"name": "frame_count",
"type": "INT",
"links": []
},
{
"name": "audio",
"type": "AUDIO",
"links": []
},
{
"name": "video_info",
"type": "VHS_VIDEOINFO",
"links": []
}
],
"properties": {
"Node name for S&R": "VHS_LoadVideo"
},
"widgets_values": {
"video": "八方向行走.mp4",
"force_rate": 24,
"custom_width": 0,
"custom_height": 0,
"frame_load_cap": 0,
"skip_first_frames": 0,
"select_every_nth": 1
},
"color": "#232",
"bgcolor": "#353",
"title": "① 加载视频(force_rate 设帧率)"
},
{
"id": 2,
"type": "RuiLucida",
"pos": [
-2270,
340
],
"size": [
340,
250
],
"flags": {},
"order": 1,
"mode": 0,
"inputs": [
{
"name": "image",
"type": "IMAGE",
"link": 1
}
],
"outputs": [
{
"name": "alpha",
"type": "MASK",
"links": [
3
]
},
{
"name": "cutout",
"type": "IMAGE",
"links": []
}
],
"properties": {
"aux_id": "rui40000/Ruinode",
"Node name for S&R": "RuiLucida"
},
"widgets_values": [
"lucida.safetensors",
"fp16",
"auto",
0.5,
1.0,
false,
false
],
"color": "#232",
"bgcolor": "#353",
"title": "② Lucida 抠图(一次抠整张,8 个角色都能识别)"
},
{
"id": 3,
"type": "RuiEightDirSplit",
"pos": [
-1860,
340
],
"size": [
380,
400
],
"flags": {},
"order": 2,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 2
},
{
"name": "masks",
"type": "MASK",
"link": 3
}
],
"outputs": [
{
"name": "dir_1",
"type": "IMAGE",
"links": [
4,
5
]
},
{
"name": "dir_2",
"type": "IMAGE",
"links": [
6,
7
]
},
{
"name": "dir_3",
"type": "IMAGE",
"links": [
8,
9
]
},
{
"name": "dir_4",
"type": "IMAGE",
"links": [
10,
11
]
},
{
"name": "dir_5",
"type": "IMAGE",
"links": [
12,
13
]
},
{
"name": "dir_6",
"type": "IMAGE",
"links": [
14,
15
]
},
{
"name": "dir_7",
"type": "IMAGE",
"links": [
16,
17
]
},
{
"name": "dir_8",
"type": "IMAGE",
"links": [
18,
19
]
},
{
"name": "info",
"type": "STRING",
"links": []
}
],
"properties": {
"aux_id": "rui40000/Ruinode",
"Node name for S&R": "RuiEightDirSplit"
},
"widgets_values": [
3,
3,
"4",
"SW,S,SE,W,E,NW,N,NE",
"已带透明通道(推荐·上游接抠图节点)",
0.92,
0.2,
1.0,
1.0,
0.05,
true,
true,
16
],
"color": "#232",
"bgcolor": "#353",
"title": "③ 八方向拆分(拆分+编号+分组)"
},
{
"id": 4,
"type": "VHS_VideoCombine",
"pos": [
-1400,
-160
],
"size": [
320,
460
],
"flags": {},
"order": 3,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 4
},
{
"name": "audio",
"type": "AUDIO",
"link": null
},
{
"name": "meta_batch",
"type": "VHS_BatchManager",
"link": null
},
{
"name": "vae",
"type": "VAE",
"link": null
}
],
"outputs": [
{
"name": "Filenames",
"type": "VHS_FILENAMES",
"links": []
}
],
"properties": {
"Node name for S&R": "VHS_VideoCombine"
},
"widgets_values": {
"frame_rate": 24,
"loop_count": 0,
"filename_prefix": "8dir/1_SW",
"format": "video/webm",
"pix_fmt": "yuva420p",
"crf": 20,
"save_metadata": true,
"trim_to_audio": false,
"pingpong": false,
"save_output": true
},
"color": "#232",
"bgcolor": "#353",
"title": "1. SW → 透明 webm"
},
{
"id": 5,
"type": "SaveImage",
"pos": [
-1040,
-160
],
"size": [
300,
300
],
"flags": {},
"order": 4,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 5
}
],
"outputs": [],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.3.49",
"Node name for S&R": "SaveImage"
},
"widgets_values": [
"8dir_frames/1_SW/SW"
],
"title": "1. SW → 透明 PNG 序列帧"
},
{
"id": 6,
"type": "VHS_VideoCombine",
"pos": [
-1400,
170
],
"size": [
320,
460
],
"flags": {},
"order": 5,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 6
},
{
"name": "audio",
"type": "AUDIO",
"link": null
},
{
"name": "meta_batch",
"type": "VHS_BatchManager",
"link": null
},
{
"name": "vae",
"type": "VAE",
"link": null
}
],
"outputs": [
{
"name": "Filenames",
"type": "VHS_FILENAMES",
"links": []
}
],
"properties": {
"Node name for S&R": "VHS_VideoCombine"
},
"widgets_values": {
"frame_rate": 24,
"loop_count": 0,
"filename_prefix": "8dir/2_S",
"format": "video/webm",
"pix_fmt": "yuva420p",
"crf": 20,
"save_metadata": true,
"trim_to_audio": false,
"pingpong": false,
"save_output": true
},
"title": "2. S → 透明 webm"
},
{
"id": 7,
"type": "SaveImage",
"pos": [
-1040,
170
],
"size": [
300,
300
],
"flags": {},
"order": 6,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 7
}
],
"outputs": [],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.3.49",
"Node name for S&R": "SaveImage"
},
"widgets_values": [
"8dir_frames/2_S/S"
],
"title": "2. S → 透明 PNG 序列帧"
},
{
"id": 8,
"type": "VHS_VideoCombine",
"pos": [
-1400,
500
],
"size": [
320,
460
],
"flags": {},
"order": 7,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 8
},
{
"name": "audio",
"type": "AUDIO",
"link": null
},
{
"name": "meta_batch",
"type": "VHS_BatchManager",
"link": null
},
{
"name": "vae",
"type": "VAE",
"link": null
}
],
"outputs": [
{
"name": "Filenames",
"type": "VHS_FILENAMES",
"links": []
}
],
"properties": {
"Node name for S&R": "VHS_VideoCombine"
},
"widgets_values": {
"frame_rate": 24,
"loop_count": 0,
"filename_prefix": "8dir/3_SE",
"format": "video/webm",
"pix_fmt": "yuva420p",
"crf": 20,
"save_metadata": true,
"trim_to_audio": false,
"pingpong": false,
"save_output": true
},
"title": "3. SE → 透明 webm"
},
{
"id": 9,
"type": "SaveImage",
"pos": [
-1040,
500
],
"size": [
300,
300
],
"flags": {},
"order": 8,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 9
}
],
"outputs": [],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.3.49",
"Node name for S&R": "SaveImage"
},
"widgets_values": [
"8dir_frames/3_SE/SE"
],
"title": "3. SE → 透明 PNG 序列帧"
},
{
"id": 10,
"type": "VHS_VideoCombine",
"pos": [
-1400,
830
],
"size": [
320,
460
],
"flags": {},
"order": 9,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 10
},
{
"name": "audio",
"type": "AUDIO",
"link": null
},
{
"name": "meta_batch",
"type": "VHS_BatchManager",
"link": null
},
{
"name": "vae",
"type": "VAE",
"link": null
}
],
"outputs": [
{
"name": "Filenames",
"type": "VHS_FILENAMES",
"links": []
}
],
"properties": {
"Node name for S&R": "VHS_VideoCombine"
},
"widgets_values": {
"frame_rate": 24,
"loop_count": 0,
"filename_prefix": "8dir/4_W",
"format": "video/webm",
"pix_fmt": "yuva420p",
"crf": 20,
"save_metadata": true,
"trim_to_audio": false,
"pingpong": false,
"save_output": true
},
"title": "4. W → 透明 webm"
},
{
"id": 11,
"type": "SaveImage",
"pos": [
-1040,
830
],
"size": [
300,
300
],
"flags": {},
"order": 10,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 11
}
],
"outputs": [],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.3.49",
"Node name for S&R": "SaveImage"
},
"widgets_values": [
"8dir_frames/4_W/W"
],
"title": "4. W → 透明 PNG 序列帧"
},
{
"id": 12,
"type": "VHS_VideoCombine",
"pos": [
-1400,
1160
],
"size": [
320,
460
],
"flags": {},
"order": 11,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 12
},
{
"name": "audio",
"type": "AUDIO",
"link": null
},
{
"name": "meta_batch",
"type": "VHS_BatchManager",
"link": null
},
{
"name": "vae",
"type": "VAE",
"link": null
}
],
"outputs": [
{
"name": "Filenames",
"type": "VHS_FILENAMES",
"links": []
}
],
"properties": {
"Node name for S&R": "VHS_VideoCombine"
},
"widgets_values": {
"frame_rate": 24,
"loop_count": 0,
"filename_prefix": "8dir/5_E",
"format": "video/webm",
"pix_fmt": "yuva420p",
"crf": 20,
"save_metadata": true,
"trim_to_audio": false,
"pingpong": false,
"save_output": true
},
"title": "5. E → 透明 webm"
},
{
"id": 13,
"type": "SaveImage",
"pos": [
-1040,
1160
],
"size": [
300,
300
],
"flags": {},
"order": 12,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 13
}
],
"outputs": [],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.3.49",
"Node name for S&R": "SaveImage"
},
"widgets_values": [
"8dir_frames/5_E/E"
],
"title": "5. E → 透明 PNG 序列帧"
},
{
"id": 14,
"type": "VHS_VideoCombine",
"pos": [
-1400,
1490
],
"size": [
320,
460
],
"flags": {},
"order": 13,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 14
},
{
"name": "audio",
"type": "AUDIO",
"link": null
},
{
"name": "meta_batch",
"type": "VHS_BatchManager",
"link": null
},
{
"name": "vae",
"type": "VAE",
"link": null
}
],
"outputs": [
{
"name": "Filenames",
"type": "VHS_FILENAMES",
"links": []
}
],
"properties": {
"Node name for S&R": "VHS_VideoCombine"
},
"widgets_values": {
"frame_rate": 24,
"loop_count": 0,
"filename_prefix": "8dir/6_NW",
"format": "video/webm",
"pix_fmt": "yuva420p",
"crf": 20,
"save_metadata": true,
"trim_to_audio": false,
"pingpong": false,
"save_output": true
},
"title": "6. NW → 透明 webm"
},
{
"id": 15,
"type": "SaveImage",
"pos": [
-1040,
1490
],
"size": [
300,
300
],
"flags": {},
"order": 14,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 15
}
],
"outputs": [],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.3.49",
"Node name for S&R": "SaveImage"
},
"widgets_values": [
"8dir_frames/6_NW/NW"
],
"title": "6. NW → 透明 PNG 序列帧"
},
{
"id": 16,
"type": "VHS_VideoCombine",
"pos": [
-1400,
1820
],
"size": [
320,
460
],
"flags": {},
"order": 15,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 16
},
{
"name": "audio",
"type": "AUDIO",
"link": null
},
{
"name": "meta_batch",
"type": "VHS_BatchManager",
"link": null
},
{
"name": "vae",
"type": "VAE",
"link": null
}
],
"outputs": [
{
"name": "Filenames",
"type": "VHS_FILENAMES",
"links": []
}
],
"properties": {
"Node name for S&R": "VHS_VideoCombine"
},
"widgets_values": {
"frame_rate": 24,
"loop_count": 0,
"filename_prefix": "8dir/7_N",
"format": "video/webm",
"pix_fmt": "yuva420p",
"crf": 20,
"save_metadata": true,
"trim_to_audio": false,
"pingpong": false,
"save_output": true
},
"title": "7. N → 透明 webm"
},
{
"id": 17,
"type": "SaveImage",
"pos": [
-1040,
1820
],
"size": [
300,
300
],
"flags": {},
"order": 16,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 17
}
],
"outputs": [],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.3.49",
"Node name for S&R": "SaveImage"
},
"widgets_values": [
"8dir_frames/7_N/N"
],
"title": "7. N → 透明 PNG 序列帧"
},
{
"id": 18,
"type": "VHS_VideoCombine",
"pos": [
-1400,
2150
],
"size": [
320,
460
],
"flags": {},
"order": 17,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 18
},
{
"name": "audio",
"type": "AUDIO",
"link": null
},
{
"name": "meta_batch",
"type": "VHS_BatchManager",
"link": null
},
{
"name": "vae",
"type": "VAE",
"link": null
}
],
"outputs": [
{
"name": "Filenames",
"type": "VHS_FILENAMES",
"links": []
}
],
"properties": {
"Node name for S&R": "VHS_VideoCombine"
},
"widgets_values": {
"frame_rate": 24,
"loop_count": 0,
"filename_prefix": "8dir/8_NE",
"format": "video/webm",
"pix_fmt": "yuva420p",
"crf": 20,
"save_metadata": true,
"trim_to_audio": false,
"pingpong": false,
"save_output": true
},
"title": "8. NE → 透明 webm"
},
{
"id": 19,
"type": "SaveImage",
"pos": [
-1040,
2150
],
"size": [
300,
300
],
"flags": {},
"order": 18,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 19
}
],
"outputs": [],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.3.49",
"Node name for S&R": "SaveImage"
},
"widgets_values": [
"8dir_frames/8_NE/NE"
],
"title": "8. NE → 透明 PNG 序列帧"
},
{
"id": 20,
"type": "Note",
"pos": [
-2680,
880
],
"size": [
740,
1120
],
"flags": {},
"order": 19,
"mode": 0,
"inputs": [],
"outputs": [],
"properties": {},
"widgets_values": [
"八方向行走动画 —— 完整管线\n\n【前置步骤(在本工作流之外完成)】\n 角色图 →(GPTimage2)→ 八方向静态图 →(Seedance 首尾帧)→ 循环行走视频\n 视频每一帧上都排布着 8 个朝向的角色。\n\n【本工作流做的事】\n ① VHS「Load Video」把视频转成序列帧\n · force_rate 就是帧率选择。设 0 用源视频帧率;\n 设 12 可减半出帧、素材更小,走路动画通常 8~12 帧一循环就够\n · frame_load_cap 可限制总帧数,先小批量试参数很有用\n ② Lucida 抠图,为拆分提供语义级 alpha(见下方「为什么要接抠图节点」)\n ③ 八方向拆分:切格 + 编号 + 按方向分组,一次给出 8 条序列\n ④ 每个方向各接一个 VHS「Video Combine」出透明 webm\n ⑤ 每个方向各接一个 SaveImage 出透明 PNG 序列帧\n\n■ 为什么要接抠图节点,而不是让拆分节点自己扣白底 ————\n\n拆分节点自带的「白底转透明」是纯颜色阈值法:按「离白色多远」估 alpha。\n它的死穴是角色身上的白色衣物 —— 白衬衫本身就接近白,alpha 天生偏低,\n一旦收边压白边,衬衫就会被啃出破洞(实测会看到背景色透过衣服)。\n\nLucida 是按语义判断的,知道那是衣服而不是背景。实测(同一素材、\n同等白边水平):主体被啃掉的面积比阈值法少 35%,白衬衫完好。\nLucida 一次就能把整张雪碧图的 8 个角色全部识别出来\n(各格前景占比 0.18~0.24,中间空格 0.002)。\n\n素材里确实没有白色元素时,可以把 bg_mode 改成「白底转透明」省掉模型开销;\n此时 edge_shrink 要调到 0.35 以上才压得住白边。\n\n■ 治白边的两个参数 ————————————————————\n\n · edge_shrink(主力)把边缘那圈几乎全是背景的半透明像素收掉。\n 配模型 alpha 用 0.15~0.25;配阈值法要 0.35+。\n 实测:0 → 白边强度 0.048;0.2 → 0.026;0.5 → 0.016。\n · decontaminate(辅助)颜色反溢出,按\n 观察色 = 前景×a + 白×(1-a) 反解真正的前景色。\n 单独用改善很小(约 3%),要和收边配合。\n\n■ 拆分节点的其他关键参数 ————————————————\n\n · grid_cols / grid_rows / empty_cells\n 3×3 中间留空即 empty_cells=4。序号行优先、从 0 开始。\n · direction_names\n 按「跳过空格后的先后顺序」命名,默认对应:\n SW S SE ← 行1:面向观众\n W E ← 行2:侧面\n NW N NE ← 行3:背对观众\n 与素材不符就直接改这行,名字只影响标注不影响画面。\n · expand_beyond_cell(务必开启)\n 允许角色超出格子边界。关闭时按格线严格切分,角色只要探出格线\n 就会被切断(最典型的是脚被削掉)。开启后格子只用来判定方向,\n 实际范围由角色自身的连通区域决定。三种 bg_mode 都有效。\n · auto_crop\n 裁剪框取该方向所有帧的并集,因此整条序列尺寸一致(能合成视频),\n 角色也不会在帧间跳动。\n\n■ webm 透明的关键 ————————————————————\n\n Video Combine 的 format 必须选 video/webm,pix_fmt 必须选 yuva420p。\n 注意:alpha 存放在 WebM 的独立边带里,用 ffprobe 看主流会显示 yuv420p,\n 这是正常的。播放器/引擎(走 libvpx 解码)能正确读到透明通道;\n 若要用 ffmpeg 自行验证,需显式加 -c:v libvpx-vp9 解码,\n 否则内置 vp9 解码器不输出 alpha,会让人误以为透明丢了。"
],
"color": "#432",
"bgcolor": "#653"
}
],
"links": [
[
1,
1,
0,
2,
0,
"IMAGE"
],
[
2,
1,
0,
3,
0,
"IMAGE"
],
[
3,
2,
0,
3,
1,
"MASK"
],
[
4,
3,
0,
4,
0,
"IMAGE"
],
[
5,
3,
0,
5,
0,
"IMAGE"
],
[
6,
3,
1,
6,
0,
"IMAGE"
],
[
7,
3,
1,
7,
0,
"IMAGE"
],
[
8,
3,
2,
8,
0,
"IMAGE"
],
[
9,
3,
2,
9,
0,
"IMAGE"
],
[
10,
3,
3,
10,
0,
"IMAGE"
],
[
11,
3,
3,
11,
0,
"IMAGE"
],
[
12,
3,
4,
12,
0,
"IMAGE"
],
[
13,
3,
4,
13,
0,
"IMAGE"
],
[
14,
3,
5,
14,
0,
"IMAGE"
],
[
15,
3,
5,
15,
0,
"IMAGE"
],
[
16,
3,
6,
16,
0,
"IMAGE"
],
[
17,
3,
6,
17,
0,
"IMAGE"
],
[
18,
3,
7,
18,
0,
"IMAGE"
],
[
19,
3,
7,
19,
0,
"IMAGE"
]
],
"groups": [],
"config": {},
"extra": {
"ds": {
"scale": 0.5,
"offset": [
2820,
100
]
}
},
"version": 0.4
}