Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

11 补全后的一致性检查

📐 设计

补全的输出要在进入叠层之前过一遍检查。检查的东西和第 9 章的验收一一对应,这里写怎么量

检查清单

# 伪代码, 每一项返回 (pass: bool, value: float)
def check_completion(orig_rgb, mask_p, rgba_p, mask_p2, tiers_p, occluders):
    filled = mask_p2 & ~mask_p                       # 补全区

    # 1 重叠区不变
    d = np.abs(rgba_p[mask_p, :3] - orig_rgb[mask_p]).max()
    yield "重叠区不变", d == 0, d

    # 2 边界连续: 交界带梯度 vs 部件内部梯度
    seam = dilate(mask_p, 2) & dilate(filled, 2)
    inner = erode(mask_p, 6)
    g = gradient_mag(rgba_p[..., :3])
    ratio = p90(g[seam]) / p90(g[inner])
    yield "边界连续", ratio <= 1.5, ratio

    # 3 色阶一致: 补全区像素到最近档的距离
    cols = np.array([rgb for _, rgb, _ in tiers_p])
    dist = nearest_color_distance(rgba_p[filled, :3], cols)
    off = (dist > 24).mean()
    yield "色阶一致", off <= 0.05, off

    # 4 不发明结构: 高频能量
    e_fill = bandpass_energy(rgba_p, filled, sigma=1)
    e_seen = bandpass_energy(rgba_p, mask_p, sigma=1)
    yield "不发明结构", e_fill <= 1.2 * e_seen, e_fill / e_seen

第 5 条(下游判据不变差)在叠层之后由 gauge.py 量,不在这里。

失败了怎么办

失败项处理
重叠区不变直接用原图覆盖回去(这一条永远能修)
边界连续在交界带上做归一化卷积羽化(第 18 章_blur(mask=) 就是这个),宽度 2–3px
色阶一致把超出的像素拉到最近档的颜色
不发明结构换工具(LaMa → ComfyUI 或反过来),或缩小 budget

重新解边界

补全区的外边界是新的,α 要重解:对 mask_p'contour.alpha_from_image()。注意补全区的外侧是遮挡它的部件clean() 取的「另一侧干净像素」会是遮挡物的颜色——这是对的,叠层时它确实压在上面。

记录

每个部件的检查结果进 plan.jsonparts[i].completion 字段:

"completion": {"filled_px": 4120, "skipped_px": 880, "tool": "lama",
               "checks": {"重叠区不变": [true, 0], "边界连续": [true, 1.12], ...}}

没补的部件这个字段为 null。这样第 15 章的判据变差时能追到是哪个部件、哪一条。