Nodes/ComfyUI CV/CV Threshold Flags
ComfyUI Node

CV Threshold Flags

Pick Your Thresholding Mode Once, Share It Everywhere

By bmad4ever·Created 3 months ago·Updated 14 days ago· 1
CV Threshold Flags
    • flags
    • value
    ◄flagsTHRESH_BINARY►

    cv2.threshold's type argument is a bit field hiding a decision. THRESH_BINARY, THRESH_BINARY_INV, TRUNC, TOZERO, TOZERO_INV - five different meanings riding on one integer - plus two modifier bits that auto-compute the threshold from the histogram. This node turns that into a dropdown with toggles, and lets you wire one configuration into every threshold node in the graph.

    Thresholding is the workhorse of mask extraction: it's what turns a saliency map, a difference image, or a channel into something you can actually mask with. The pack's 04_threshold_playground.json exists because getting the mode right is most of the job, and eyeballing five variants on the same image is faster than reasoning about them.

    What the flags mean

    The base picks the method:

    • THRESH_BINARY (the default) - above the threshold becomes max, below becomes 0.
    • THRESH_BINARY_INV - the same, inverted. The one you reach for when your subject came out black on white instead of white on black.
    • THRESH_TRUNC - everything above the threshold is clipped down to it. A highlight limiter, not a mask.
    • THRESH_TOZERO - below goes to 0, above is untouched. Useful for killing background noise while keeping real values.
    • THRESH_TOZERO_INV - the mirror image of that.

    Then two toggles:

    • THRESH_OTSU computes the threshold from the image's histogram instead of using the number you passed, picking the split that best separates two populations. This is the "I don't want to tune a value" option, and it deserves a warning: it's implemented only for 8-bit single-channel images, and it's really meant to pair with BINARY or BINARY_INV. Combine it with TRUNC and you're relying on undefined behaviour.
    • THRESH_TRIANGLE does the same trick using the histogram's peak-to-tail distance - better than Otsu on the skewed, one-sided histograms you get from fluorescence or heavily backlit images.

    When either auto method is toggled on, the threshold value you passed is ignored. That surprises people who set both and wonder which won.

    Outputs

    Two of them, matching the pack's other flag nodes:

    • flags (STRING) - the pipe-joined constant names, for wiring into the flags input of cv2_threshold or cv2_thresholdWithMask. This is the type-safe path: the string is resolved and validated when the node runs, so a typo errors loudly instead of OR-ing nonsense bits.
    • value (INT) - the resolved integer, for raw INT flag parameters or arithmetic in a MathExpression.

    Because it's a STRING that fans out, one node can configure every threshold call in a workflow. When you decide mid-run that Otsu was the wrong call, you flip one toggle instead of five.

    Install

    ComfyUI Manager → search ComfyUI CV (publisher bmad4ever), or:

    cd ComfyUI/custom_nodes
    git clone https://github.com/bmad4ever/comfyui_cv
    pip install "opencv-contrib-python-headless~=5.0.0.93"
    

    Restart after. Python ≥ 3.12 and a recent ComfyUI on the V3 node API. Keep the contrib wheel - a plain opencv-python installed over it shares site-packages/cv2 and silently empties the contrib submodules, breaking other nodes in the pack. tools/repair_opencv_contrib.py --check / --apply handles the repair.

    04_threshold_playground.json is the reference graph; the sample images come in via 01_install_example_inputs.json (run it once, then reload the page).

    Where it bites

    The dropdown-and-toggles renderer comes from a per-node spec the pack ships with the widget. On an older frontend build flags renders as a plain text box and you'd be typing constant names by hand - still valid, just less pleasant.

    Beyond that: nothing here checks that you wired it somewhere sensible. cv2_threshold will happily take a flags value meant for something else. The pack ships one flag builder per target family precisely because that's the failure mode, so match the node to the consumer.

    And the pack's standing disclaimer, since it applies to everything in this collection: bmad4ever's README describes a personal, heavily LLM-assisted project, curated against a specific OpenCV build, with no support planned and workflows built to demonstrate rather than ship. A flags OR-er with two outputs is about as safe as that gets.

    Categoryimage/CV/low-level

    Inputs (1)

    NameTypeDefaultDescription
    flagsSTRINGTHRESH_BINARYPipe-joined cv2 constant names, e.g. "THRESH_BINARY | THRESH_OTSU". In the UI this renders as a base dropdown with one toggle per flag.

    Outputs (2)

    NameTypeDescription
    flagsSTRINGThe pipe-joined flags string - wire it into the flags input of cv2_threshold / cv2_thresholdWithMask nodes.
    valueINTThe resolved integer (constants OR-ed together).