cv2.thresholdWithMask
Threshold only inside the region you care about
- src
- dst
- mask
- float
- result
The honest pitch first: this is one of the least-known functions in OpenCV 5 - a masked variant of threshold - and it exists in this pack only because the pack auto-generates a wrapper for everything cv2 exposes. Nobody's shipping workflows around it. But the shape of what it does is genuinely useful in a mixing graph, and it's simple enough to explain in a paragraph.
threshold binarises the whole frame. thresholdWithMask binarises only where the mask is non-zero and leaves everything else as it was. In a ComfyUI graph that's "sharpen the decision in this region", which is how you binarise a soft mask only inside the subject's bounding area, or cut a local threshold out of a noisy background without touching the rest of the picture.
One of roughly 470 auto-generated raw cv2.* wrappers in ComfyUI CV (bmad4ever/comfyui_cv) - uncurated by design, LLM-generated, per the pack's own disclaimers.
Inputs
Six, and the middle one is the interesting bit.
src-NPARRAY,IMAGEorMASK. An IMAGE is auto-grayscaled, because this function wants single-channel input.dst- required, and this is the best thing about the node. In cv2,thresholdWithMaskwrites its result intodst, and the pixels outside the mask keep whateverdstheld. The wrapper's tooltip says it plainly: cv2 writes into this array in place, "but this wrapper passes cv2 a private copy, so your input array is never modified". Meaning: whatever you link intodstis the content that survives outside the mask. Link your original image and only the masked region gets thresholded - a local binarisation brush. Link a black image and the outside goes black.mask- required here (the same-size 8-bit array), which is exactly what makes this a different node fromcv2.threshold. Same size assrc.thresh,maxval,type- the same trio as plainthreshold, withtypea dropdown of theTHRESH_*flags plus the OTSU/TRIANGLE options pipe-joined ontoTHRESH_BINARY.
Same units warning as its sibling: an IMAGE is 8-bit, so thresh and maxval are 0..255, not 0..1.
Outputs
result echoes src's socket type (IMAGE → IMAGE, MASK → MASK) and float is the threshold value cv2 settled on - only interesting when you've enabled OTSU or TRIANGLE, in which case it's the histogram's answer and worth reading.
Is it worth using?
Sometimes. The three-step version of the same thing - threshold the frame, then cv2.copyTo or cv2.bitwise_and the result back through the mask - gives you more control and more knobs (you can feather the seam, pick which of several sources survives outside, dilate the mask first to avoid a hard cut). This node does it in one call, and one call is a real advantage when all you want is "don't let the binarisation touch anything outside this box".
What it won't do is give you a soft transition at the mask border, any more than threshold gives you one at the intensity border. If the edge of the region is visible in the result - and on a difference-of-two-results it always is - the fix is to feather the mask before it arrives, not to look for a knob here. The stock binary mask is sharp by nature.
Treat this as a raw building block: there's no shipped example workflow using it, no curated preset, and no author support. Verify on your own data before you build a production graph around it, which the pack's README says about everything in here anyway.
Installing the pack
cd ComfyUI/custom_nodes
git clone https://github.com/bmad4ever/comfyui_cv
cd comfyui_cv && pip install "opencv-contrib-python-headless~=5.0.0.93"
Manager → search ComfyUI CV → install → restart works too. Python ≥ 3.12 and a ComfyUI on the V3 node API are hard requirements - older installations never show these nodes. Keep the OpenCV build contrib: all four distributions share one site-packages/cv2, and installing plain opencv-python over the contrib wheel silently empties the contrib submodules, taking contrib nodes with it. tools/repair_opencv_contrib.py --check diagnoses, --apply repairs. Behaviour is curated against 5.0.0.93.
Watch out for
Forgetting dst is not just a formality - it defines everything outside the mask, so leaving it wired to a black constant gives you a hard black border you didn't intend. Mismatched src/dst/mask sizes raise rather than resize. And a maxval of 0 still produces an all-zero result inside the mask, exactly as in plain threshold.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| src | COMFY_MATCHTYPE_V3 | input array (multiple-channel, 8-bit or 32-bit floating point). The image output(s) echo this input's format. 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. | |
| dst | NPARRAY,IMAGE,MASK | output array of the same size and type and the same number of channels as src. The low-level cv2 function writes its result into this array in place, but this wrapper passes cv2 a private copy, so your input array is never modified. 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. | |
| mask | NPARRAY,IMAGE,MASK | optional mask (same size as src, 8-bit). 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. | |
| thresh | FLOAT | 0.0000-1e+38–1e+38 | threshold value. |
| maxval | FLOAT | 0.0000-1e+38–1e+38 | maximum value to use with the #THRESH_BINARY and #THRESH_BINARY_INV thresholding types. |
| type | STRING | THRESH_BINARY | thresholding type (see #ThresholdTypes). cv2.thresholdWithMask flags: one of THRESH_BINARY, THRESH_BINARY_INV, THRESH_TRUNC, THRESH_TOZERO, THRESH_TOZERO_INV plus any of THRESH_OTSU, THRESH_TRIANGLE, pipe-joined (e.g. "THRESH_BINARY | THRESH_OTSU"). In the UI this renders as a dropdown with one toggle per flag. |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| float | FLOAT | — |
| result | COMFY_MATCHTYPE_V3 | Echoes the 'src' input's format: an IMAGE link comes back as IMAGE, MASK as MASK, NPARRAY stays NPARRAY. |