Nodes/koo-nodes-pack/KoO Noise Mask Builder
ComfyUI Node

KoO Noise Mask Builder

Masks From Texture, Not From What's In the Picture

By kooailab·Created 15 days ago·Updated 4 days ago· 0
KoO Noise Mask Builder
  • image
  • mask
  • edge_map
  • texture_map
  • flat_map
  • report
◄modecombined►
◄edge_strength1.00►
◄texture_strength1.00►
◄flat_surface_suppression0.75►
◄threshold_low0.05►
◄threshold_high0.95►
◄blur_radius0.00►
◄expand_mask0►
◄gamma1.00►
◄invertfalse►
◄normalizetrue►

Most masking in ComfyUI answers "where is the face." Detection models find objects; segmentation models find regions; everything downstream crops and re-renders. KoO Noise Mask Builder answers a completely different question: where is there detail? Feed it a finished image and it hands you a mask that's bright where the image has edges and fine texture, dark where it's smooth.

That's not semantic and the node says so in its own report: "This mask is frequency-based only. It does not perform semantic material detection." Good. Half the confusion in this space comes from people expecting a texture mask to know what skin is.

What it computes

Three underlying maps, all built from luminance:

  • Sobel edges - classic gradient magnitude over a 3×3 kernel pair, catching hard boundaries.
  • Local variance - mean of squares minus square of mean over a Gaussian window (sigma 2), i.e. how much the neighbourhood fluctuates. High on fabric, foliage, hair; low on walls and skies.
  • High-frequency - luminance minus a blurred copy of itself: fine grain without the structural edges.

mode picks which of these to combine: edges, local_variance, high_frequency, or combined (default), which sums edge detail weighted by edge_strength and a texture map weighted by texture_strength.

Then comes the part that makes it useful rather than just a Sobel filter: flat_surface_suppression (default 0.75). The node computes a flatness map as "not edge AND not texture," and subtracts it from the detail map before thresholding. That's what keeps a large smooth gradient background from contributing a faint wash of mask everywhere, which is the normal behaviour of a naive edge mask and the reason people give up on them.

After that you get the usual finishing chain: threshold_low/threshold_high for a soft clip, gamma for the curve, blur_radius for feathering, expand_mask for morphological grow/shrink (±64 pixels), invert, and a normalize toggle that min-max normalizes each map.

Inputs and outputs

One input: image (IMAGE) - typically the decoded output of a generation, or an upscaled result.

Five outputs: mask (the thing you use, single-channel), plus edge_map, texture_map, flat_map as MASK, and a report STRING with mask mean, edge mean, texture mean, flat mean and all your settings echoed back. Wire the component maps to previews while tuning - seeing flat_map light up on the sky tells you instantly whether your suppression is doing what you think.

Downstream, mask feeds anything that takes a MASK: a masked noise injection, an inpaint pass, a compositing node, an area-weighted detailer. The natural pairing inside this pack is KoO Latent Noise Injector - build a "where's the texture" mask from the image, then inject noise only into the busy regions, or invert it and inject only into the smooth ones to add grain where the model left a plastic surface.

Honest about the limits

A frequency mask can't tell a smooth plaster wall from a smooth cheek. It will happily include skin pores as "detail" and exclude a sharp-edged flat logo as an edge. That makes it excellent for material and texture work - grain where grain belongs, keeping flat gradients flat - and risky for anything that needs object knowledge. If the job is "mask the face," use a detector; the detector loop is a solved, well-documented pattern and this node isn't pretending to be it.

It's also, like the rest of the Noise Lab, 4D-only in practice. Feed it a batch and it works per-frame; feed it a 5D tensor and it won't.

Installing it

cd ComfyUI/custom_nodes
git clone https://github.com/kevintronchin-blip/koo-nodes-pack

Restart ComfyUI. Pure tensor math on top of torch - no models, no extra packages, no frontend component. It's under KoO/Noise Lab.

Registry and Manager availability at v1.0.3 depends on moderation approval; the README's supported install is the source ZIP extracted as ComfyUI/custom_nodes/koo-nodes-pack with __init__.py directly inside.

Troubleshooting

The mask is all grey mush. threshold_low/threshold_high are too wide, or flat_surface_suppression is fighting you. Set normalize on, preview edge_map on its own, then tighten the thresholds.

The mask is almost entirely black. Your image is smooth at this resolution - or you're feeding a heavily denoised upscale. expand_mask and a lower threshold_low will recover some of it, but a genuinely flat image has genuinely little to find.

Hard edges on the mask. blur_radius of 4–12 is the standard feathering range for anything that's going to be blended. Zero blur means visible transitions wherever the mask ends.

Everything selected, including the background. Turn flat_surface_suppression up toward 1.0 and re-check flat_map - the bug is usually that you inverted your intuition about which map is which, not the node.

CategoryKoO/Noise Lab

Inputs (12)

NameTypeDefaultDescription
imageIMAGE—
modeCOMBOcombined4 options: edges, local_variance, high_frequency, combined
edge_strengthFLOAT1.000–4—
texture_strengthFLOAT1.000–4—
flat_surface_suppressionFLOAT0.750–1—
threshold_lowFLOAT0.050–1—
threshold_highFLOAT0.950–1—
blur_radiusFLOAT0.000–64—
expand_maskINT0-64–64—
gammaFLOAT1.000.1–4—
invertBOOLEANfalse—
normalizeBOOLEANtrue—

Outputs (5)

NameTypeDescription
maskMASK—
edge_mapMASK—
texture_mapMASK—
flat_mapMASK—
reportSTRING—