blazediff-interpret
Structured region analysis for image diffs. Given two images and a set of changed regions, it says what changed in each one — not just where.
use ;
// From a pixel diff — what `blazediff` does.
let result = interpret?;
// From a similarity map — what `blazediff-ssim` does.
let result = interpret?;
// From boxes you already have.
let result = interpret?;
println!;
for region in &result.regions
Why it's a separate crate
The classifier is deliberately independent of whatever found the regions. Three producers feed it today:
| Producer | ChangeSource |
How it finds regions |
|---|---|---|
blazediff |
Diff |
connected components over a pixel-diff mask |
blazediff-ssim |
ScoreMap |
thresholding a local SSIM score map |
| your code | Regions |
DOM rectangles, a JS-side diff, a crop list — anything |
All three call the same function and get identical treatment; only the description of where
differs. blazediff and blazediff-ssim are independent of each other, so a classifier living in
either would be unreachable from the other. It sits below both instead.
Coarse regions are fine
A producer only has to know roughly where something changed. Before any statistic is computed, the supplied boxes are refined against the source pixels — every pixel whose YIQ delta falls below the noise floor is dropped — so shape, colour and gradient analysis stay per-pixel no matter how blocky the input was:
// An 8x8 change, described exactly and then quantized to a 16px grid.
let exact = interpret?;
let coarse = interpret?;
assert_eq!; // both 64
That is what makes an SSIM window map a usable region source: its grid is coarse, but the
statistics derived from it are not. diff_count therefore means the same thing on every path —
actually-changed pixels, never windows.
API
| Item | Purpose |
|---|---|
interpret |
the entry point: a ChangeSource in, a full InterpretResult out |
ChangeSource |
Diff (a pixel diff's output + counts), ScoreMap (a similarity map), or Regions |
classify_region / classify_regions |
classify against a mask you already hold |
detect_regions |
connected components over a boolean mask |
extract_change_mask |
recover a mask from an RGBA diff visualization |
detect_shifts |
the shift-relabeling pass, for producers holding an exact mask |
classify_severity, build_summary |
the pooling steps, exposed for custom pipelines |
Regions arriving from a caller are validated: a box outside the image is an
InterpretError::RegionOutOfBounds, not an out-of-bounds panic. That matters now that regions
cross the wasm and N-API boundaries.
What it classifies
Each region gets a change type, a shape, a position, a confidence, and the statistics behind them — colour delta, gradient/edge correlation, fill ratios, and the signals the classifier used. See INTERPRET.md for the full algorithm: pipeline stages, formulas, and classification rules.
License
MIT