OpenCV inRange_0
Keep only the pixels inside a color range
- src
- lowerb
- upperb
- dst
- nparray
OpenCV's inRange is the classic way to say "keep every pixel whose color is between these two bounds, zero out the rest" - and OpenCV inRange_0 is a straight wrapper around it. You feed it an image, a lower bound, an upper bound, and you get back a binary mask that's 255 where the pixel fit the range and 0 everywhere else. In a ComfyUI workflow that mask is gold: it's the thing you wire into a compositing or inpainting branch so the model only re-renders the pixels you actually care about. Think "cut out the blue sky," "keep the red dress," or isolate a color band before running a detailer on it.
How it works
cv2.inRange(src, lowerb, upperb) compares each pixel against the bounds per channel, and every channel has to be inside its own [lowerb[c], upperb[c]] for the pixel to survive - the bounds are inclusive, so a pixel exactly equal to lowerb or upperb counts as inside. For a single-channel grayscale image the bounds are effectively scalars; for a 3-channel BGR image they're 3-element arrays, one range per channel. The output is a single-channel uint8 mask with values 0 and 255.
Where beginners get tripped up with this node specifically: the bounds are NPARRAY inputs, not numbers you type. The pack works in raw OpenCV arrays (see the Image2Nparray / Nparrays2Image conversion nodes), and lowerb and upperb are no exception. So you need a way to produce a small array for the range - an array-holding nparray from another node or a scripting node. If you don't have one handy, reach for the pack's threshold_0 instead, which takes a plain FLOAT and is far friendlier for a single-value cutoff. inRange earns its keep when you genuinely want a multi-channel color band, not when you want "brighter than X."
Inputs and outputs
Only four, and three of them matter:
src- your image as an NPARRAY, converted withImage2Nparrayfirst (RGB in, BGR out, remember).lowerb/upperb- NPARRAYs with the per-channel range. For a grayscalesrcthey can be a single value; for BGR, three values.dst- optional output array (the author auto-generates out-parameters when OpenCV types them| None). You can safely ignore it; the node returns the result either way.- Output
nparray- the0/255mask.
Because the pack only handles batch_size == 1, feed a single image - use ImageFromBatch with length=1 if your batch is bigger.
Installing the pack
This node ships in opencv-comfyui, Gerold Meisinger's auto-generated pack of ~635 OpenCV wrappers. Install it once and every OpenCV * node in this pack comes with it:
cd ComfyUI/custom_nodes
git clone https://github.com/geroldmeisinger/opencv-comfyui
cd opencv-comfyui
pip install -r requirements.txt
requirements.txt is just opencv-contrib-python, numpy, and torch - no model files, nothing to download. ComfyUI Manager finds it too, if you search "opencv-comfyui". Restart ComfyUI and you're done.
Gotchas
The mask output is grayscale (CV_8UC1), so the conversion node handles previewing it fine. The pack's other signature error, img.type() == CV_8UC1, means "this function wanted a single-channel image" - if a node demands grayscale, convert with cvtColor (code 6 = BGR2GRAY) before feeding it. Also: remember this pack auto-generates from OpenCV stubs, and the author's own README opens with "Expect dragons!" - the numbering (inRange_0 vs inRange_1) is just OpenCV's overloads, and the two variants behave identically, so pick whichever your graph already references.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| src | NPARRAY | — | |
| lowerb | NPARRAY | — | |
| upperb | NPARRAY | — | |
| dstopt | NPARRAY | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| nparray | NPARRAY | — |