Reads a screenshot of the in-game map table and recovers where on the board it is looking. The scene is a flat table under a perspective camera, so a single homography describes grid<->screen exactly; that is fitted from line evidence (LSD segments, vanishing-point RANSAC, 1-D lattice fits). Line evidence alone cannot finish the job: the 1km cells and the 100m subgrid are locally identical, so it fixes neither scale, axis assignment, axis direction nor phase. Those come from the cell labels -- and the labels are never *detected*, they are correlated where the grid says they must be (9% in from a cell's left edge, 6% down from its top). Blob detection on aerial-photo terrain finds texture, not glyphs; correlating a known template at a known place has no such failure mode. The same score then ranks the geometry hypotheses, since a wrong lattice puts the crop where no label is, so one number resolves scale, axis assignment, direction, phase and anchor together. Markers are found by hostile/friendly colour plus an IoU test against an ideal inscribed diamond, which cut a red-lit shot from 43 false positives to 2 while preserving every hand-verified count. Unit-type classification is present but not yet reliable, and returns unknown rather than guessing. Measured over the fixture set: 7 of 10 solve, each with 100% of its ground-truth points in the correct cell (85/112 overall), residual spread 0.005-0.033 cells. The other three reject cleanly; none has ever produced a plausible-but-wrong grid. Across 122 typewriter screenshots solve() accepted none, which is what makes clipboard routing safe. Fixtures: 10 map shots with hand-transcribed ground truth, plus 10 typewriter shots spanning 262-5366px for routing and future OCR tests. Map shots wider than 2400px (the pipeline's own maximum working width) were downscaled with their coordinates rescaled to match; re-measured afterwards, the results are identical. Typewriter shots stay at native resolution because OCR needs the text legible. Drops docs/map_vision_plan.md and its WIP prototype: the design now lives in the module docstring, next to the code it describes. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
37 lines
1.6 KiB
Markdown
37 lines
1.6 KiB
Markdown
# Test fixtures
|
|
|
|
Real screenshots of the game, used as regression data. They are the game
|
|
author's work, not covered by this repo's MIT license (see `/LICENSE`).
|
|
|
|
## `map_shots/` + `map_shots_gt.json`
|
|
|
|
The evaluation set for the map-grid solver (`src/fenigma/map_vision.py`), scored
|
|
by `tools/eval_map_vision.py`. The JSON holds hand-transcribed cell labels at
|
|
native pixel positions; its own header comment explains the format and the
|
|
9%/6% label-padding constant.
|
|
|
|
Shots wider than 2400px were downscaled to 2400px, and their ground-truth
|
|
coordinates rescaled with them. 2400 is `map_vision.RETRY_WORK_W`, the widest
|
|
the pipeline ever works at, so nothing the code can actually read was lost.
|
|
Measured after the downscale: the same 7 of 10 solve, 100% of their points land
|
|
in the correct cell, residual spread unchanged.
|
|
|
|
`too_hard/` holds shots that are permanent rejections; see its own README.
|
|
|
|
## `writer_shots/`
|
|
|
|
Typewriter/field-log screenshots. Two uses:
|
|
|
|
- Measuring false positives in the map-vs-text routing gate
|
|
(`map_vision.looks_like_map` / `solve`). Over the full 122-shot set the cheap
|
|
gate false-positived on 6% and `solve()` accepted **none**.
|
|
- OCR regression material for `ocr.py`.
|
|
|
|
Kept at NATIVE resolution deliberately: the routing gate only ever sees 1500px,
|
|
but OCR needs the text legible, so these must not be downscaled.
|
|
|
|
Ten shots are committed, chosen to span the capture-scale range (262px to
|
|
5366px wide) since scale is what both the gate and OCR are sensitive to. The
|
|
false-positive numbers above were measured on all 122; this subset is a
|
|
regression guard, not the measurement.
|