Nodes/ComfyUI CV/CV Stack Images
ComfyUI Node

CV Stack Images

The before/after strip node (and a contact sheet trick)

By bmad4ever·Created 4 months ago·Updated 15 days ago· 1
CV Stack Images
  • images
  • image
◄directionhorizontal (a then b)►
◄gap0►

You've processed an image and you want to see what happened. Two previews, two tabs, flicking back and forth. CV Stack Images puts them side by side on one black canvas, pads whatever is smaller, and hands you a single image.

That's the main use, and it's the one every CV graph ends up needing: mask next to source, skeleton next to mask, detected next to original. The secondary use is better than it sounds - as the body of a loop it folds a whole list into one contact sheet, so you can look at a hundred processed frames in one preview instead of a hundred.

How it works

There's an autogrow input called images: one slot to start, and it grows as you connect things. Whatever you plug into the first slot sets the type for the rest - IMAGE, MASK or NPARRAY all work, and all inputs share the first input's type. That's the mechanism the author points at in the source, matching core's Create List: the template match makes every added slot follow the first wire, so you don't get a type mismatch on slot 7 after the graph was already working.

Every input is padded out to the largest one - bottom-right padding for a horizontal strip, right-edge padding for a vertical one - on a black canvas. So mixing a 512×512 and a 1024×1024 means the small one gets black bars, and there's no resampling anywhere. That's deliberate: this is a diagnostic node, and a resized comparison is a misleading one.

  • direction - horizontal (a then b) or vertical (a above b). All inputs stack the same way.
  • gap - INT, 0 to 256, default 0. A black separator between consecutive inputs. Set it to something small on a mask comparison, because two adjacent 0/255 masks with no gap read as one image.

One output, image, in whatever format the inputs were - so a stack of MASKs comes out as a MASK, which you can keep feeding into CV nodes rather than popping out to the image pipeline.

The loop trick

The description's own suggestion: as the body of an Inspire Foreach List loop, with image0 wired from intermediate_output and image1 from item, this folds a list into one contact sheet. Each iteration stacks the accumulated sheet with the next item, and the loop's output is the whole grid.

That's a genuinely nice pattern for video or batch CV work, where per-frame previews are useless and a strip is exactly the artefact you want. Note the dependency: that trick needs Dr.Lt.Data's ComfyUI-Inspire-Pack, which the pack's README lists as required by some of its workflows and subgraphs (along with ComfyUI-Custom-Scripts and Basic Data Handling). The node itself doesn't need any of them.

Install

ComfyUI Manager → ComfyUI CV → install → restart. Or:

cd ComfyUI/custom_nodes
git clone https://github.com/bmad4ever/comfyui_cv
pip install "opencv-contrib-python-headless~=5.0.0.93"

Python ≥ 3.12, a recent ComfyUI on the V3 node API, no models. Python 3.12 and the V3 schema are hard requirements, not preferences - the whole pack is written against the newer node authoring API, which is also why a grep for NODE_CLASS_MAPPINGS in this repo comes back empty and that means the opposite of broken.

If you load one of the pack's example workflows and want the sample media, run workflows/01_install_example_inputs.json once - a single node with nothing to wire - then reload the ComfyUI page, because the Load Image dropdown only picks up new files when node definitions are fetched.

Common issues

  • Black bars in your comparison. Expected - padding, no resampling. Match the input sizes if the bars bother you, or crop the stack afterwards with CV Slice Array.
  • A mask stack renders as a thin grey band. One-channel 0/255 data previews badly. Convert or overlay it if you need to look at it properly.
  • Adding a sixth input changed the whole node's type. The first connected slot wins. Connect in the order you mean, or check which slot your IMAGE actually landed in.
  • "CV Stack Images needs at least one input." An autogrow input with nothing connected does raise, unlike most nodes in this pack. Connect at least one.
  • The image/CV category is missing entirely after installing another pack. Non-contrib OpenCV wheel overwrote the contrib one in the shared site-packages/cv2, emptying the contrib submodules. python tools/repair_opencv_contrib.py --check, then --apply.
Categoryimage/CV/features

Inputs (3)

NameTypeDefaultDescription
imagesCOMFY_AUTOGROW_V3—
directionCOMBOhorizontal (a then b)Side by side, or one above the other.
gapINT00–256Black separator between consecutive inputs, in pixels.

Outputs (1)

NameTypeDescription
imageCOMFY_MATCHTYPE_V3Same format as the image inputs.