首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >我用 WorkBuddy 量出了参考表的「缝」:为什么四格宽是 476 / 554 / 556 / 462

我用 WorkBuddy 量出了参考表的「缝」:为什么四格宽是 476 / 554 / 556 / 462

原创
作者头像
用户6882326
发布于 2026-10-08 16:04:59
发布于 2026-10-08 16:04:59
660
举报

一张 2048×1024 的角色参考表整版,四格横排。

如果按等分切,每格正好 512。可我把切出来的分图翻出来一看——文件名上的宽度是 476 / 554 / 556 / 462。

四个数,一个都不等于 512,最大差 50px。

我第一次看到的时候以为是模型随机性。后来才想明白:这不是等分切的,是"量着缝"切的。整版是模型一次生成的,人物站在哪儿、留多少空,模型自己说了算;你只能先量出画面里人与人的空隙在哪,再沿着空隙下刀。

而"怎么量"这件事,我前后翻过两次车。这篇把两次翻车和最后跑通的算法都摊开讲。


一、先看看"想当然"会切出什么

最直觉的做法当然是四等分。我把等分线画到整版上,和实际用的裁切线并排——

等分线与实测缝位叠加在同一张整版上
等分线与实测缝位叠加在同一张整版上

红虚线是等分点(512 / 1024 / 1536),绿实线是实际下刀的位置(476 / 1030 / 1586)。

看清了:红虚线直接压在脸上,绿线落在两张脸之间的空隙里。第三处差得最狠——50px,在 2048 宽的图上看着不多,但那一刀落在脸颊边缘,切出来的分图就会缺一块下巴。

一处的偏差不算事,问题是我把这八张整版全量了一遍:

八张整版的实测缝位与等分点的偏移量
八张整版的实测缝位与等分点的偏移量

整版

尺寸

等分点

实际裁切边

偏移

角色 A · 头

2048×1024

512 / 1024 / 1536

476 / 1030 / 1586

−36 / +6 / +50

角色 A · 身

1536×1536

384 / 768 / 1152

398 / 830 / 1126

+14 / +62 / −26

角色 B · 头

2048×1024

512 / 1024 / 1536

471 / 1038 / 1579

−41 / +14 / +43

角色 B · 身

1536×1536

384 / 768 / 1152

304 / 700 / 1170

−80 / −68 / +18

角色 C · 头

2048×1024

512 / 1024 / 1536

527 / 1067 / 1574

+15 / +43 / +38

角色 C · 身

1536×1536

384 / 768 / 1152

465 / 811 / 1075

+81 / +43 / −77

角色 D · 头

2048×1024

512 / 1024 / 1536

490 / 1028 / 1541

−22 / +4 / +5

角色 D · 身

1536×1536

384 / 768 / 1152

384 / 768 / 1152

0 / 0 / 0

八张里只有一张是能等分的(角色 D 的身体图)。其余七张的最大偏移是 −80 和 +81——在 1536 宽的身体图上,等于把五分之一格宽整个挪走。

结论:等分切法在这类整版上不可用。


二、第二次翻车:我按「纯白背景」判缝,全图零命中

既然不能等分,那就找缝。缝是什么?是两格之间的背景。

那么,"背景"怎么认?我第一反应是——背景当然是白的,三通道都大于 245 就算背景。

这个假设错得离谱。

八张整版背景真实底色与 245 阈值线的对照
八张整版背景真实底色与 245 阈值线的对照

我把八张整版的实际底色采出来:最亮通道只有 110 ~ 190。

  • 角色 A 头:RGB(127, 126, 129)
  • 角色 B 头:RGB(110, 112, 125)
  • 角色 C 身:RGB(165, 168, 169)
  • 角色 A 身:RGB(190, 175, 186) ← 最亮的一张,也是粉调的

全部落在 245 以下。 按 >245 判背景,这些底色会被整体判成"前景",一列干净缝都找不出来。

原因很朴素:这些整版根本不是纯白底,而是浅灰蓝 / 浅灰粉的影棚渐变底,底下还压着一层投影。我拿一次"想当然"去假定生成底的颜色,直接被自己的采样打脸。

