Nodes/ComfyUI-StableManifoldCompander/SMC Affine Estimate Drift
ComfyUI Node

SMC Affine Estimate Drift

Stop eyeballing it — here's the actual scale and translation drift.

By xmarre·Created 6 months ago·Updated 6 months ago· 0
SMC Affine Estimate Drift
  • anchor_image
  • target_image
  • mask
  • scale_x
  • scale_y
  • scale_iso
  • compaction
  • translation_x_px
  • translation_y_px
  • stats_json
stable_sigma8.0
boundary_feather_px18.0
geometry_strength1.00
max_shrink0.050
max_expand0.000
anisotropy0.20

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_image and target_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.

CategoryStableManifoldCompand/Affine

Inputs (9)

NameTypeDefaultDescription
anchor_imageIMAGE
target_imageIMAGE
stable_sigmaFLOAT8.00–64
boundary_feather_pxFLOAT18.00–256
geometry_strengthFLOAT1.000–2
max_shrinkFLOAT0.0500–0.25
max_expandFLOAT0.0000–0.25
anisotropyFLOAT0.200–1
maskoptMASK

Outputs (7)

NameTypeDescription
scale_xFLOAT
scale_yFLOAT
scale_isoFLOAT
compactionFLOAT
translation_x_pxFLOAT
translation_y_pxFLOAT
stats_jsonSTRING