Nodes/Auto Mask/Auto Mask Threshold
ComfyUI Node

Auto Mask Threshold

Stop guessing the cutoff, read the histogram

By easygoing0114·Created about a month ago·Updated about a month ago· 2
Auto Mask Threshold
  • mask
  • mask_batch (x8)
  • mask
  • histogram
threshold5

Thresholding a soft mask is the most fiddly two-minute task in ComfyUI. You've got a feathered alpha matte and you need a hard binary mask - so where's the cutoff? 0.3? 0.5? 0.7? You drag a Threshold node, squint at the preview, drag it again. Auto Mask Threshold does the guessing for you: it analyzes the mask's value histogram, finds the meaningful boundaries - the valleys between peaks - and hands you up to eight candidate binary masks at once, with a rendered histogram so you can see exactly why each cutoff lands where it does.

It's the natural companion to the pack's Mask Refine node, and the README example workflow is literally BiRefNet → Mask Threshold → Mask Refine. Soft mattes are great for compositing but annoying when a downstream step wants a clean yes/no mask - inpainting regions, feeding a detailer loop, or exporting to another program. This node is the bridge from "fractional alpha" back to "definitely in, definitely out."

How it works

No model, no GPU - this is pure histogram math on the mask tensor. The node builds a 256-bin histogram of mask values across the 0–1 range, then goes hunting for boundaries:

  • It finds up to 5 valleys between histogram peaks, scored by topographic prominence (how deep a valley sits relative to the peaks on either side).
  • Then it digs up to 3 minor minima inside the largest peak - useful when one big mass of pixels has subtle internal structure.
  • That's up to 8 candidate boundaries. Each becomes a binary mask via mask >= threshold_value.

The trick that makes this usable: the boundaries are computed once, then exposed in order, so you can flip between cutoffs without re-running the analysis.

The inputs and outputs that matter

Two inputs, and only one you'll set:

  • mask - a soft, non-binary mask. A hard binary mask in here produces a degenerate histogram and meaningless valleys.
  • threshold - an INT, default 5, range 18. Picks the n-th detected boundary (ascending) as the single-mask output.

Three outputs:

  • mask_batch (x8) - all candidate binary masks stacked into one MASK batch. Don't assume it's always exactly 8 items; it's "up to 8" depending on what the histogram actually contains.
  • mask - the single binary mask selected by threshold.
  • histogram - an IMAGE of the rendered histogram with the detected peaks/valleys drawn on, and the selected boundary highlighted in red. The node also writes it to ComfyUI's temp folder so it shows up in your previews.

That histogram output is the reason the node is worth it even if you end up overriding its pick - you get a map of where the mask's value distribution actually lives, which is more than most manual thresholding ever tells you.

Installing it

Identical to the rest of the pack. ComfyUI Manager → search "easygoing" → install, or:

cd ComfyUI/custom_nodes
git clone https://github.com/easygoing0114/ComfyUI-AutoMask.git
cd ComfyUI-AutoMask
pip install -r requirements.txt

Dependencies are just opencv-python and pymatting. No model files, no weights, nothing to download.

Where people get burned

The big one is feeding it a binary mask. This node is built to analyze a distribution; if every pixel is 0 or 1, the "valleys" it finds are noise. Feed it the soft output of Mask Refine, a BiRefNet matting result, or a heavily feathered SAM mask - not the hard output of another threshold node.

Second: the threshold input is 1-indexed and ascending, so 1 is the lowest boundary and 8 the highest, not the other way around. It's easy to assume a bigger number means a stricter cutoff when it actually means a brighter one.

And the same pack-level gotcha applies here as to Mask Refine: this is built on the new comfy_api.latest extension API, so a stale ComfyUI install throws at import. Update before you troubleshoot anything else.

For what it is, it's surprisingly pleasant. One input, a histogram you can actually read, and all the candidate masks in a batch for comparison. That's the whole job, done without a single trial-and-error pass.

CategoryAutoMask

Inputs (2)

NameTypeDefaultDescription
maskMASK
thresholdINT51–8Selects the n-th boundary value (ascending, 1-8) as the single-mask output.

Outputs (3)

NameTypeDescription
mask_batch (x8)MASK
maskMASK
histogramIMAGE