纪律:不要对生成的底色做任何先验假设。要判背景,一律"就地采样"。


三、正解:逐行自适应背景的「前景密度法」

正确的做法是:不定义"背景是什么颜色",而是"每行各自取一个背景基色,再比差"。

整版是纵向渐变的,所以基色必须逐行取——全局取一个色,会把整片渐变背景误判成前景。

一个反直觉的点:我从每行最右侧 20 列取中位色当作该行的背景基色。为什么是最右边?因为四格横排时,第 4 格的右侧一定是纯背景区。这一招对头图、身体图都成立。

代码语言:python
复制
import numpy as np
from PIL import Image

BG_TOL  = 22      # 与逐行背景基色的最大通道差,超过算前景
SMOOTH  = 9       # 列密度的平滑窗

def density(path):
    a = np.asarray(Image.open(path).convert("RGB")).astype(np.float32)
    h, w, _ = a.shape

    bg   = np.median(a[:, w - 20:, :], axis=1)        # (h,3) 每行的背景基色
    diff = np.abs(a - bg[:, None, :]).max(axis=2)     # 每像素与所在行基色的最大通道差
    fg   = (diff > BG_TOL)                            # 前景掩码

    y0, y1 = int(h * 0.06), int(h * 0.96)             # 掐掉顶部 6% 与底部 4%
    cnt = fg[y0:y1, :].sum(axis=0).astype(np.float32) # 每列的前景像素数
    sm  = np.convolve(cnt, np.ones(SMOOTH) / SMOOTH, mode="same")
    return sm, w, h

四个参数,每一个都有来历:

参数

取值

为什么

背景采样位置

每行最右 20 列

第 4 格右侧一定是纯背景;全局取色会被纵向渐变骗

容差 BG_TOL

22

对浅灰蓝底最稳。调低会把渐变噪声算成前景,调高会漏掉薄纱

掐头去尾

y 6% ~ 96%

避开顶部的标注文字与底部的投影/鞋

平滑窗

9

抹掉单列噪声,又不至于把 100px 级的窄缝抹平


四、怎么读结果:峰是人,谷是缝

把每列前景像素数画成曲线,答案就自己浮出来了:

整版每列前景密度曲线:四个峰是四个视图,三个谷是缝
整版每列前景密度曲线:四个峰是四个视图,三个谷是缝

四个峰 = 四个视图,三个谷 = 三处缝。

红虚线是等分点,绿实线是谷底。可以看到绿线每次都精准落在谷的最深处——而且,谷底就是实际裁切边。角色 A 头图自动量出的 476 / 1030 / 1586,跟文件名里那三个数一分不差。

这就是开头那个问题的答案:那些宽度不是随手定的,是量出来的。

谷底值多少算"干净"?

这里有个我踩过的坑:"干净"的标准不能一概而论。

八张整版的谷底残留值:头图与身体图的分层
八张整版的谷底残留值:头图与身体图的分层

同一条"残留 ≤ 20 即干净背景"的标准:

  • 身体图里成立了两次:角色 B(24 / 31 / 16)、角色 D(0 / 0 / 0)——背景干净得像真空
  • 身体图里崩了两次:角色 A(392 / 473 / 744)、角色 C(669 / 559 / 701)——裙摆和纱边飘起来,跟隔壁粘连了
  • 四张头图全部远高于 20(178 ~ 564)

头图为什么天然脏?因为头像是占满整格高度的,两张脸之间那道"缝"里,上半段是头发、下半段还是头发,根本不是干净背景。

所以判据要分两套:

图型

谷底残留参考

含义

身体图(纱不飘)

≤ 20

干净缝,scan 结果可直接采信

身体图(纱/裙摆飘)

400 ~ 700

缝是"脏"的,必须人工复核

头图(四格横排)

300 ~ 560 属正常

谷底不干净是必然,别拿 ≤20 去套

关键认知:「谷底残留高」不等于「切错了」。 头图谷底残留 534 / 564 / 542,看着很脏——但那三个位置恰恰就是正确的裁切边。判据的意义是"要不要人工复核",不是"对不对"。


