Nodes/ComfyUI CV/Mask → CV Array
ComfyUI Node

Mask → CV Array

Get your mask out of ComfyUI's type system and into numpy

By bmad4ever·Created 3 months ago·Updated 14 days ago· 1
Mask → CV Array
  • mask
  • nparray
◄dtypeuint8 (0-255)►
◄batch_index0►

ComfyUI's MASK type is a tensor with a specific shape and a 0–1 float range. OpenCV wants a 2-D uint8 array. Those two facts are responsible for a surprising amount of quiet confusion, because ComfyUI will happily pass a mask around for the whole graph and then the moment you touch a cv2.* node you find nothing matches.

This node is one of the pack's converters: MASK in, raw single-channel ndarray out. It exists so the ~470 generated cv2.* wrappers - and the ~200 curated nodes - can be fed something they understand.

How it works

Pick a frame with batch_index (clamped to the batch size, so an out-of-range index is safe rather than an exception), then pick a dtype:

  • uint8 (0-255) - what almost every cv2 call wants. Thresholds, morphology, findContours, distanceTransform: all uint8.
  • float32 (0-1) - keeps the fractional values ComfyUI's mask already carries. Use it when you're doing float arithmetic and don't want a mask's soft edge quantized into 256 steps.

batch_index is a widget rather than a socket, and that's the practical catch of the node: it emits one frame. If you have a 16-frame mask batch and you want all of them in array-land, this isn't the node - use the batch-level bridges (Image Batch -> CV Batch and friends) so the batch survives as a 4-D array.

The inputs and outputs

Three inputs, one output:

  • mask (MASK, required) - one frame is taken.
  • dtype (COMBO, uint8 (0-255) or float32 (0-1)).
  • batch_index (INT, default 0).
  • nparray out - the NPARRAY socket this whole pack runs on.

That NPARRAY is what you wire into cv2_threshold, cv2_Canny, cv2_findContours' inputs, or any of the curated contour/moment nodes. Going the other way later, CV Array -> Mask brings it back (and min-max normalizes floats on the way).

Install

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

Or ComfyUI Manager → search ComfyUI CV. Restart, reload the page. Dependencies are just opencv-contrib-python-headless~=5.0.0.93 (plus numpy and torch), and the pack wants Python ≥ 3.12 on a ComfyUI recent enough to support the V3 node API. Nothing to download.

Common issues

A "black" mask that isn't. If you convert with float32 and then feed it into a node expecting a binary image, a mask whose values sit at 0.0–1.0 reads as almost entirely black to anything using a 0–255 assumption. That's not a bug in either node - it's the dtype choice. uint8 for cv2, float32 for math, and know which side of the line you're on.

Only frame 0 arrives. The single most common report-shaped confusion with converters like this one. Check batch_index.

Contrib nodes vanish after an OpenCV update. Worth knowing for every article in this pack: all four OpenCV wheels (opencv-python, opencv-python-headless, opencv-contrib-python and its headless twin) share one site-packages/cv2. Install a non-contrib wheel over a contrib one and the contrib submodules silently empty out - the contrib nodes just disappear from the menu, with no error at install time. The pack ships a diagnostic for it:

python tools/repair_opencv_contrib.py --check     # diagnose
python tools/repair_opencv_contrib.py --apply     # repair

People hit the plain-cv2 problem constantly in ComfyUI - the standard community advice is always the headless wheel for a backend, precisely because nothing here draws a window. This pack blacklists imshow/waitKey outright, which is why headless is the declared dependency.

Categoryimage/CV/low-level

Inputs (3)

NameTypeDefaultDescription
maskMASKMASK to convert. One frame is taken (see batch_index).
dtypeCOMBOuint8 (0-255)uint8 for most cv2 functions; float32 (0-1) to preserve fractional mask values for downstream float math.
batch_indexINT00–4095Which mask of the batch to convert. Clamped to the batch size.

Outputs (1)

NameTypeDescription
nparrayNPARRAY—