Nodes/ComfyUI-UtilsCollection/Optical Flow Composite (Global Align)
ComfyUI Node

Optical Flow Composite (Global Align)

When your edit model redraws the whole frame, composite it back with optical flow

By silveroxides·Created 2 months ago·Updated about 7 hours ago· 24
Optical Flow Composite (Global Align)
  • original_image
  • generated_image
  • composited_image
  • change_mask
  • report
delta_e_threshold-1
grow_mask_pct0.0
feather_pct2.00
flow_qualitymedium
occlusion_threshold-1.0
close_radius_pct0.5
min_region_pct1.00

Here's the problem this node solves: you take a photo into an edit model like Klein or Flux 2, ask it to change one thing, and it regenerates the entire image. The edit is great, but the background drifted - the wall changed color, the person's head got subtly reshaped, the chair moved. You wanted a localized edit and you got a full redraw with a couple of tweaks. UC_OpticalFlowComposite is the fix: it figures out which pixels actually changed, and composites only those back onto the untouched original.

It's part of silveroxides/ComfyUI-UtilsCollection, and the source calls it exactly what it is: "Composites a Klein edit onto the original image." You connect your original_image and the generated_image (the edited render), and it returns a clean composite where the background comes from the original and only the real edits carry over.

How it works

The node estimates motion between the two images using optical flow - per-pixel, where did the content move? - and uses that to align the generated image to the original (a global rigid alignment that compensates for AI background drift), then finds the edit mask as the regions where pixels changed more than a color-difference threshold (ΔE). Those changed regions are warped and feathered back onto the original. There's also occlusion handling for pixels that moved so much they can't be matched at all.

The knobs that matter

  • delta_e_threshold - how different a pixel's color must be to count as "edited." Higher = only obvious edits, smaller mask, more original preserved. Lower = catches subtle changes. Set to -1 for automatic tuning, which is a genuinely good default.
  • occlusion_threshold - sensitivity to pixels that moved too far to match. -1 also auto-tunes.
  • flow_quality - medium (default), fast, or ultrafast. Higher accuracy costs time; drop to fast for quick previews.
  • grow_mask_pct - expand or shrink the detected edit region as a percentage of the image diagonal. Bump it up if the edit edges are getting clipped.
  • feather_pct - how gradually the edit blends into the original at the boundary. Higher = softer, wider transition.
  • close_radius_pct and min_region_pct - close small holes in the mask and drop tiny stray blobs, respectively.

Outputs

  • composited_image - the result you save.
  • change_mask - the detected edit region, useful if you want to inspect or reuse it.
  • report - a text summary of what it decided: the auto-tuned thresholds, how much of the image changed, flow shift in pixels. Genuinely useful for debugging why a composite looks wrong.

Installing it

Part of the pack:

  • ComfyUI Manager: search "ComfyUI-UtilsCollection".
  • Or:
cd ComfyUI/custom_nodes
git clone https://github.com/silveroxides/ComfyUI-UtilsCollection

Restart ComfyUI. This node leans on OpenCV for the flow estimation, and the pack's opencv-python requirement covers it. No model downloads.

Gotchas

Two things bite people. First, if the two input images have different resolutions, the generated one gets resized to match the original - so feed it the same-size pair when you can. Second, the "edit" definition is color-based: if the model made a big global change (turned a day scene into night), every pixel is "changed" and you'll get the whole generated image, not a localized edit - this node is for local edits that leave most of the frame intact. The report output is the best debug tool here; if a composite looks wrong, read the Changed region percentage. And keep in mind this runs on CPU flow estimation, so big 4K pairs can take a moment - start on fast quality while you're dialing thresholds.

Categoryadvanced/image

Inputs (9)

NameTypeDefaultDescription
original_imageIMAGE
generated_imageIMAGE
delta_e_thresholdFLOAT-1-1–100How different a pixel's color must be to count as 'edited'. Higher values = only obvious edits are detected (smaller mask, more original preserved). Lower values = subtle changes are also captured (larger mask, more of the generated image used). Set to -1 for automatic tuning.
grow_mask_pctFLOAT0.0-3–3Expands or shrinks the detected edit region. Positive values grow the mask outward, capturing more of the surrounding area (useful if edges of the edit are being clipped). Negative values erode the mask inward, trimming the edges (useful if too much background is being pulled in).
feather_pctFLOAT2.000–10How gradually the edit blends into the original at the mask boundary. Higher values create a wider, softer transition (smoother blending, but may wash out fine edges). Lower values create a sharper, more abrupt cutover (crisper edges, but seams may be more visible).
flow_qualityCOMBOmediumAccuracy of the optical flow alignment between original and generated images. Higher quality = more precise change detection and alignment (slower). Lower quality = faster processing but may miss subtle shifts or produce noisier masks.
occlusion_thresholdFLOAT-1.0-1–20Sensitivity to pixels that moved so much they can't be reliably matched between images. Higher values ignore more motion discrepancies (fewer false positives from camera jitter, but may miss real edits). Lower values flag more pixels as changed (catches more edits, but may over-detect in noisy areas). Set to -1 for automatic tuning.
close_radius_pctFLOAT0.50–5Fills small holes and gaps inside the detected edit region. Higher values close larger gaps (creates a more solid, continuous mask). Lower values leave small holes intact (preserves finer mask detail but may leave speckled artifacts inside the edit).
min_region_pctFLOAT1.000–2Removes small isolated blobs from the mask that are likely false positives. Higher values filter out larger stray regions (cleaner mask, but may discard small intentional edits). Lower values keep smaller regions (preserves tiny edits, but may let through noise).

Outputs (3)

NameTypeDescription
composited_imageIMAGE
change_maskMASK
reportSTRING