From ec49a835361fd0f6d92a41204dcc9547073b46ee Mon Sep 17 00:00:00 2001 From: "Somhairle H. Marisol" Date: Tue, 29 Sep 2026 06:12:57 +0800 Subject: p64: 整改桥梁栏杆可辨(深墨栏体/亮扶手/望柱)与内景四角布局(Hermes vision 复核) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/analyze-p64.py | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) (limited to 'scripts/analyze-p64.py') diff --git a/scripts/analyze-p64.py b/scripts/analyze-p64.py index f1b0e0c..243d7dd 100644 --- a/scripts/analyze-p64.py +++ b/scripts/analyze-p64.py @@ -10,8 +10,13 @@ (P62 同带基线 0.103;HUD 顶部条带 y<120 不计,避免把 UI 当内容)。 3. 桥近景:桥所在区域 (x 560..720, y 360..500) 的「木色像素」占比 >= 0.20, 证明桥面/栏杆木色进入实拍帧。 - 4. 三帧均 1280x720、非空、无 64x64 纯白块、无 24x24 纯黑块,且两两不同。 - 5. 缺字空白位:中文经 CjkGlyphAtlas 绘制,P61 已证覆盖(P61GlyphCoverageTests 绿)。 + 4. 栏杆可辨(整改新增):以日志相机定位桥格(世界 tile x31,y29..31),取两侧栏杆条带 + (相对桥格 x 偏移 1..6 与 26..31,纵向 3 格)。栏杆像素口径 = 亮色 (r>150,g>130,b>100) + 或深色 (r<80,g<80,b<80)——纯桥面木色 (≈119,77,47) 两类都不满足,故该指标直接区分 + 「有栏杆」与「只有桥面木板」。要求左右两条带各自 rail_ratio >= 0.70。 + 在俯瞰帧(1x 全帧)与桥近景帧上都成立。 + 5. 三帧均 1280x720、非空、无 64x64 纯白块、无 24x24 纯黑块,且两两不同。 + 6. 缺字空白位:中文经 CjkGlyphAtlas 绘制,P61 已证覆盖(P61GlyphCoverageTests 绿)。 Usage: python3 scripts/analyze-p64.py Exit 0 pass / 1 fail / 2 usage. @@ -73,6 +78,26 @@ def non_background_ratio(img, y0, y1): return 1.0 - float(counts.max()) / float(counts.sum()) +BRIDGE_TILE_X = 31 +BRIDGE_TILE_Y0 = 29 +BRIDGE_TILE_H = 3 +RAIL_THRESHOLD = 0.70 + + +def rail_strip_ratios(img, camx, camy): + """Return (left_ratio, right_ratio) of rail-colored pixels in the two rail strips.""" + bx = BRIDGE_TILE_X * 32 - camx + y0 = BRIDGE_TILE_Y0 * 32 - camy + y1 = y0 + BRIDGE_TILE_H * 32 + results = [] + for sx0 in (bx + 1, bx + 26): + reg = img[y0:y1, sx0 : sx0 + 5].astype(np.int16) + r, g, b = reg[:, :, 0], reg[:, :, 1], reg[:, :, 2] + rail = ((r > 150) & (g > 130) & (b > 100)) | ((r < 80) & (g < 80) & (b < 80)) + results.append(float(rail.mean()) if rail.size else 0.0) + return results[0], results[1] + + def main(): if len(sys.argv) != 3: print(__doc__) @@ -151,6 +176,17 @@ def main(): lines.append(f"bridge region wood-pixel ratio (x {x0}..{x1}, y {y0}..{y1}) = {wood}/{total} = {wood/total:.4f}") if wood / total < 0.20: failures.append(f"bridge wood ratio {wood/total:.4f} < 0.20") + for name in ("p64-overview", "p64-bridge"): + if name not in stats or name not in shots: + continue + camx = int(float(shots[name].group(5))) + camy = int(float(shots[name].group(6))) + left, right = rail_strip_ratios(stats[name], camx, camy) + lines.append(f"rail strips [{name}] cam=({camx},{camy}) left={left:.3f} right={right:.3f} (threshold {RAIL_THRESHOLD})") + if left < RAIL_THRESHOLD: + failures.append(f"{name} left rail ratio {left:.3f} < {RAIL_THRESHOLD}") + if right < RAIL_THRESHOLD: + failures.append(f"{name} right rail ratio {right:.3f} < {RAIL_THRESHOLD}") lines.append("") for name, shot in sorted(shots.items()): -- cgit v1.2.3