fix(vision): find_rightmost_dot returns cluster centre, not edge

Also: calibrate._sample_rgb now snaps to the most-saturated pixel within 15px
of the click, so rough clicks still pick up the dot's pure colour. Default
dot-colour tolerance bumped 30→60 to absorb anti-aliasing.

Test fixture _SAMPLED_RGB recomputed for the new 36/49 dilution (was 24/49
when sampling at the trailing edge).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Claude Agent
2026-04-16 06:59:47 +00:00
parent 0a4f9793e9
commit 0f430dae21
3 changed files with 53 additions and 20 deletions

View File

@@ -19,17 +19,17 @@ from atm.dryrun import ConfusionMatrix, DryrunResult, dryrun
# so classify_pixel returns the correct label.
# ---------------------------------------------------------------------------
_SCALE = 24 / 49 # fraction of dot pixels in the 7x7 sample box
_SCALE = 36 / 49 # fraction of dot pixels in the 7x7 sample box (centre-based)
# True BGR paint values → sampled RGB ≈ int(true_RGB * _SCALE)
_SAMPLED_RGB: dict[str, tuple[int, int, int]] = {
"turquoise": (0, 97, 97), # true (0, 200, 200)
"yellow": (124, 124, 0), # true (255, 255, 0)
"dark_green": (0, 48, 0), # true (0, 100, 0)
"dark_red": (68, 0, 0), # true (139, 0, 0)
"light_green": (70, 116, 70), # true (144, 238, 144)
"light_red": (124, 89, 94), # true (255, 182, 193)
"gray": (62, 62, 62), # true (128, 128, 128)
"turquoise": (0, 146, 146), # true (0, 200, 200)
"yellow": (187, 187, 0), # true (255, 255, 0)
"dark_green": (0, 73, 0), # true (0, 100, 0)
"dark_red": (102, 0, 0), # true (139, 0, 0)
"light_green": (105, 174, 105), # true (144, 238, 144)
"light_red": (187, 133, 141), # true (255, 182, 193)
"gray": (94, 94, 94), # true (128, 128, 128)
}
# True RGB values used when painting frames (before sampling dilution)