Add marker id detection; log unit_score/margin; use full-res captures
read_marker_id (map_vision.py) reads each marker's own small "#<N>" id label via template correlation, same approach as read_cell_label and for the same documented reason (this text sits over the same aerial- photo backdrop that defeated detection-based approaches for grid labels). Wired end-to-end: find_markers -> Proposal.detected_id -> save_marker_ground_truth's JSON. Reads against ScreenshotImport's full_image when available, since the id text is tiny. Crop region and threshold are a single-screenshot calibration, not yet validated against real ground truth (documented as such). Also switches save_marker_ground_truth/save_grid_correction to use full_image over the WORK_W-downscaled image, so a human reviewing a capture can actually read the small id text well enough to judge it. Logs unit_score/unit_margin on every Proposal too (previously only pass/fail `unit` was recorded), and measured current type-detection reliability against the 6 existing ground-truth captures: 0/72 (0%) accepted proposals had any confident detected_unit at all, not just wrong guesses -- classify_marker never clears its own confidence floor against real screenshots. Findings and next steps in TODO.md. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -151,12 +151,50 @@ Status legend: [x] fixed+tested, [~] partially addressed, [ ] open/needs input
|
||||
|
||||
## Needs more scope / your input before I keep going
|
||||
|
||||
- [ ] Enemy type detection needs to be more robust; read the entity id
|
||||
- [~] Enemy type detection needs to be more robust; read the entity id
|
||||
label so dedup is reliable; detect death from the log.
|
||||
All three are real computer-vision/OCR feature work (better marker
|
||||
classification in `map_vision.py`'s `classify_marker`, a new OCR pass
|
||||
reading each marker's id label off the map screenshot, and a
|
||||
"<Type>#<id> Destroyed" log-scan tied into a dedup key that includes
|
||||
that read id) rather than bugs with a small fix. Worth its own pass
|
||||
once there's a batch of the `debug_capture` failure/maybe_map
|
||||
screenshots above to develop against.
|
||||
|
||||
Started on the id-reading piece: `map_vision.read_marker_id` reads
|
||||
each marker's own small "#<N>" label (distinct from the big
|
||||
per-cell grid label `read_cell_label` reads) via the SAME template-
|
||||
correlation approach as `read_cell_label`, not OCR -- this text
|
||||
sits over the same aerial-photo backdrop that this module's own
|
||||
docstring says defeated every detection-based approach tried for
|
||||
grid labels, so pytesseract (already tried elsewhere in this repo,
|
||||
`ocr.py`, for a different image domain: flat scanned paper, not
|
||||
photo-textured) was skipped in favor of the approach already proven
|
||||
here. Wired end-to-end: `find_markers` -> `Proposal.detected_id` ->
|
||||
`debug_capture.save_marker_ground_truth`'s JSON. Reads against
|
||||
`ScreenshotImport.full_image` (sharper than the WORK_W image
|
||||
detection itself runs against) when available. Crop region and
|
||||
`MIN_MARKER_ID_SCORE` are a single-screenshot calibration (see
|
||||
`read_marker_id`'s own docstring) -- UNVALIDATED against a real
|
||||
ground-truth batch (none of the 6 existing captures have a
|
||||
confirmed id to check against, they all predate this). New unit
|
||||
tests (`tests/test_map_vision_marker_id.py`) only cover the
|
||||
synthetic-render round-trip, not real-screenshot accuracy.
|
||||
|
||||
Measured type-detection reliability against the 6 existing
|
||||
`marker_ground_truth` captures (72 accepted proposals total,
|
||||
2026-08-13): **0/72 (0%) had ANY confident `detected_unit` guess**
|
||||
-- `classify_marker` returned `None` on every single one, every
|
||||
side, every capture. Not "guesses wrong" -- never confident enough
|
||||
to answer at all. Spot-checked directly against one real marker
|
||||
crop (a hostile Infantry, confirmed by the user): best match was
|
||||
"Underground Fort" at score 0.376 (Infantry wasn't even in the top
|
||||
8), against a `min_score=0.55` floor `classify_marker` requires --
|
||||
not a close miss, a real correlation failure. The clean rendered
|
||||
icon templates `icon_bank()` matches against apparently don't
|
||||
correlate well with how markers actually look in a real screenshot
|
||||
(compression/blur/aerial-photo texture underneath), unlike text
|
||||
glyphs (`read_cell_label`'s measured 0.73-0.87 vs 0.40-0.56) where
|
||||
the same template-correlation idea works well. Added `unit_score`/
|
||||
`unit_margin` to `Proposal`/ground-truth JSON (previously only
|
||||
pass/fail `unit` was logged) so every future capture shows exactly
|
||||
how far off a guess was, not just None -- there was no way to tell
|
||||
"barely missed the bar" from "wildly wrong" before this.
|
||||
|
||||
Death-detection-from-log is still fully unstarted -- no log-parsing
|
||||
code exists in this repo at all yet, real scope work (find/access
|
||||
the game's log, agree a "<Type>#<id> Destroyed" grammar, wire it
|
||||
into a dedup key) rather than a quick pass.
|
||||
|
||||
Reference in New Issue
Block a user