CV DNN Images From Blob
Turning a network's output tensor back into pictures
- blob
- images
CV DNN Images From Blob unpacks an NCHW tensor back into an NHWC image batch. It's the postprocess step of the pack's generic ONNX chain - the one you wire after CV DNN Forward when the model's output is a picture.
It's a one-call node (cv2.dnn.imagesFromBlob), and it's easy to overlook exactly how much it saves you: a transpose of four axes, with the channel order and value range preserved and no normalisation guesswork. Super-resolution, denoise, deblur, style transfer, colorisation - everything whose output is an image ends up here.
How it works, and what it does not do
The blob is (N, C, H, W); the output is (N, H, W, C), the layout ComfyUI's imaging nodes expect. That's the whole operation.
Two things it deliberately doesn't touch, and both are the source of "my upscaler output is black / grey / neon":
- Values are returned exactly as the network emitted them. No clipping, no rescaling. If the model's output is in 0–1 you'll need to map it into display range; if it's logits or residual values, they need whatever postprocessing that model requires.
- Channel order follows the blob. If you swapped R and B going in, you get RGB out - so a round-trip through the same settings gives you back what you started with, but a model trained with a different convention needs handling.
The channel count is free-form, which turns out to be more useful than it sounds: C = 1 is a grayscale map, C = 3 a colour image, and C = 2 is a dense flow field - an (H, W, 2) dx/dy pair, which is exactly what the pack's flow nodes take. So a flow network's output goes through this node and then into a flow visualiser without any reshaping in between.
Inputs and outputs
One required input, blob - an (N, C, H, W) NCHW array, typically straight off CV DNN Forward but any correctly-shaped array works.
One output, images - an (N, H, W, C) float32 batch in the network's own output range. Two nodes split it up: CV Unstack Batch for individual frames, CV Index Batch to pick one by index. And if the batch is already a single frame, several of the pack's image nodes accept the NPARRAY directly and will convert on the way in, so don't assume a separate conversion step is always required.
Install
From comfyui_cv (bmad4ever/comfyui_cv). ComfyUI Manager → search "ComfyUI CV", or:
cd ComfyUI/custom_nodes
git clone https://github.com/bmad4ever/comfyui_cv
pip install "opencv-contrib-python-headless~=5.0.0.93"
Restart ComfyUI. Python ≥ 3.12 and a recent V3-API ComfyUI - the pack is a rewrite on the V3 node API, so it needs a ComfyUI recent enough to have one. Dependencies are OpenCV (contrib wheel, pinned to 5.0.0.93), numpy and torch; the site-packages/cv2 sharing trap applies here as everywhere in this pack, so if contrib nodes vanish after you install something else, tools/repair_opencv_contrib.py --check will tell you which wheel won.
Common issues
- Black or all-white output. Range, not shapes. Blow the result through
cv2_normalize(orcv2_convertScaleAbs, which scales and clips to 8-bit in one go) before you save it.CV Array → Imagehandles the conversion for the common 0–1 case. - Colours are swapped. Channel order from the blob's
swap_rbsetting. Round-trip consistently - swap going in, and the swap is already undone; don't swap twice. - The image is a weird shape or has odd channels. Inspect the upstream tensor with
Inspect CV Datafirst. A detection head's output has a channel dimension that isn't a channel dimension. - You get one frame but expected a batch. Many image models in the OpenCV Zoo set are batch-1 by design. That's the model, not the transpose.
- It works but takes an age. This is
cv2.dnnon the CPU. For the common cases - upscaling, face restoration, frame interpolation - ComfyUI core has PyTorch nodes doing the same job on the GPU with fp16 and model offloading. Use this chain to understand the mechanics or to reach a model core can't run; don't use it to reimplement what's already native.
If you're assembling the whole thing from scratch: CV DNN Blob From Image → CV DNN Forward → this → cv2_convertScaleAbs → CV Array → Image is the canonical pipeline, and it works for any ONNX model whose output is an image.
Inputs (1)
| Name | Type | Default | Description |
|---|---|---|---|
| blob | NPARRAY | (N, C, H, W) NCHW blob, e.g. an image model's output from 'CV DNN Forward'. Any channel count: C=1 gray, C=3 colour, C=2 a dense flow field ((H, W, 2) dx/dy, which is what the flow nodes take). |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| images | NPARRAY | (N, H, W, C) float32 batch in the network's output range. Use 'CV Unstack Batch' or 'CV Index Batch' to split into individual frames. |