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.