summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSomhairle H. Marisol <[email protected]>2026-09-29 10:42:46 +0800
committerSomhairle H. Marisol <[email protected]>2026-09-29 10:42:46 +0800
commitc1857556fb4c0c3fd684b4261966f5f97ee2ba13 (patch)
treeab955d1b952ae19bf2ef769a3ce407db8762cc2e
parent328760853c15c44d1de915d6c88e0dfd7ddc5af6 (diff)
downloadliving-village-c1857556fb4c0c3fd684b4261966f5f97ee2ba13.tar.gz
p72: 补齐六帧行走证据(含 FrameTwo 独立抽帧)
analyze-p72 改为按帧各取像素相异的独立抽帧;docs/evidence 增 p72-walk-frametwo.png,framesix 换为独立帧。已 add 全部改动,工作树就绪,未 push。
-rw-r--r--docs/evidence/p72-analysis.txt8
-rw-r--r--docs/evidence/p72-walk-framesix.pngbin74665 -> 117053 bytes
-rw-r--r--docs/evidence/p72-walk-frametwo.pngbin0 -> 74665 bytes
-rw-r--r--scripts/analyze-p72.py49
4 files changed, 46 insertions, 11 deletions
diff --git a/docs/evidence/p72-analysis.txt b/docs/evidence/p72-analysis.txt
index 67b1894..ea8f2e0 100644
--- a/docs/evidence/p72-analysis.txt
+++ b/docs/evidence/p72-analysis.txt
@@ -4,7 +4,7 @@ P72(角色行走四向 8 帧:6 走 + 2 待机)证据分析 — 真实 Desk
recorded frames: 41
distinct walk frames observed: ['FrameFive', 'FrameFour', 'FrameOne', 'FrameSix', 'FrameThree', 'FrameTwo']
-walk frame exemplars: FrameFive=p72-walk-0492.png(npc0), FrameFour=p72-walk-0264.png(npc0), FrameOne=p72-walk-0276.png(npc0), FrameSix=p72-walk-0132.png(npc0), FrameThree=p72-walk-0120.png(npc0), FrameTwo=p72-walk-0132.png(npc1)
+walk frame exemplars: FrameFive=p72-walk-0492.png(npc0), FrameFour=p72-walk-0264.png(npc0), FrameOne=p72-walk-0276.png(npc0), FrameSix=p72-walk-0252.png(npc0), FrameThree=p72-walk-0120.png(npc0), FrameTwo=p72-walk-0132.png(npc1)
npcs with observed displacement: 30
npc0 distinct frames: ['FrameFive', 'FrameFour', 'FrameOne', 'FrameSix', 'FrameThree']
@@ -13,17 +13,23 @@ p72-walk-0132.png: size=1280x720 mean=118.5 std=54.2 dark_block=0 white_block=52
p72-walk-0120.png: size=1280x720 mean=87.1 std=34.5 dark_block=0 white_block=32
p72-walk-0264.png: size=1280x720 mean=87.1 std=34.9 dark_block=0 white_block=32
p72-walk-0492.png: size=1280x720 mean=87.3 std=34.9 dark_block=0 white_block=26
+p72-walk-0252.png: size=1280x720 mean=87.1 std=34.8 dark_block=0 white_block=32
diff p72-walk-0276.png vs p72-walk-0132.png: differing_pixels=905924
diff p72-walk-0276.png vs p72-walk-0120.png: differing_pixels=313725
diff p72-walk-0276.png vs p72-walk-0264.png: differing_pixels=242017
diff p72-walk-0276.png vs p72-walk-0492.png: differing_pixels=294080
+diff p72-walk-0276.png vs p72-walk-0252.png: differing_pixels=244428
diff p72-walk-0132.png vs p72-walk-0120.png: differing_pixels=906006
diff p72-walk-0132.png vs p72-walk-0264.png: differing_pixels=905936
diff p72-walk-0132.png vs p72-walk-0492.png: differing_pixels=905931
+diff p72-walk-0132.png vs p72-walk-0252.png: differing_pixels=905769
diff p72-walk-0120.png vs p72-walk-0264.png: differing_pixels=306092
diff p72-walk-0120.png vs p72-walk-0492.png: differing_pixels=241732
+diff p72-walk-0120.png vs p72-walk-0252.png: differing_pixels=288175
diff p72-walk-0264.png vs p72-walk-0492.png: differing_pixels=276242
+diff p72-walk-0264.png vs p72-walk-0252.png: differing_pixels=243494
+diff p72-walk-0492.png vs p72-walk-0252.png: differing_pixels=270079
verdict=PASS
all 6 walk frames exercised; npc0 moved through >=4 frames;
diff --git a/docs/evidence/p72-walk-framesix.png b/docs/evidence/p72-walk-framesix.png
index af5fa25..a121ac3 100644
--- a/docs/evidence/p72-walk-framesix.png
+++ b/docs/evidence/p72-walk-framesix.png
Binary files differ
diff --git a/docs/evidence/p72-walk-frametwo.png b/docs/evidence/p72-walk-frametwo.png
new file mode 100644
index 0000000..af5fa25
--- /dev/null
+++ b/docs/evidence/p72-walk-frametwo.png
Binary files differ
diff --git a/scripts/analyze-p72.py b/scripts/analyze-p72.py
index a9171e0..bd179ca 100644
--- a/scripts/analyze-p72.py
+++ b/scripts/analyze-p72.py
@@ -105,18 +105,47 @@ def main():
if mean > 75.0:
world_pngs.add(rec_["png"])
- # First world PNG per distinct frame, preferring npc 0, else any NPC (stable walkers).
+ # Candidate world PNGs per frame: npc 0 first (stable walker), then other NPCs.
+ candidates = {f: [] for f in ALL_FRAMES}
+ for rec_ in records:
+ if rec_["png"] not in world_pngs:
+ continue
+ ordered = sorted(rec_["npcs"], key=lambda r: 0 if r["npc"] == 0 else 1)
+ for r in ordered:
+ if rec_["png"] not in candidates[r["frame"]]:
+ candidates[r["frame"]].append((rec_["png"], r["npc"]))
+ pix_cache = {}
+
+ def pixel_hash(path):
+ if path not in pix_cache:
+ import hashlib
+ with open(path, "rb") as fh:
+ pix_cache[path] = hashlib.sha256(np.asarray(Image.open(path).convert("RGB")).tobytes()).hexdigest()
+ return pix_cache[path]
+
+ # Greedy: for each frame pick the first candidate whose pixels are distinct from
+ # every already-chosen exemplar (so each cell gets a visually distinct shot).
exemplar = {}
- for want_npc in (0, -1):
- for rec_ in records:
- if rec_["png"] not in world_pngs:
+ used_pngs = set()
+ used_hashes = set()
+ for f in ALL_FRAMES:
+ choice = None
+ for png, npc in candidates[f]:
+ if png in used_pngs:
+ continue
+ if pixel_hash(png) in used_hashes:
continue
- for r in rec_["npcs"]:
- if r["frame"] in exemplar:
- continue
- if want_npc == 0 and r["npc"] != 0:
- continue
- exemplar[r["frame"]] = (rec_["png"], r["npc"])
+ choice = (png, npc)
+ break
+ if choice is None:
+ for png, npc in candidates[f]:
+ if png not in used_pngs:
+ choice = (png, npc)
+ break
+ if choice is not None:
+ exemplar[f] = choice
+ used_pngs.add(choice[0])
+ used_hashes.add(pixel_hash(choice[0]))
lines.append(
"walk frame exemplars: "
+ ", ".join(f"{k}={Path(v[0]).name}(npc{v[1]})" for k, v in sorted(exemplar.items()))