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.