HSV Colour-Space Segmentation

find_color_region masks in RGB with a per-channel ± tolerance box, which fails the canonical case: a status light, highlight or theme tint that is “the same colour” but at a different brightness. HSV separates hue from saturation/value, so a hue band with a saturation/value floor catches every shade of a colour across lighting. This adds HSV masking and blob boxes, reusing the shared connected-component helper, with correct hue-wrap handling for red (which straddles the 0/180 boundary).

Runs on an injectable haystack (ndarray / path / PIL, RGB), so it is headless- testable on synthetic arrays. OpenCV + NumPy come in via je_open_cv. Imports no PySide6.

Headless API

from je_auto_control import dominant_hue_regions, segment_hsv, color_mask

# Every red region — bright or dark — regardless of lighting (red wrap handled).
for r in dominant_hue_regions(hue=0, hue_tol=10, sat_min=80, val_min=80):
    click(*r["center"])

# Or an explicit HSV band (H 0-179, S/V 0-255).
greens = segment_hsv(lower_hsv=[40, 80, 80], upper_hsv=[80, 255, 255])
mask = color_mask(lower_hsv=[40, 80, 80], upper_hsv=[80, 255, 255])

dominant_hue_regions constrains only the hue (± hue_tol) plus a sat_min / val_min floor to skip greys, returning {x, y, width, height, area, center} per blob largest first — so it finds a colour at any brightness, unlike the RGB box. segment_hsv takes an explicit lower_hsv / upper_hsv band; color_mask returns the raw uint8 mask.

Executor commands

AC_segment_hsv (lower_hsv / upper_hsv / min_area / region) and AC_dominant_hue_regions (hue / hue_tol / sat_min / val_min / min_area / region), both returning {count, regions, best}. They are exposed as the MCP tools ac_segment_hsv / ac_dominant_hue_regions and as Script Builder commands under Image.