SMC Affine Estimate Drift
Stop eyeballing it — here's the actual scale and translation drift.
- anchor_image
- target_image
- mask
- scale_x
- scale_y
- scale_iso
- compaction
- translation_x_px
- translation_y_px
- stats_json
SMC Affine Estimate Drift (class SMCAffineEstimate) is the diagnostic node of the pack. It compares a low-res anchor against a high-res target and returns a set of numbers describing how the target drifted: scale, compaction, and translation. It doesn't correct anything - it measures, so you can see what the correction path is reacting to.
The mechanism is a moment-based affine estimate. Both images get Gaussian-blurred with stable_sigma (default 8), a structure feature (blurred Sobel gradient + luminance deviation, weighted by the mask interior) is computed, and the weighted centroids and covariance matrices are compared. The ratio of the anchor's structure spread to the target's becomes the drift readout, clamped so it can't go nuts. All of it runs on the low-frequency content, because that's where drift lives.
Inputs
anchor_imageandtarget_image- the stable low-res reference and the drifted high-res result. The anchor is auto-resized to match the target, so mismatched resolutions aren't fatal.stable_sigma(0–64, default 8) - blur for the comparison; higher = more tolerant of detail differences, so it measures big-picture drift.boundary_feather_px(18),geometry_strength(1),max_shrink(0.05),max_expand(0),anisotropy(0.2) - the same profile-style knobs, inline; they shape how the estimate is clamped and scaled.mask(optional) - restrict the estimate to a region. No mask = whole frame.
The numbers that matter
scale_x/scale_y/scale_iso(FLOAT) - the estimated scale from target to anchor. Below 1.0 means the high-res output read as bigger/flatter than the anchor - the outward drift. Above 1.0 would mean it shrank.compaction(FLOAT) -1/det(A). Above 1.0 means content spread out and needs pulling in to match the anchor. This is the number the affine compand acts on.translation_x_px/translation_y_px(FLOAT) - how far the structure centroid shifted, in pixels.stats_json(STRING) - the same numbers plus the full affine matrix, as JSON.
Use it like this
Wire the outputs into a Show Text node (or read stats_json) and you get an actual measurement instead of a guess. A face detail pass that expanded 4% will show scale_iso ≈ 0.96 and compaction ≈ 1.04 - and then you know exactly why SMC Affine Compand is about to shrink things. If the numbers come back at ~1.0, there's nothing to correct, and you can stop fighting the workflow.
Install & gotchas
Same pack, trivial install:
cd ComfyUI/custom_nodes
git clone https://github.com/xmarre/ComfyUI-StableManifoldCompander
or ComfyUI Manager (search "Stable Manifold Compander"). No extra dependencies. The one thing to keep in mind: this is a heuristic moment-based estimate, not optical flow - if the content changed structurally (new elements, big inpaint), the numbers describe average spread, not per-pixel truth. Read them as a trend, not a verdict.
Inputs (9)
| Name | Type | Default | Description |
|---|---|---|---|
| anchor_image | IMAGE | — | |
| target_image | IMAGE | — | |
| stable_sigma | FLOAT | 8.00–64 | — |
| boundary_feather_px | FLOAT | 18.00–256 | — |
| geometry_strength | FLOAT | 1.000–2 | — |
| max_shrink | FLOAT | 0.0500–0.25 | — |
| max_expand | FLOAT | 0.0000–0.25 | — |
| anisotropy | FLOAT | 0.200–1 | — |
| maskopt | MASK | — |
Outputs (7)
| Name | Type | Description |
|---|---|---|
| scale_x | FLOAT | — |
| scale_y | FLOAT | — |
| scale_iso | FLOAT | — |
| compaction | FLOAT | — |
| translation_x_px | FLOAT | — |
| translation_y_px | FLOAT | — |
| stats_json | STRING | — |