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

34 量错对象案例集

✅ 已验证——每一条都是真的栽过

「量错了对象」是这个项目里最贵的一类错误:它不报错,只给出一个看起来合理但方向相反的结论。五版下来至少栽了 28 次。按「症状 → 真相 → 规矩」记,这样下次症状出现时能对号。

量的层不对

1. 量累积合成图,当成量单层。 症状:「线稿层 K90=0.104 很脏」。真相:量的是 008-lineart.png 这张累积合成图,单独量 Line_Main 是 0.032,本来就达标。→ 量某一层就只量那一层。

2. 量 Flat 层,而塑造在 Shade 层。 症状:三种画法都「颜色数=1、σ 全 0」。真相:塑造画在 clip 的 Shade 层上。→ 量 group 的 projection

3. 在透明层上量。 症状:多尺度能量 94%。真相:透明区 RGB=0,滤波器把黑边混进来,实际 7%。→ 用 projection,或把未覆盖处填成均值。

4. 只看 RGB 判 clip。 症状:「inherit alpha 不生效」。真相:clip 只写 RGB 不写 A,alpha=0 处 RGB 照样被写。→ 同时看 alpha。

5. 在根节点下测 clip。 症状:同上。真相:根下有全不透明 Background,累积 alpha 处处 255,什么也不裁是正确行为。→ 在 group 里测。

6. 单层测 multiply。 症状:暗角把纯黑抬成 (6,6,6),但单层测 multiply 叠黑是 (0,0,0)。真相:不透传的组先合兄弟层再整组盖下去,暗角在跟透明的兄弟相乘。→ 在真实的组结构里量。

11b. 量非破坏效果时量源层。 FilterMask / FilterLayer / TransformMask 一个字节都不改源层像素,node.pixelData() 前后逐字节相同。量它必须用 s.projection(group),否则结论是「完全没生效」。→ 效果在合成里,就去合成里量。

比的对象不对

7. 拿整幅比整幅。 症状:「局部对比度差 51 倍」。真相:参照图主体含多种材质,我们的 body 判据把背景算进去了。→ 在可比的语义区域上比,同类区域我们甚至更高。

8. 跨分辨率比 p99。 症状:8K 成品 p99 33.2 vs 参考画 59.4–74.6,「差一倍」。真相:同一张成品 @2508 是 42.2。→ 归一到同一物理宽度再量。

9. 以参考画为锚。 症状:p99 永远达不到 59。真相:源图自己只有 41.6,参考画有成套线稿而源图没有。→ 门槛写成源图的百分比。

10. 拿 8x 输出和放大的 origin 比。 真相:那是拿插值当真值。→ 降采样回 1x 再比。

11. 另画一张 1x 真值。 症状:锚点读 0.1245 而不是 0。真相:PIL 在不同超采样倍数下有约 1/8 像素系统偏移。→ 1x 真值由 8x 真值降采样得到。

指标本身不对

12. empty 在放大目标上是反的。 nearest 放大 39.93 通过,lanczos 51.58 不通过。→ 配 edge_ratio

13. 整块的梯度 p99 判边缘。 症状:四条填色路子里三条读出 p99 = 0.0。真相:边只占 1%,p99 落在纯内部。→ 在边界带里量。

14. 边界带偏差判「边是不是曲线」。 症状:v4 四条、v5 十二条全部 0.47±0.02。真相:那条带 1px 宽,从 1x 二值 mask 恢复不出 8x 亚像素位置;它量的是「边在不在原位」。→ K90 + 形状偏差配对。

15. 梯度 p90 当细节密度。 grain 降低后 p90 反而掉。→ 它被均匀噪声主导。

16. 只看 K90 判矢量化好坏。 会奖励「抹圆一切」。→ 配形状偏差。

17. aliased 0.0% 读成「利」。 症状:用 c) Pencil 1 Sketch 画发丝,全糊。真相:它 W=3.25 是最软的笔,aliased 0 是因为软到没有台阶。→ 看 W。

17b. 判据比被测对象更粗。 用「离哪个色点最近」的硬分类去算 ColorizeMask 输出的覆盖率,边界带偏差恒等于 0.5——那量的是我的分类器是二值的。换成把像素投影到「背景色→区色」线段上的连续覆盖率,才读到可信的 0.4981。→ 判据的分辨率不能低于你想区分的差别。

17c. 判据没有地板。 filter.apply 的过渡带量出 7.2 px,看着像「有一点羽化」。其实理想台阶经过同样的 9 宽平滑就是 7.2 px——那是判据自己的读数。→ 先把「完美的那一端」和「最差的那一端」都算出来,再看被测的落在哪。

探针几何不对

18. 长曲线探针,短线段用法。 path() 在长曲线上比 stroke() 干净 23–47%,短线段上反过来。→ 探针几何匹配实际用法。

19. 量长直线的边,问一个点的形状。 f) Bristles-5 Flat aliased 0.0 / K90 0.065 全场最干净,但它是平头笔,短笔全是矩形。→ 问什么量什么,probe_markshape 就是为它写的。

工具本身不对

20. 半像素坐标约定。 matplotlib contour 返回下标空间,PIL/Krita 是像素空间,差 0.5。形状偏差 0.302 被读成「矢量化不如 coverage()」。→ 每个坐标约定都要验一次。

21. 取景函数的 and/or 不重叠判断写成 and,只好捡纯黑背景块,判据 14.5 而实际 43.5。→ 打印取景坐标和均亮。

22. 读到过期像素。 erase 擦掉 2198 px。真相:异步,读到稳定后是 0。→ s.settle()

23. 用重心判位移。 shape 挪了 300 px,重心只动 214.5 px。两个原因叠在一起:量的框比形状小,挪出去的部分被截断;而且组的投影在形状挪走之后留残影(同一个大框里的不透明像素从 258 万涨到 286 万)。→ 判位移用对象自己的 boundingBox(),或者对着「挪过的解析真值」量偏差。

24. 竖条纹量逐列方差。 模糊强度剖面取的是「每一列在行方向的标准差」,而竖条纹每一列都是常数,量出来处处是 0,四条路一起读成「全都没生效」。→ 探针的纹理方向要和判据的求和方向垂直。

25. 卷积的零填充。 剖面平滑用 np.convolve(..., mode="same"),两端被零填充拉低;右端被拉低就等于「变糊了」,剖面末尾伪造出一个强度回升,过渡带量出 1203 px 而不是 7 px。→ 复制边界再卷积。

一句话

每次量之前问三个问题:我量的是哪一层?它和什么比?这个指标能不能区分我想区分的两样东西? 第三个最容易漏。