Skip to content

抠图的图像后处理(112 行)应从 framework/providers 迁到 ai_engine(Refs #171) #212

Description

@johnnyzhang-eng

结论

framework/providers/matte.py 里混了两种性质不同的东西,其中约 112 行(全文 205 行)属于图像后处理,与"用哪个抠图模型"无关,应该迁到 ai_engine

评审意见原话:「抠图调用逻辑可以放在这里,但有关后面的图像预处理算法,应该放在 ai_engine 处理流程中。」这条成立。

现状拆分(按行数实测)

性质 行数 内容
模型适配 71 u2netp 权重下载/缓存、onnxruntime 会话、预处理归一化常量、cutout 主流程
图像后处理 112 _flat_bg_penalty 键控清理、_fill_enclosed_holes 封闭空洞填充、_spread 连通域传播、_bg_key / _corner_pixels 取样
其它 22 import、模块 docstring

为什么该搬

这些算法修的是显著性抠图模型的通病,不是 u2netp 特有的:

  • _flat_bg_penalty:显著性模型对闭合区域天然失灵(四足角色腿间的背景、盔甲缝隙会被判成主体)。换成 BiRefNet 或云端抠图同样需要。
  • _fill_enclosed_holes:修的是"主体内部透出背景"。成因既包括模型判错,也包括上面那个键控清理自己误杀的像素(实测浅肤色到灰底欧氏距离仅 31.3,窄于清理阈值 38,每帧误杀 820~2346 个像素)。
  • _spread:为上面两个服务的连通域传播原语。

留在 provider 里的实际后果:换抠图实现时这些修法会跟着丢掉,而它们是拿实测换来的。

迁移时必须一起搬的实测依据(不要顺手"统一"阈值)

这些阈值的窗口非常窄,是逐个试出来的:

  1. 锈橙色毛发 (222,130,70) 与洋红底 (222,41,124) 共享红通道,欧氏距离只有 104。 放宽 chroma 容差会把毛发先变成橄榄绿、再变亮绿。
  2. _EDGE_SKIP = 2:视频帧最外一两行/列是编码器伪影不是底色。实测 9 段真 i2v × 16 帧 = 144 帧,贴边采样时 26 帧(18%)被判"底不均匀"而跳过清理;往里让 2px 后归零,而三张静态母版的取样中位色一个字节都没变。
  3. _HOLE_BG_TOL = 14:纯背景色距 p99.9≈6.5、最大 11.1(压缩噪点),而被误杀区域的中位色距 ≥17.1,14 落在这条 1.5 倍间隙里。
  4. 空洞判定必须同时看连通性与颜色。 只按"不与画幅边界连通"判会把两腿之间填实——迈步相里两只靴子在下方交叠,把腿间空隙彻底封死。实测 121 帧中 80 帧存在这种封闭的底色空隙、共 25,173 px,朴素版会把它们全部填成主体(最惨单帧 3,172 px,两腿焊死)。
  5. _bg_key 与键控清理必须用同一个取样口径,否则一个把某块当背景清掉、另一个又把它当主体填回来。

迁移方案(要拍板的点)

搬过去之后 MatteProvider 的契约会变:现在 cutout(bytes) -> bytes 是"抠图 + 后处理"一步到位,搬走后 provider 只做纯抠图,后处理由 ai_engine 显式调。

消费方是 ai_engine/strategy/concrete.pyVideoFrameStrategyPerFrameStrategy 各一处 self._matte.cutout(...))。所以要定:

  • 后处理放 ai_engine.postprocess 下的新模块,还是并入现有 postprocess.pack 那一层?
  • strategy 里是每次 cutout 后手动调,还是包一层"抠图 + 后处理"的组合函数?

我倾向前者各自独立、strategy 显式调两步——链路里每一步都看得见,符合这层"出帧流水线"的写法。但这是 ai_engine 的内部结构,想听一下意见。

不在本 Issue 范围

  • 换抠图实现本身(MatteProvider 已是 Protocol、消费方按 Protocol 注入,换实现不需要动现有代码)
  • 抠图算法本身的改进

相关

代码现在在 #179 / #181 的范围内。刻意不塞进那两个 PR:这条要动 ai_engine.postprocess 的接口,而 #180 / #181 正在评审,现在动会让三个 PR 互相牵扯、评审锚点再移一次。等那批合入后单独提。

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestproposal该 Issue 是一个产品提案

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions