diff options
| author | Somhairle H. Marisol <[email protected]> | 2026-09-29 06:12:57 +0800 |
|---|---|---|
| committer | Somhairle H. Marisol <[email protected]> | 2026-09-29 06:12:57 +0800 |
| commit | ec49a835361fd0f6d92a41204dcc9547073b46ee (patch) | |
| tree | e487c692e327484bfc813db2f65cb6a43a13b4cc /scripts | |
| parent | 166fbeb4efd1c36c5c8289defdf480c89835d540 (diff) | |
| download | living-village-ec49a835361fd0f6d92a41204dcc9547073b46ee.tar.gz | |
p64: 整改桥梁栏杆可辨(深墨栏体/亮扶手/望柱)与内景四角布局(Hermes vision 复核)
Diffstat (limited to 'scripts')
| -rw-r--r-- | scripts/analyze-p64.py | 40 | ||||
| -rw-r--r-- | scripts/make-jiangnan-art.py | 31 |
2 files changed, 56 insertions, 15 deletions
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 <record-dir> <out-txt> 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()): diff --git a/scripts/make-jiangnan-art.py b/scripts/make-jiangnan-art.py index c28244f..caf0c01 100644 --- a/scripts/make-jiangnan-art.py +++ b/scripts/make-jiangnan-art.py @@ -192,24 +192,29 @@ def build_world_atlas(): # P64 桥:在既有栈板桥面上补可读的两侧栏杆与望柱(桥沿纵向铺 3 格,栏杆随格连续), # 并保留桥面横铺板纹。低饱和木色,仍为 slot 5 单格、尺寸不变,不改位置/通行。 + # P64 桥(整改):栏杆须在 1x 俯瞰下与桥面木色差 >= 2 档,故改用「深墨栏杆体 + 暖亮扶手线 + + # 亮色望柱」三段对比:桥面 (119,76,47) 为中间调,栏杆体远暗、扶手/望柱远亮。仍为 slot5 单格。 x0 = slot(5) c.rect(x0, 0, 32, 32, wood) + # 桥面栈板(保留中间调木色) for y in (0, 8, 16, 24): - c.rect(x0 + 5, y, 22, 1, wood_light) + c.rect(x0 + 6, y, 20, 1, wood_light) for y in (7, 15, 23, 31): - c.rect(x0 + 5, y, 22, 1, wood_dark) - bridge_rail = (132, 84, 52, 255) - bridge_rail_light = (176, 122, 71, 255) - bridge_rail_dark = (83, 52, 39, 255) + c.rect(x0 + 6, y, 20, 1, wood_dark) + bridge_rail_ink = (34, 28, 30, 255) + bridge_rail_light = (214, 196, 158, 255) bridge_kerb = (150, 146, 138, 255) - for bx in (1, 27): - c.rect(x0 + bx, 0, 4, 32, bridge_rail) - c.rect(x0 + bx, 0, 1, 32, bridge_rail_light) - c.rect(x0 + bx + 3, 0, 1, 32, bridge_rail_dark) - for by in (2, 10, 18, 26): - c.rect(x0 + 1, by, 5, 3, bridge_rail_dark) - c.rect(x0 + 27, by, 5, 3, bridge_rail_dark) - for bx in (5, 26): + for bx in (1, 26): + # 通长栏杆体(深墨,宽 5px) + c.rect(x0 + bx, 0, 5, 32, bridge_rail_ink) + # 扶手亮线(沿栏杆全长,与桥面亮 2 档以上) + c.rect(x0 + bx + 1, 0, 1, 32, bridge_rail_light) + # 望柱:每格两根,暖亮柱头压住深墨栏体 + for by in (1, 17): + c.rect(x0 + bx, by, 5, 5, bridge_rail_light) + c.rect(x0 + bx, by + 5, 5, 1, bridge_rail_ink) + # 桥面与栏杆交界的石缘 + for bx in (6, 25): c.rect(x0 + bx, 0, 1, 32, bridge_kerb) x0 = slot(6) |
