diff --git a/extensions/renderers/unity/plates/crypt_kit_v1_registered.png b/extensions/renderers/unity/plates/crypt_kit_v1_registered.png new file mode 100644 index 00000000..849f474e Binary files /dev/null and b/extensions/renderers/unity/plates/crypt_kit_v1_registered.png differ diff --git a/extensions/renderers/unity/plates_manifest.json b/extensions/renderers/unity/plates_manifest.json index 9c291521..02621673 100644 --- a/extensions/renderers/unity/plates_manifest.json +++ b/extensions/renderers/unity/plates_manifest.json @@ -3,14 +3,53 @@ "_comment": "WALKABLE-SLICE-V1 item 6 (W5e runtime plate registry; docs/roadmap/W5E-PLATE-REGISTRY-DECISION.md). Keys are the ENGINE location.id the surface carries (viewer/server.py _session_location -> surface.location.id), the SAME keying the editor-time _location_plates.json already uses. `plate` is a path under StreamingAssets (BuildMacOSPlayer.EnsurePackaged copies this file + plates/*.png from the Unity project root). planeSize + cameraPin are OPTIONAL: absent => the client derives the plane from the plate aspect (oh=2*orthoSize, ow=oh*aspect) and leaves the scene camera as-is (crypt + camp share the ortho=13 / pitch=30 / yaw=45 rig). Adding a room later = one entry here + drop the PNG under plates/. On the box, CONFIRM these keys against the smoke campaign's real location.id (curl /combat-surface | jq .location.id in each room) and rename if they differ.", "plates": { "crypt": { - "plate": "plates/crypt_v36_registered.png", + "plate": "plates/crypt_kit_v1_registered.png", "cameraPin": { "ortho": 11.7851, "pitch": 30, "yaw": 45 }, "boxes": "boxes/crypt_v36_boxes.json", - "_provenance": "SHIP-THREE-PLATES (2026-07-15, owner 'ship it'): crypt v3.6 16x12 via qa/paint_room.py (recipe qa/unified_paint_recipes.json; base seed 12346 recall 0.9595; Gemini structure-lock). Blind panel 8.3 vs PoE2 control 9.4 / incumbent 7.2 (qa/evidence/paint-room/restored_pipeline_panel.json). Boxes sidecar = the EXACT conditioning volumes (UNIFY-THE-FRAMES). Geometry qa/room_geometries/crypt_v36_geometry.json; ortho = _fit_ortho_size(16,12)." + "effects": [ + { + "type": "fire_medium", + "cell": [ + 5, + 1 + ], + "scale": 0.8, + "y": 1.2 + }, + { + "type": "fire_medium", + "cell": [ + 14, + 4 + ], + "scale": 0.8, + "y": 1.2 + }, + { + "type": "fire_medium", + "cell": [ + 6, + 5 + ], + "scale": 0.8, + "y": 1.2 + }, + { + "type": "fire_medium", + "cell": [ + 10, + 5 + ], + "scale": 0.8, + "y": 1.2 + } + ], + "_effects_comment": "Animated fire over the four painted brazier fires (geometry brazier cells; bowls sit ~1.2u up the stem). Tune scale/y at the sandbox eyeball if the flame floats or washes the paint.", + "_provenance": "KIT-CRYPT v1 (2026-07-23, #83/#84 nav-truth spike): 3D-FIRST CERTIFIED CHAIN \u2014 geometry crypt_v36 -> build_room_kit scene (footprint SEG GATE 100.00%, 0/192 disagreements, qa/evidence/kit-crypt/) -> kit 3D depth -> flux depth-CN base seed 12346 (recall 0.9752, asset_qM9R3tuRH4sceUrVjCoLdPRk) -> Gemini 3.0 Pro edit (model_google-gemini-pro-image-editing, critique-targeted detail prompt, job_Lmhssjh7iWnHsUKY1dhnHB4m) -> phase-corr ALIGNED dx=0,dy=0 vs base (qa/styled_align_check.py) -> geometric void composite (seg-frame mask). Blind panel 7 vs control 8 (delta -1.0, in-band; wf_89967920). Collision truth UNCHANGED (same geometry/walkmask/boxes as crypt_v36). NOTE: model_google-gemini-pro-image-editing pending model-registry allowlist (owner sign-off)." }, "camp_clearing_night": { "plate": "plates/camp_clearing_night_truegrey_v1.png", @@ -40,9 +79,19 @@ "yaw": 45 }, "boxes": "boxes/tavern_v2_boxes.json", - "_door_hotspots_comment": "#1585/#1647 PAINTED-DOOR HOTSPOTS (plate-pixel click targets in the 1344x768 registered plate). Measured 2026-07-22 by overlaying the contract-camera cell projection (qa/walk_test.world_to_window_px at texW/texH) on tavern_v2_registered.png and reading the PAINTED arch centroid off a 50px grid (artifacts/zoom_tavern_left.png). door_cell (7,0) projects to px (440,242) at the bar, but the room's one painted STONE ARCHWAY (dark interior) sits on the SAME back-left (r=0) wall with its opening centroid at ~(210,320) — a large ~4.5-cell #1585 divergence, the exact 'no functional doors' case: clicking the visible arch now crosses at (7,0). door_cell (13,5) lands on the painted fireplace/hearth (no arch) -> intentionally omitted (TODO, see PR body).", + "_door_hotspots_comment": "#1585/#1647 PAINTED-DOOR HOTSPOTS (plate-pixel click targets in the 1344x768 registered plate). Measured 2026-07-22 by overlaying the contract-camera cell projection (qa/walk_test.world_to_window_px at texW/texH) on tavern_v2_registered.png and reading the PAINTED arch centroid off a 50px grid (artifacts/zoom_tavern_left.png). door_cell (7,0) projects to px (440,242) at the bar, but the room's one painted STONE ARCHWAY (dark interior) sits on the SAME back-left (r=0) wall with its opening centroid at ~(210,320) \u2014 a large ~4.5-cell #1585 divergence, the exact 'no functional doors' case: clicking the visible arch now crosses at (7,0). door_cell (13,5) lands on the painted fireplace/hearth (no arch) -> intentionally omitted (TODO, see PR body).", "door_hotspots": [ - { "door_cell": [7, 0], "px": [210, 320], "radius_px": 85 } + { + "door_cell": [ + 7, + 0 + ], + "px": [ + 210, + 320 + ], + "radius_px": 85 + } ], "_provenance": "SHIP-THREE-PLATES (2026-07-15): tavern v2 14x11 molded (bar/table kinds) via qa/paint_room.py. Panel 8.4. Geometry qa/room_geometries/tavern_v2_geometry.json; ortho = _fit_ortho_size(14,11). Replaces tavern_fit2_v1 (12x10, ortho 9.2597)." }, @@ -64,9 +113,19 @@ "yaw": 45 }, "boxes": "boxes/shop_v1_boxes.json", - "_door_hotspots_comment": "#1585/#1647 PAINTED-DOOR HOTSPOTS (plate-pixel click targets in the 1344x768 registered plate; a click inside a hotspot routes exactly like clicking door_cell -> cross_door). Measured 2026-07-22 by overlaying the contract-camera cell projection (qa/walk_test.world_to_window_px at texW/texH) on shop_v1_registered.png and reading the PAINTED arch centroid off a 50px grid (artifacts/zoom_shop_door12_5.png). door_cell (12,5) projects to px (1037,230) but the painted dark archway opening centroid sits at ~(900,275) — the ~2-cell #1585 divergence. door_cell (6,0) is occluded by the potion shelf (no visible arch) -> intentionally omitted (TODO, see PR body).", + "_door_hotspots_comment": "#1585/#1647 PAINTED-DOOR HOTSPOTS (plate-pixel click targets in the 1344x768 registered plate; a click inside a hotspot routes exactly like clicking door_cell -> cross_door). Measured 2026-07-22 by overlaying the contract-camera cell projection (qa/walk_test.world_to_window_px at texW/texH) on shop_v1_registered.png and reading the PAINTED arch centroid off a 50px grid (artifacts/zoom_shop_door12_5.png). door_cell (12,5) projects to px (1037,230) but the painted dark archway opening centroid sits at ~(900,275) \u2014 the ~2-cell #1585 divergence. door_cell (6,0) is occluded by the potion shelf (no visible arch) -> intentionally omitted (TODO, see PR body).", "door_hotspots": [ - { "door_cell": [12, 5], "px": [900, 275], "radius_px": 85 } + { + "door_cell": [ + 12, + 5 + ], + "px": [ + 900, + 275 + ], + "radius_px": 85 + } ], "_provenance": "ROOM-READINESS SCALE PROOF (2026-07-16, epic #1581/#1588): the first room authored AFTER the pipeline existed, run hands-off end-to-end \u2014 author_shop() 13x10 (design-gated 2x locally) -> build_room_unified on the box (ortho 9.6806, 49 boxes incl. auto door frames) -> qa/paint_room.py shop (base seed 12347 recall 0.9555; Gemini structure-lock) -> blind panel 6 vs PoE2 control 8, delta -2.0 IN-BAND (tier=stable, cycle-2 levers in qa/evidence/paint-room/shop/panel.json). Geometry qa/room_geometries/shop_geometry.json; ortho = _fit_ortho_size(13,10). Walk gate: #1596 sandbox lane after the player rebuild packages this entry." }, @@ -110,4 +169,4 @@ "boxes": "boxes/dwing_room_1_v1_boxes.json" } } -} +} \ No newline at end of file diff --git a/qa/evidence/kit-crypt/seg_100pct.png b/qa/evidence/kit-crypt/seg_100pct.png new file mode 100644 index 00000000..7903a302 Binary files /dev/null and b/qa/evidence/kit-crypt/seg_100pct.png differ diff --git a/qa/evidence/kit-crypt/seg_registration.json b/qa/evidence/kit-crypt/seg_registration.json new file mode 100644 index 00000000..385768bf --- /dev/null +++ b/qa/evidence/kit-crypt/seg_registration.json @@ -0,0 +1,1954 @@ +{ + "room": "crypt", + "plate": "kit_crypt_r8d_score.png", + "ortho": 11.7851, + "bar": 0.99, + "block_threshold": 1.85, + "agreement_pct": 100.0, + "passed": true, + "scored_cells": 192, + "box_cells": 0, + "invisible_wall_cells": [], + "walkthrough_cells": [], + "counts": { + "invisible_wall": 0, + "walkthrough": 0 + }, + "baseline": { + "base_rgb": [ + 235.0, + 235.0, + 235.0 + ], + "base_edge": 0.0, + "base_luma_std": 0.0, + "clean_floor_cells": 115, + "scales": { + "color": 16.0, + "edge": 0.035, + "var": 7.0 + } + }, + "per_cell": [ + { + "cell": [ + 0, + 0 + ], + "collision": true, + "painted_blocking": true, + "score": 6.232, + "class": "agree" + }, + { + "cell": [ + 0, + 1 + ], + "collision": true, + "painted_blocking": true, + "score": 6.229, + "class": "agree" + }, + { + "cell": [ + 0, + 2 + ], + "collision": true, + "painted_blocking": true, + "score": 6.229, + "class": "agree" + }, + { + "cell": [ + 0, + 3 + ], + "collision": true, + "painted_blocking": true, + "score": 6.229, + "class": "agree" + }, + { + "cell": [ + 0, + 4 + ], + "collision": true, + "painted_blocking": true, + "score": 6.229, + "class": "agree" + }, + { + "cell": [ + 0, + 5 + ], + "collision": true, + "painted_blocking": true, + "score": 6.226, + "class": "agree" + }, + { + "cell": [ + 0, + 6 + ], + "collision": true, + "painted_blocking": true, + "score": 6.226, + "class": "agree" + }, + { + "cell": [ + 0, + 7 + ], + "collision": true, + "painted_blocking": true, + "score": 6.246, + "class": "agree" + }, + { + "cell": [ + 0, + 8 + ], + "collision": true, + "painted_blocking": true, + "score": 6.246, + "class": "agree" + }, + { + "cell": [ + 0, + 9 + ], + "collision": true, + "painted_blocking": true, + "score": 6.246, + "class": "agree" + }, + { + "cell": [ + 0, + 10 + ], + "collision": true, + "painted_blocking": true, + "score": 6.247, + "class": "agree" + }, + { + "cell": [ + 0, + 11 + ], + "collision": true, + "painted_blocking": true, + "score": 6.247, + "class": "agree" + }, + { + "cell": [ + 1, + 0 + ], + "collision": true, + "painted_blocking": true, + "score": 6.218, + "class": "agree" + }, + { + "cell": [ + 1, + 1 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 1, + 2 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 1, + 3 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 1, + 4 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 1, + 5 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 1, + 6 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 1, + 7 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 1, + 8 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 1, + 9 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 1, + 10 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 1, + 11 + ], + "collision": true, + "painted_blocking": true, + "score": 6.273, + "class": "agree" + }, + { + "cell": [ + 2, + 0 + ], + "collision": true, + "painted_blocking": true, + "score": 6.206, + "class": "agree" + }, + { + "cell": [ + 2, + 1 + ], + "collision": true, + "painted_blocking": true, + "score": 4.176, + "class": "agree" + }, + { + "cell": [ + 2, + 2 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 2, + 3 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 2, + 4 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 2, + 5 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 2, + 6 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 2, + 7 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 2, + 8 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 2, + 9 + ], + "collision": true, + "painted_blocking": true, + "score": 3.819, + "class": "agree" + }, + { + "cell": [ + 2, + 10 + ], + "collision": true, + "painted_blocking": true, + "score": 4.584, + "class": "agree" + }, + { + "cell": [ + 2, + 11 + ], + "collision": true, + "painted_blocking": true, + "score": 6.282, + "class": "agree" + }, + { + "cell": [ + 3, + 0 + ], + "collision": true, + "painted_blocking": true, + "score": 6.206, + "class": "agree" + }, + { + "cell": [ + 3, + 1 + ], + "collision": true, + "painted_blocking": true, + "score": 3.897, + "class": "agree" + }, + { + "cell": [ + 3, + 2 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 3, + 3 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 3, + 4 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 3, + 5 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 3, + 6 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 3, + 7 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 3, + 8 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 3, + 9 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 3, + 10 + ], + "collision": true, + "painted_blocking": true, + "score": 3.572, + "class": "agree" + }, + { + "cell": [ + 3, + 11 + ], + "collision": true, + "painted_blocking": true, + "score": 6.273, + "class": "agree" + }, + { + "cell": [ + 4, + 0 + ], + "collision": true, + "painted_blocking": true, + "score": 6.206, + "class": "agree" + }, + { + "cell": [ + 4, + 1 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 4, + 2 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 4, + 3 + ], + "collision": true, + "painted_blocking": true, + "score": 5.486, + "class": "agree" + }, + { + "cell": [ + 4, + 4 + ], + "collision": true, + "painted_blocking": true, + "score": 5.494, + "class": "agree" + }, + { + "cell": [ + 4, + 5 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 4, + 6 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 4, + 7 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 4, + 8 + ], + "collision": true, + "painted_blocking": true, + "score": 5.371, + "class": "agree" + }, + { + "cell": [ + 4, + 9 + ], + "collision": true, + "painted_blocking": true, + "score": 5.335, + "class": "agree" + }, + { + "cell": [ + 4, + 10 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 4, + 11 + ], + "collision": true, + "painted_blocking": true, + "score": 6.273, + "class": "agree" + }, + { + "cell": [ + 5, + 0 + ], + "collision": true, + "painted_blocking": true, + "score": 6.207, + "class": "agree" + }, + { + "cell": [ + 5, + 1 + ], + "collision": true, + "painted_blocking": true, + "score": 6.907, + "class": "agree" + }, + { + "cell": [ + 5, + 2 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 5, + 3 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 5, + 4 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 5, + 5 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 5, + 6 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 5, + 7 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 5, + 8 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 5, + 9 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 5, + 10 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 5, + 11 + ], + "collision": true, + "painted_blocking": true, + "score": 6.252, + "class": "agree" + }, + { + "cell": [ + 6, + 0 + ], + "collision": true, + "painted_blocking": true, + "score": 6.207, + "class": "agree" + }, + { + "cell": [ + 6, + 1 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 6, + 2 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 6, + 3 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 6, + 4 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 6, + 5 + ], + "collision": true, + "painted_blocking": true, + "score": 7.132, + "class": "agree" + }, + { + "cell": [ + 6, + 6 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 6, + 7 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 6, + 8 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 6, + 9 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 6, + 10 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 6, + 11 + ], + "collision": true, + "painted_blocking": true, + "score": 6.235, + "class": "agree" + }, + { + "cell": [ + 7, + 0 + ], + "collision": false, + "painted_blocking": false, + "score": 0.09, + "class": "agree" + }, + { + "cell": [ + 7, + 1 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 7, + 2 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 7, + 3 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 7, + 4 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 7, + 5 + ], + "collision": true, + "painted_blocking": true, + "score": 5.38, + "class": "agree" + }, + { + "cell": [ + 7, + 6 + ], + "collision": true, + "painted_blocking": true, + "score": 5.364, + "class": "agree" + }, + { + "cell": [ + 7, + 7 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 7, + 8 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 7, + 9 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 7, + 10 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 7, + 11 + ], + "collision": true, + "painted_blocking": true, + "score": 6.235, + "class": "agree" + }, + { + "cell": [ + 8, + 0 + ], + "collision": true, + "painted_blocking": true, + "score": 6.207, + "class": "agree" + }, + { + "cell": [ + 8, + 1 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 8, + 2 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 8, + 3 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 8, + 4 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 8, + 5 + ], + "collision": true, + "painted_blocking": true, + "score": 6.185, + "class": "agree" + }, + { + "cell": [ + 8, + 6 + ], + "collision": true, + "painted_blocking": true, + "score": 6.254, + "class": "agree" + }, + { + "cell": [ + 8, + 7 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 8, + 8 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 8, + 9 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 8, + 10 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 8, + 11 + ], + "collision": true, + "painted_blocking": true, + "score": 6.235, + "class": "agree" + }, + { + "cell": [ + 9, + 0 + ], + "collision": true, + "painted_blocking": true, + "score": 6.207, + "class": "agree" + }, + { + "cell": [ + 9, + 1 + ], + "collision": true, + "painted_blocking": true, + "score": 4.037, + "class": "agree" + }, + { + "cell": [ + 9, + 2 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 9, + 3 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 9, + 4 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 9, + 5 + ], + "collision": true, + "painted_blocking": true, + "score": 5.384, + "class": "agree" + }, + { + "cell": [ + 9, + 6 + ], + "collision": true, + "painted_blocking": true, + "score": 5.371, + "class": "agree" + }, + { + "cell": [ + 9, + 7 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 9, + 8 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 9, + 9 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 9, + 10 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 9, + 11 + ], + "collision": true, + "painted_blocking": true, + "score": 6.235, + "class": "agree" + }, + { + "cell": [ + 10, + 0 + ], + "collision": true, + "painted_blocking": true, + "score": 6.207, + "class": "agree" + }, + { + "cell": [ + 10, + 1 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 10, + 2 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 10, + 3 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 10, + 4 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 10, + 5 + ], + "collision": true, + "painted_blocking": true, + "score": 6.988, + "class": "agree" + }, + { + "cell": [ + 10, + 6 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 10, + 7 + ], + "collision": true, + "painted_blocking": true, + "score": 3.572, + "class": "agree" + }, + { + "cell": [ + 10, + 8 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 10, + 9 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 10, + 10 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 10, + 11 + ], + "collision": true, + "painted_blocking": true, + "score": 6.235, + "class": "agree" + }, + { + "cell": [ + 11, + 0 + ], + "collision": true, + "painted_blocking": true, + "score": 6.215, + "class": "agree" + }, + { + "cell": [ + 11, + 1 + ], + "collision": true, + "painted_blocking": true, + "score": 3.99, + "class": "agree" + }, + { + "cell": [ + 11, + 2 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 11, + 3 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 11, + 4 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 11, + 5 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 11, + 6 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 11, + 7 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 11, + 8 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 11, + 9 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 11, + 10 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 11, + 11 + ], + "collision": true, + "painted_blocking": true, + "score": 6.239, + "class": "agree" + }, + { + "cell": [ + 12, + 0 + ], + "collision": true, + "painted_blocking": true, + "score": 6.215, + "class": "agree" + }, + { + "cell": [ + 12, + 1 + ], + "collision": true, + "painted_blocking": true, + "score": 3.572, + "class": "agree" + }, + { + "cell": [ + 12, + 2 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 12, + 3 + ], + "collision": true, + "painted_blocking": true, + "score": 5.567, + "class": "agree" + }, + { + "cell": [ + 12, + 4 + ], + "collision": true, + "painted_blocking": true, + "score": 5.577, + "class": "agree" + }, + { + "cell": [ + 12, + 5 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 12, + 6 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 12, + 7 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 12, + 8 + ], + "collision": true, + "painted_blocking": true, + "score": 5.571, + "class": "agree" + }, + { + "cell": [ + 12, + 9 + ], + "collision": true, + "painted_blocking": true, + "score": 5.555, + "class": "agree" + }, + { + "cell": [ + 12, + 10 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 12, + 11 + ], + "collision": true, + "painted_blocking": true, + "score": 6.239, + "class": "agree" + }, + { + "cell": [ + 13, + 0 + ], + "collision": true, + "painted_blocking": true, + "score": 6.214, + "class": "agree" + }, + { + "cell": [ + 13, + 1 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 13, + 2 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 13, + 3 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 13, + 4 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 13, + 5 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 13, + 6 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 13, + 7 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 13, + 8 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 13, + 9 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 13, + 10 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 13, + 11 + ], + "collision": true, + "painted_blocking": true, + "score": 6.253, + "class": "agree" + }, + { + "cell": [ + 14, + 0 + ], + "collision": true, + "painted_blocking": true, + "score": 6.214, + "class": "agree" + }, + { + "cell": [ + 14, + 1 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 14, + 2 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 14, + 3 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 14, + 4 + ], + "collision": true, + "painted_blocking": true, + "score": 6.885, + "class": "agree" + }, + { + "cell": [ + 14, + 5 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 14, + 6 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 14, + 7 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 14, + 8 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 14, + 9 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 14, + 10 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 14, + 11 + ], + "collision": true, + "painted_blocking": true, + "score": 6.253, + "class": "agree" + }, + { + "cell": [ + 15, + 0 + ], + "collision": true, + "painted_blocking": true, + "score": 6.214, + "class": "agree" + }, + { + "cell": [ + 15, + 1 + ], + "collision": true, + "painted_blocking": true, + "score": 6.435, + "class": "agree" + }, + { + "cell": [ + 15, + 2 + ], + "collision": true, + "painted_blocking": true, + "score": 6.422, + "class": "agree" + }, + { + "cell": [ + 15, + 3 + ], + "collision": true, + "painted_blocking": true, + "score": 6.422, + "class": "agree" + }, + { + "cell": [ + 15, + 4 + ], + "collision": true, + "painted_blocking": true, + "score": 6.422, + "class": "agree" + }, + { + "cell": [ + 15, + 5 + ], + "collision": false, + "painted_blocking": false, + "score": 0.0, + "class": "agree" + }, + { + "cell": [ + 15, + 6 + ], + "collision": true, + "painted_blocking": true, + "score": 6.419, + "class": "agree" + }, + { + "cell": [ + 15, + 7 + ], + "collision": true, + "painted_blocking": true, + "score": 6.42, + "class": "agree" + }, + { + "cell": [ + 15, + 8 + ], + "collision": true, + "painted_blocking": true, + "score": 6.42, + "class": "agree" + }, + { + "cell": [ + 15, + 9 + ], + "collision": true, + "painted_blocking": true, + "score": 6.42, + "class": "agree" + }, + { + "cell": [ + 15, + 10 + ], + "collision": true, + "painted_blocking": true, + "score": 6.42, + "class": "agree" + }, + { + "cell": [ + 15, + 11 + ], + "collision": true, + "painted_blocking": true, + "score": 6.421, + "class": "agree" + } + ] +} \ No newline at end of file diff --git a/qa/styled_align_check.py b/qa/styled_align_check.py new file mode 100644 index 00000000..3176f65c --- /dev/null +++ b/qa/styled_align_check.py @@ -0,0 +1,52 @@ +"""Global alignment of a styled plate vs its depth-proven flux base (kit pipeline styled-layer gate v0). +Pure numpy: FFT phase correlation for translation at several candidate scales; reports the best +(scale, dx, dy) and the response strength. Styled plate inherits the base's registration iff the +best transform is near-identity (|dx|,|dy| <= 10px ~ 0.2 cell at ortho 11.79, scale within 2%).""" +import sys, numpy as np +from PIL import Image + +def luma(p, size=(1344, 768)): + im = Image.open(p).convert('L') + if im.size != size: im = im.resize(size, Image.LANCZOS) + a = np.asarray(im, dtype=np.float64) + a -= a.mean(); s = a.std(); + return a / s if s > 0 else a + +def phasecorr(a, b): + # hann window to suppress edge wrap + wy = np.hanning(a.shape[0])[:, None]; wx = np.hanning(a.shape[1])[None, :] + A = np.fft.rfft2(a * wy * wx); B = np.fft.rfft2(b * wy * wx) + R = A * np.conj(B); R /= np.abs(R) + 1e-9 + r = np.fft.irfft2(R, a.shape) + peak = np.unravel_index(np.argmax(r), r.shape) + dy, dx = peak + if dy > a.shape[0] // 2: dy -= a.shape[0] + if dx > a.shape[1] // 2: dx -= a.shape[1] + return dx, dy, float(r.max()) + +def scaled(img, s): + if abs(s - 1.0) < 1e-6: return img + h, w = img.shape + im = Image.fromarray(((img - img.min()) / (np.ptp(img) + 1e-9) * 255).astype(np.uint8)) + sw, sh = int(round(w * s)), int(round(h * s)) + im = im.resize((sw, sh), Image.LANCZOS) + a = np.asarray(im, dtype=np.float64) + # center-crop or pad back to (h, w) + out = np.zeros((h, w)); ys = max(0, (sh - h)//2); xs = max(0, (sw - w)//2) + yd = max(0, (h - sh)//2); xd = max(0, (w - sw)//2) + ch = min(h, sh); cw = min(w, sw) + out[yd:yd+ch, xd:xd+cw] = a[ys:ys+ch, xs:xs+cw] + out -= out.mean(); s2 = out.std() + return out / s2 if s2 > 0 else out + +base = luma(sys.argv[1]) +for cand_path in sys.argv[2:]: + cand = luma(cand_path) + best = None + for s in (0.94, 0.97, 1.0, 1.03, 1.06): + dx, dy, resp = phasecorr(scaled(cand, s), base) + if best is None or resp > best[3]: best = (s, dx, dy, resp) + s, dx, dy, resp = best + ok = abs(dx) <= 10 and abs(dy) <= 10 and abs(s - 1.0) <= 0.02 + name = cand_path.split('/')[-1] + print(f"{name}: scale={s} dx={dx} dy={dy} resp={resp:.3f} -> {'ALIGNED' if ok else 'GLOBAL-TRANSFORM'}")