Image Merge By Pixel Align
Stitch two images that don't quite line up — SIFT alignment plus a clean blend
- base_img
- patch_img
- IMAGE
Most "merge two images" nodes assume the images already line up. Image Merge By Pixel Align is for when they don't, or when you're not sure: it detects feature points with SIFT, computes the homography that aligns your patch to your base image, and composites the aligned patch on top with a proper feathered blend. It's the node for the jobs that make ordinary merges fall apart - a region you upscaled separately and want to put back, a crop that came back a few pixels off, a composited element that needs to sit exactly where it belongs.
The pack's own example images (ImageMergeByPixelAlign.png and a workflow variant) show it being used to composite a generated patch back into a base image, which is the canonical use. Think: fix a face in one tile of a big image, then blend the repaired patch back in without the seam or the misalignment.
How it works
The mechanism, grounded in the source:
- Background keying. The patch has a background color you want excluded - set
bg_color_r/g/b(default 255/0/255, magenta) andbg_tolerance(default 10). Everything within that color distance is treated as the patch's background and gets cut, not composited. - SIFT alignment.
sift_features(default 5000) feature points are detected on both images and matched with Lowe'smatch_ratiothreshold (default 0.7). A homography is estimated from the matches, and the patch is warped to align with the base. This is what absorbs the "few pixels off" problem. - Core coverage and blend.
core_coverage(default 0.6) defines the inner region where the patch fully covers the base; outside it,blend_width(default 30) andblend_strength(default 0.7) control the transition, withblend_modechoosing the curve:smooth(sigmoid),linear,full_gradient, ornone.
The inputs that matter
- base_img / patch_img - the two images. The patch gets aligned onto the base.
- bg_color_r/g/b + bg_tolerance - what counts as patch background to exclude. Get this right and the composite is clean; get it wrong and you'll carry a colored fringe.
- core_coverage - how much of the patch is fully opaque. Lower = more blending area.
- blend_width / blend_strength / blend_mode - the feather behavior at the patch edge.
- sift_features / match_ratio - alignment quality. If alignment fails (noisy or low-texture images), raise features and lower the ratio.
One output: IMAGE, the composited result.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/mirabarukaso/ComfyUI_MiraSubPack
This node uses OpenCV (cv2), which is the pack's one real extra dependency - ComfyUI doesn't ship it by default:
pip install opencv-python
(or search "MiraSubPack" in Manager and restart; if the node errors on import, the cv2 install is the fix.)
Notes and gotchas
- It's slow-ish and CPU-bound - SIFT on a big image plus a homography warp is real work, and it runs per batch item.
- Low-texture images defeat SIFT. A flat wall or smooth gradient has no features to match, and alignment can silently fall back to returning the base image (the source catches the error and returns
base_imgunchanged - which is a silent failure worth knowing about). If your result just doesn't change, check whether the image has enough detail to align at all. - The background color needs to actually be uniform. The tolerance keying assumes a solid background; a gradient or noisy backdrop will leave remnants.
- If alignment is consistently off, tune
match_ratiodown (stricter matches) before raisingsift_features.
Inputs (12)
| Name | Type | Default | Description |
|---|---|---|---|
| base_img | IMAGE | — | |
| patch_img | IMAGE | — | |
| bg_color_r | INT | 2550–255 | Background color Red component (0-255) to exclude from patch |
| bg_color_g | INT | 00–255 | Background color Green component (0-255) to exclude from patch |
| bg_color_b | INT | 2550–255 | Background color Blue component (0-255) to exclude from patch |
| bg_tolerance | INT | 100–100 | Color distance tolerance for background detection |
| core_coverage | FLOAT | 0.600–1 | Core region coverage ratio (0-1), where patch fully covers base |
| blend_width | INT | 300–200 | Width of blend transition in pixels from core edge |
| blend_strength | FLOAT | 0.700–1 | Patch opacity in blend region (0=invisible, 1=fully opaque) |
| blend_mode | COMBO | smooth | Blend transition curve: - 'smooth': sigmoid within blend_width - 'linear': linear within blend_width - 'full_gradient': gradient from core edge to patch edge - 'none': no blend outside core |
| sift_features | INT | 50001000–10000 | Number of SIFT features to detect |
| match_ratio | FLOAT | 0.700.5–0.9 | Lowe's ratio threshold for feature matching |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | — |