Structural-Similarity (SSIM) Comparison
The framework already compares screens by raw pixel diff (diff_screenshots)
and by colour histogram (detect_drift) — but neither is structural. A pixel
diff fires on a one-pixel shift or a brightness change that a human would ignore;
a histogram is blind to layout (swap two halves of the screen and it is
unchanged). SSIM is the standard visual-regression metric: tolerant of small
illumination changes, sensitive to structural change (edited text, moved or
missing elements). ssim_compare returns a single 0..1 score, and
ssim_changed_regions returns the boxes of what actually changed.
It is a pure NumPy + OpenCV implementation (no scikit-image dependency) over an
injectable image pair, so it is unit-testable on synthetic arrays without a real
screen. OpenCV + NumPy come in via je_open_cv. Imports no PySide6.
Headless API
from je_auto_control import ssim_compare, ssim_changed_regions
# Gate a visual regression test against a golden screenshot.
score = ssim_compare("golden.png") # current = live screen
assert score > 0.98
# Ignore a live clock / blinking cursor, then show what moved.
for box in ssim_changed_regions("golden.png", ignore=[[0, 0, 120, 30]]):
print(box["x"], box["y"], box["width"], box["height"])
ssim_compare returns the mean SSIM over the image (1.0 = identical);
current defaults to a screen grab of the optional region. ignore is a
list of [x, y, w, h] boxes excluded from the score and from change detection.
ssim_changed_regions flags pixels where local dissimilarity 1 - SSIM
exceeds threshold, groups the connected ones (min_area and up) and returns
{x, y, width, height, area, center} largest first. Comparing two
different-sized images raises ValueError.
Executor commands
AC_ssim_compare (reference / current / ignore / region →
{score}) and AC_ssim_changed_regions (also threshold / min_area →
{count, regions}). They are exposed as the MCP tools ac_ssim_compare /
ac_ssim_changed_regions and as Script Builder commands under Image.