五、三档工具:scan / probe / cut

把这套算法封成三个模式,按需调用:

代码语言:bash
复制
# 1) scan:量化边界,自动报三处缝的谷底 x 坐标(先跑这个)
set CS_CROP_SRC=<整版图绝对路径>
python crop_sheet.py scan
# → 直接可用的输出:  CS_X=476,1030,1586

# 2) probe:在整版上盖坐标网格,出标尺图供人工目视(scan 有歧义时用)
python crop_sheet.py probe

# 3) cut:按 CS_X 给出的三条缝切开 4 段
python crop_sheet.py cut  CS_X=476,1030,1586

cut 只做一件事:纯裁切,不重绘、不缩放。这是"零漂移"的前提——一旦在裁切这步引入缩放或重绘,四格的脸就不再是同一张脸了。

切出来的分图,文件名直接带上裁切尺寸:

代码语言:markdown
复制
P1_正面_476x1024.png
P2_四分之三侧_554x1024.png
P3_九十度侧面_556x1024.png
P4_背面_462x1024.png

文件名自带尺寸,本身就是"这是量出来的"的存档证据——哪天有人问"为什么不是 512",翻文件名就行。


六、自动量的可信度

自动跑的结果能不能直接信?我用一套手工量过的整版对过账:

缝 1

缝 2

缝 3

scan 自动报

890

1295

1642

手工目视网格 + 逐列量化

889

1296

1640

差

1

1

2

相差 1 ~ 2px。

所以结论是:scan 的结果可以直接采信,不必再手工量一遍。只有在两种情况下才需要动 probe 目视复核:

  1. scan 报"找到的缝不是 3 处"(比如只找到 2 处)
  2. 有段宽异常(任何一段 < 100px)

七、两个必须单独说的特例

特例一:头图不能用同一套「找缝」逻辑

头图是四格横排,谷底天然不干净(上一节讲过,残留 300~560)。如果判定逻辑里带一条"深度必须低于峰值 35%"的门槛,头图会全军覆没——所有候选谷底都因为不够深而被滤掉,scan 直接报"只找到 0 处缝"。

我实测就撞上了:用带深度门槛的版本跑头图,八张里有三张返回空。

头图的正确做法是换一把刀——十字刀:

  • 竖缝只在 w/2 ± 130px 内找
  • 横缝只在 h/2 ± 130px 内找
  • 切十字,得四象限

田字格布局下只需找两条线,比四格横排的"三处缝"简单得多,而且不受"谷底不够深"的干扰,因为我们不再要求谷底干净,只要求在给定窗口里取最小。

特例二:「脚被切」不是画幅的锅

身体图曾经反复出现"脚被切掉"。我一度以为是画幅太宽导致的固有边界。实测下来,元凶是人物被画得太大。

几何账很简单:全身入镜时人物高约 950px,身高 : 身宽 ≈ 4 : 1,所以人物宽必须压在 380 ~ 400px 以内。

  • 画幅取 1536×1024 → 每格 384 → 正好在安全区
  • 画幅取 2048×1024 → 每格 512 → 超标 30% → 脚必然出画

而人物为什么会被画大?因为提示词里写了"四格并排铺满整幅画面"。

"铺满"这个词是在鼓励模型填满画格,人物一放大,高度必然溢出。改掉它,换成:

代码语言:markdown
复制
每格四周留出大面积纯色背景、从头顶到脚底完整入镜、双脚与鞋清晰可见

出完还得验:用垂直前景密度判触底——最底行仍是前景 = 脚被切,别只靠肉眼。


八、裁完必做:隔离检查

切开不等于切对。四张分图出来以后,有一道不能省的工序:

  1. 逐张读图,不是抽检。 重点看每张的左右边缘有没有带进隔壁的人。
  2. 边缘若有可疑的淡竖条,放大原图该处核实再决定动不动刀:
代码语言:python
复制
z = im.crop((x0, y0, x1, y1)).resize(((x1 - x0) * 3, y1 - y0), Image.LANCZOS)

