CV Stitch (Advanced List)
The Full Stitching Pipeline, Fed One Image at a Time
- images
- masks
- panorama
- status
- success
This is CV Stitch (Advanced) with one substitution: images takes a ComfyUI list instead of a batched NPARRAY. Each item can be an IMAGE, a LATENT or an NPARRAY, and only the first frame of each item is used.
If that sounds like a footnote, it isn't. Lists and batches are different shapes in ComfyUI, and which one you have depends on where your images came from - a folder loader handing you a list of images wants this node, while a batched IMAGE clip wants the batch version (or a trip through Image Batch → CV Batch). Getting it wrong isn't an error, it's a quiet one: feed a batch into a list socket and you stitch a single frame. The example graph builds its list with core's Batch Images node, which is the usual assembly point.
Everything else is the full cv2.detail pipeline rather than the one-call cv2.Stitcher: feature detection, matching, homography or affine estimation, bundle adjustment, warp projection, exposure compensation, seam finding, blending. Stage order and parameter set follow OpenCV's own stitching_detailed.py, so the knobs mean what they mean in the reference implementation.
The knobs that earn their place
warp_type is the big one - spherical by default and right for a wide sweep, but plane is what you want for flat, coplanar subjects (documents, posters, a wall). Spherical on a flat subject is the classic bow-tie distortion.
seam_finder - gc_colorgrad (GraphCut on colour plus gradient) is the best all-rounder; dp_color / dp_colorgrad are cheaper dynamic-programming cuts; voronoi is crude and fast; no disables it. blend_type picks multiband (Laplacian pyramid, best), feather (linear) or no (hard cut), with blend_strength setting how soft the merge is.
exposure_compensation deals with the brightness jumps your camera's metering created between frames: gain_blocks default, gain for one global gain, channel/channel_blocks for colour, no to leave it alone.
Then features (orb / sift), matcher, match_conf (-1 auto), estimator (homography for perspective, affine for planar SCANS-style captures), bundle_adjuster, pano_confidence_thresh, and the three resolution stages - registration_resol, seam_estimation_resol, compositing_resol - all at -1 for full resolution, and the first place to look when memory runs out. wave_correction (auto by default) handles hand-held drift. interpolation_flags sets the warp interpolator.
There's an optional masks list too, one coverage mask per image.
Outputs: panorama (uint8 BGR NPARRAY), status (OK or an ERR_* label) and success. Failures return a copy of the first input frame instead of raising, so branch on success. Stitching happens in a separate process and stays interruptible.
Install
ComfyUI Manager → search ComfyUI CV (publisher bmad4ever), or:
cd ComfyUI/custom_nodes
git clone https://github.com/bmad4ever/comfyui_cv
pip install "opencv-contrib-python-headless~=5.0.0.93"
Restart after. Python ≥ 3.12 and a recent ComfyUI on the V3 node API. Keep the contrib wheel: a plain opencv-python install shares one site-packages/cv2 and silently empties the contrib submodules other nodes here rely on. tools/repair_opencv_contrib.py --check and --apply are in the repo.
48_panorama_playground.json uses this node alongside the batch variants - a genuinely good way to see what each parameter does, since all three run on the same two images. Get those files in place with workflows/01_install_example_inputs.json, then reload the page.
Where it bites
Change one parameter per run. Twenty knobs with visual failure modes is not a place to be brave. And remember the item ordering is the stitch order - a list assembled out of sequence produces a panorama that's technically successful and completely wrong.
The pack caveat applies as always, and it's worth repeating because the author says it himself: this is a personal, heavily LLM-assisted project, updates aren't planned, and the workflows demonstrate functionality rather than ship it. The parameter set here is lifted from OpenCV's official sample, which is the reassuring part; the preset values are one person's taste.
Inputs (22)
| Name | Type | Default | Description |
|---|---|---|---|
| images | NPARRAY,IMAGE,MASK | List of images to stitch. Each element is an IMAGE / LATENT / NPARRAY; only the first frame of each is used. Accepts a ComfyUI IMAGE/MASK directly (frame 0 of a batch) or an NPARRAY. Arithmetic ops (add, multiply, etc.) process the full IMAGE batch when both inputs have the same batch size. | |
| features | COMBO | orb | Feature detector type. ORB is fast and universally available. SIFT is more distinctive but slower. |
| matcher | COMBO | best_of_2_nearest | Feature matcher. best_of_2_nearest (default): standard pairwise matching. best_of_2_nearest_range: limits matching to neighbors within range_width. affine_best_of_2_nearest: for affine transformations (SCANS mode). |
| match_conf | FLOAT | -1.00-1–1 | Feature match confidence threshold. -1 = auto (0.3 for ORB, 0.65 for SIFT). Higher = fewer, more reliable matches. |
| range_width | INT | -1-1–100 | Range width for best_of_2_nearest_range matcher. -1 = match against all images. Only used when matcher is best_of_2_nearest_range. |
| estimator | COMBO | homography | Camera estimator. homography (default): perspective transforms between images (PANORAMA mode). affine: affine transforms (SCANS mode, planar scenes). |
| bundle_adjuster | COMBO | ray | Bundle adjustment cost function. ray (default): ray-based error. reproj: reprojection error. affine_partial: partial affine refinement. no: skip bundle adjustment. |
| pano_confidence_thresh | FLOAT | 1.000–10 | Confidence threshold for feature matching. Images with confidence below this are excluded. Also passed to the bundle adjuster. |
| warp_type | COMBO | spherical | Projection warp type. spherical (default): good for wide panoramas. plane: no warping (flat scenes). cylindrical: vertical lines stay straight. fisheye/stereographic/mercator: specialized projections. |
| wave_correction | COMBO | auto | Wave correction for horizontal/vertical drift. auto (default): auto-detect direction. horiz/vert: force direction. no: disable. |
| registration_resol | FLOAT | -1.00-1–100 | Resolution in megapixels for the registration stage (feature detection + matching). -1 = full resolution. |
| seam_estimation_resol | FLOAT | -1.00-1–100 | Resolution in megapixels for seam estimation and exposure compensation. -1 = full resolution. |
| compositing_resol | FLOAT | -1.00-1–100 | Resolution in megapixels for compositing/warping phase. -1 = full resolution. |
| interpolation_flags | COMBO | INTER_LINEAR | Interpolation method for warping. INTER_LINEAR (default) is fast; INTER_CUBIC or INTER_LANCZOS4 are sharper. |
| exposure_compensation | COMBO | gain_blocks | Exposure compensation method. gain_blocks (default): local block gain. gain: global per-image gain. channel: per-channel gain. channel_blocks: local per-channel gain. no: disable. |
| expos_comp_nr_feeds | INT | 11–10 | Number of exposure compensation feeds. Only used for channel / channel_blocks compensators. |
| expos_comp_nr_filtering | INT | 21–10 | Number of filtering iterations for exposure compensation gains. Higher = smoother gain maps. Default 2. Only used for channel / channel_blocks compensators. |
| expos_comp_block_size | INT | 321–256 | Block size (pixels) for block-based exposure compensators (gain_blocks, channel_blocks). |
| seam_finder | COMBO | gc_colorgrad | Seam finding method. gc_colorgrad (default): GraphCut with color + gradient cost. gc_color: GraphCut, color only. dp_color / dp_colorgrad: dynamic programming. voronoi: Voronoi diagram. no: skip. |
| blend_type | COMBO | multiband | Blending method. multiband (default): Laplacian pyramid blend (best quality). feather: linear distance blend. no: direct cut. |
| blend_strength | FLOAT | 5.00–100 | Blending strength [0-100]. Higher = softer transition at seams. Default 5.0. |
| masksopt | NPARRAY,MASK | Optional list of coverage masks (one per image in the image list). Accepts a ComfyUI IMAGE/MASK directly (frame 0 of a batch) or an NPARRAY. Arithmetic ops (add, multiply, etc.) process the full IMAGE batch when both inputs have the same batch size. |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| panorama | NPARRAY | Stitched panorama (uint8 BGR). On failure returns a copy of the first input frame. |
| status | STRING | 'OK' or an error label returned by the detail pipeline. |
| success | BOOLEAN | True when stitching succeeded (status == OK). Use with IfElse to branch on success/failure. |