Nodes/ComfyUI CV/CV Unstack Batch
ComfyUI Node

CV Unstack Batch

Getting one frame at a time out of a DNN output batch

By bmad4ever·Created 4 months ago·Updated 14 days ago· 1
CV Unstack Batch
  • nparray
  • frame

Most nodes in this pack do one image. Run a network on a batch and you get a batch back, and now you're holding (N, H, W, C) with a graph full of nodes that want (H, W, C). CV Unstack Batch is the one-wire fix: split along axis 0 and hand out a list.

(N, H, W, C)  ->  [ (H, W, C), (H, W, C), ... ]   # N entries

That's the entire node. Its input is nparray - a batched array, most often what CV DNN Images From Blob (the batch variant) gives you back, or any N-D array with a real first axis. Its single output is frame, and it's a list: one array per batch element.

Why a list, and what consumes one

This is the node that makes batch output usable. Wire a list into a downstream node and ComfyUI runs that consumer once per item - so a chain like Cast Array → CV Array → Image → Preview Image runs N times and you get N previews instead of a shape error. Nested loops, folds, and the like are the same idea with the core list nodes; the pack's own video subgraphs use the core ITEM_LIST/fold nodes when they need an accumulator rather than a fan-out.

Two practical notes about list behaviour, because it's the part people trip on:

  • The output length is the batch size, and it's fixed at that node's execution. Change the batch size upstream and everything downstream re-runs. That's correct, not a bug.
  • A list is not an IMAGE. Nothing will preview a batch of raw arrays until you've converted them - CV Array → Image for the BGR/gray frames. If a downstream node is complaining about types, this is usually why.

When it's the wrong node

If whatever you're doing to each frame could be done to the whole batch at once, don't unstack. Nodes in this pack that take an NPARRAY or IMAGE and say "a batch is processed frame by frame" already loop internally, and they're faster and simpler than an explicit fan-out. CV Transform (Rotate/Scale/Shift) is the obvious one: rotating every frame by the same angle needs no unstacking at all.

You reach for this when the per-frame step genuinely is per-frame - a differing parameter per frame, a node that only accepts single images, or something you want to inspect one element at a time.

There's also the reverse-direction reason: some DNN nodes take a single frame and want a blob. Unstack, convert, blob, feed. That's the standard shape of a "run this network over a video" workflow built from low-level pieces rather than a purpose-built node. The inverse, CV Stack Batch, merges a list back into one batched array - the pair is how you round-trip a batch through per-frame work without losing the batch.

Installing it

Manager → ComfyUI CV, or:

cd ComfyUI/custom_nodes
git clone https://github.com/bmad4ever/comfyui_cv

Restart, then watch the console on the way up: the pack registers a large generated node set at import, and that's where a dependency problem announces itself. Python ≥ 3.12 and a recent ComfyUI on the V3 node API are requirements, and the one real dependency is opencv-contrib-python-headless~=5.0.0.93. Keep it contrib: all four opencv-*-python distributions write into the same site-packages/cv2, so installing the plain wheel quietly deletes the contrib submodules that a good chunk of this pack is built on. tools/repair_opencv_contrib.py --check tells you whether that has happened. GPL-3.0, forked from opencv-comfyui. No models.

Where people get burned

The wrong axis. It splits axis 0, whatever axis 0 happens to be. Hand it a plain 3-D (H, W, C) image and you get H items - individual rows of pixels - not one frame. That looks like "the node is broken"; it isn't, it's your array not being batched. A 1-D array is the one thing it refuses outright.

Assuming the list is ordered. It is, along axis 0, which for a video batch is frame order. For a DNN output batch it's whatever order the network produced, which for segmentation or detection heads isn't necessarily reading order.

An empty batch. An array with zero elements in axis 0 comes back as a one-item list containing an empty array, rather than an empty list - so downstream nodes get called once with nothing to work on rather than not at all. If your batch can legitimately be empty, gate that branch before it reaches a preview or a save.

Categoryimage/CV/low-level

Inputs (1)

NameTypeDefaultDescription
nparrayNPARRAYBatched array, e.g. (N, H, W, C) from DNN Images From Blob (Batch) or any N-D array with N>0 in axis 0.

Outputs (1)

NameTypeDescription
frameNPARRAYList of (H, W, C) arrays, one per batch element.