实测放大后多数是绒边 / 纱边 / 手臂外缘——正常现象,不是残留。只有真看清了再改坐标。

  1. 改坐标后,重裁前先删旧分图,否则新旧混在一个目录里,你分不清哪张是新的。
  2. 边界取舍原则一句话:宁可切掉自己这侧的衣角,也绝不带进隔壁视图的人。

优先级永远是"人物完整" > "画面留白"。纱尖、袖角出画,视觉上是自然出画;带进隔壁半张脸,那是事故。


九、整条链长什么样

  • 整版出图:一次生成,四格横排(头图 2048×1024 / 身体图 1536×1536)
  • 量缝:scan 报出三处谷底 x 坐标
  • 裁切:cut 纯裁切,不重绘不缩放 → 四张分图,文件名带实测宽度
  • 超分:纯超分 2x,不重绘
  • 归档:整版 / 分图 / 超分三态分目录
整版 → 四张分图 → 纯超分 2x
整版 → 四张分图 → 纯超分 2x

到这一步,四张分图的宽度各不相同(476 / 554 / 556 / 462),但它们来自同一张图、同一次生成、零重绘——所以四格脸的是一致的。宽度不同恰恰不是缺陷,是"沿着真实空隙下刀"的结果。

而这条链上的每一步——调 ComfyUI 出整版、跑量缝脚本、批量裁切、检查脚有没有被切、归档三态目录——都是我在 WorkBuddy 里用自然语言驱动完成的。脚本是本机跑的,图片是本机生成的,整条链零云端调用、零积分。


十、踩坑速查表

症状

根因

解法

判"三通道 >245 = 背景",一列都没命中

生成底是浅灰蓝渐变 + 投影,不是纯白

改用逐行自适应基色,别再假设底色

全局取一个底色,半张图被当成前景

影棚底是纵向渐变的

背景基色必须逐行取

谷底找不准,缝跑到人的肩膀里

容差太小,把渐变噪声算成前景;或没掐头去尾

容差 22;y 取 6%~96%

头图 scan 报"找到 0 处缝"

头图谷底天然不干净,被"深度 < 峰值 35%"的门槛滤光

头图换十字刀,只找中线上两条

身体图谷底残留 400~700

裙摆 / 纱边飘起来,跟隔壁粘连

不采信自动结果,动 probe 目视

脚被切掉

提示词里"四格铺满画面"把人物撑大了

写"每格留大面积背景、完整入镜";画幅按每格 384 取

分图边缘有可疑淡竖条

可能是绒边/纱边,也可能真带进了隔壁

放大 3 倍看清再动刀;宁可切衣角不带人

重裁后新旧分图混在一起

没删旧文件

改坐标后先删旧分图再重裁


写在最后

这篇的起点只是一个很具体的问题:为什么四格的宽度是 476 / 554 / 556 / 462,而不是 512?

答案朴素到有点无聊——因为这四个格子是模型自己排的,缝在哪只有量了才知道。但把这件事做对,我翻了两次车:一次想当然地等分,一次想当然地判白。

两条纪律值得带走:

  1. 不要对生成的画面做任何先验假设。 底色不是白的,缝不在中线上,人物不在格子中央。
  2. 判据要分清适用域。 "谷底残留 ≤ 20 算干净"在身体图上成立,在头图上就是错的——拿错判据,你会把正确的裁切当成错误的。

剩下的就交给数字。截图和曲线的每一处标注,都能在脚本里复现。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 一、先看看"想当然"会切出什么
  • 二、第二次翻车:我按「纯白背景」判缝,全图零命中
  • 三、正解:逐行自适应背景的「前景密度法」
  • 四、怎么读结果:峰是人,谷是缝
    • 谷底值多少算"干净"?
  • 五、三档工具:scan / probe / cut
  • 六、自动量的可信度
  • 七、两个必须单独说的特例
    • 特例一:头图不能用同一套「找缝」逻辑
    • 特例二:「脚被切」不是画幅的锅
  • 八、裁完必做:隔离检查
  • 九、整条链长什么样
  • 十、踩坑速查表
  • 写在最后
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档