cv2.checkRange
Find the NaN before it paints your image black
- a
- ok
- pos
Every graphics-adjacent bug you've ever chased ends the same way: a NaN got into the buffer and something downstream turned it into black, white, or a frame of solid noise. cv2.checkRange is OpenCV's answer - walk the array, is every element inside the bounds you gave, and if not, where is the first one that isn't.
It's a raw wrapper in comfyui_cv (~470 cv2.* nodes), and it's one of the few in the catalog whose natural home is a debug branch rather than the main pipeline.
The defaults are already a NaN detector
This is the part worth reading twice. minVal and maxVal default to blank, which the pack maps to OpenCV's own defaults - the extreme ends of the double range. Left alone, the range check is therefore effectively "is this a number at all": a NaN fails every comparison, so it counts as out of range, and so does ±infinity. You don't have to configure anything to catch the classic failure.
Set real bounds and it becomes a validation node instead - "is this mask in 0–1", "is this magnitude map sane", "did the division at the end of my array maths leave anything above 10". The tooltips are precise about the semantics: minVal is an inclusive lower bound, maxVal is exclusive upper.
Inputs and outputs
a(required) - the array to audit. Accepts NPARRAY, IMAGE or MASK, converting on the way in, and this conversion is a trap worth knowing before you write an assertion: an IMAGE becomes uint8 BGR (values 0–255) and a MASK becomes uint8 single-channel. Checking a converted image against0–1will report the whole frame as out of bounds, because nothing is 0–1 any more. Audit NPARRAYs, or set bounds matching the uint8 range.quiet(optional, defaulttrue) - what happens when something is out of range.truereturnsfalseand carries on.falsemakes OpenCV raise, which inside a ComfyUI run means the node errors out and the queue stops. Counterintuitive naming, useful behaviour: leave it on for a gate, turn it off when you want the run to stop loudly.minVal,maxVal(optional, blank by default) - the bounds, as above.
Two outputs:
ok- BOOLEAN, all-in-range or not. This is what you gate on: a boolean is a switch selector, so it can route a good array down one path and a bad one to a preview or a halt.pos- aCV_TUPLEcomposite point (x, y), the position of the first offending element. Meaningless whenokis true. Wire it into any cv2 point input - acv2.circlefrom the same pack will draw you a marker where it blew up - or intoCV Split Tupleif you want the numbers loose.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/bmad4ever/comfyui_cv
Restart, or Manager → search "comfyui_cv". Python ≥ 3.12, a recent ComfyUI on the V3 node API, and:
pip install "opencv-contrib-python-headless~=5.0.0.93"
Nothing to download model-wise - it's a scan over an array.
Common issues
It reports out of range and you're certain the data is fine. Check the bounds against what the socket actually carries. A MASK that arrived as 0/255 uint8 is not in 0–1, and a normalised float array can legitimately contain a small negative value from floating-point error.
The run died instead of returning false. You turned quiet off. That's the documented behaviour, and it's a legitimate way to make a bad value halt the queue instead of flowing on.
pos is garbage but ok is true. Expected - OpenCV only writes the position when it finds something. Don't read it unless ok is false.
It only checks one frame of your batch. Feed it an NPARRAY for whole-array checks; IMAGE and MASK links go through frame 0.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| a | NPARRAY,IMAGE,MASK | input array. Accepts a ComfyUI IMAGE/MASK directly (frame 0 of a batch) or an NPARRAY. Arithmetic ops (add, multiply, etc.) process the full IMAGE batch when both inputs have the same batch size. | |
| quietopt | BOOLEAN | true | a flag, indicating whether the functions quietly return false when the array elements are out of range or they throw an exception. Preset to the OpenCV default (True). |
| minValopt | FLOAT | inclusive lower boundary of valid values range. Preset to the OpenCV default (-1.7976931348623157e+308). | |
| maxValopt | FLOAT | exclusive upper boundary of valid values range. Preset to the OpenCV default (1.7976931348623157e+308). |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| ok | BOOLEAN | — |
| pos | CV_TUPLE | - - - Pixel coordinates (x, y) as ONE composite value - wire it straight into any cv2 point input (center, seedPoint, pt1/pt2) or into 'CV Split Tuple' for the separate numbers. |