ComfyUI Node

Mask: Sky

Select the Sky Without a Segmenter, a Download or a Prompt

By jetthuangai·Created 6 months ago·Updated a day ago· 6
Mask: Sky
  • image
  • sky_mask
◄sensitivity0.50►
◄refine_edgestrue►

Every sky-replacement tutorial starts the same way: paint a gradient mask, then spend ten minutes cleaning branches. Mask: Sky (JHPixelProSkyMask) skips both. It's a classical vision node - no model, no checkpoint, no prompt, about 0.2 seconds per photo - and it returns a soft sky mask good enough to grade through.

The name is not a lie in either direction. There's no hidden ONNX file: the whole thing is colour, texture and geometry heuristics.

What it looks for

Four signals, and knowing them tells you exactly when it will fail:

Colour. Blue sky by hue (roughly 170–260°) with some saturation. Overcast and white cloud by "bright and nearly grey" - with a wrinkle: in a photo that clearly has blue sky, whites warmer than neutral get rejected, because that's a sunlit wall, not a cloud. Sunset glow scores at half weight, restricted to the upper half of the frame.

Smoothness. Sky has no fine texture. Local luma standard deviation must be low. Clouds and gradients pass; leaves, buildings, grass and gravel don't. This is the test that does most of the work.

Position. The sky is open to the top of the frame. Candidate regions must touch the top rows, or be large and in the upper half, or be large and clearly blue. That's what stops a smooth white wall low in the frame from being selected.

Edges. The readout happens on a proxy no longer than 768 px, then the mask is scaled up and refined with a colour-guided filter against the full-resolution photo. That's the part that makes the result usable: the edge follows branches and roof lines instead of stair-stepping at proxy resolution.

The two inputs that matter

image, naturally. Then:

sensitivity, 0 to 1, default 0.5. Higher reaches hazy, textured and sunset sky - raise it for thin cloud, textured cloud, warm evening light. Lower keeps only clear sky - lower it when a white wall or the surface of a lake leaks in.

refine_edges, on by default. Leave it on. Turning it off gives you a plain soft proxy-resolution mask, which is only useful if you want to see what the raw classifier thought.

One output: sky_mask, a soft MASK, one per image in a batch. White is sky.

Where it fits in a real workflow

The obvious use is grading the sky on its own - run the mask into the mask input of a colour node and lift or calm just the sky. The less obvious and more valuable use is the inverse: protect the sky while you edit everything else. A Color Matcher pass or a Shadows/Highlights lift applied to a whole frame will happily flatten your sky; gate it with show sky = off and the foreground changes while the sky keeps its detail.

It's also a cheap substitute for promptable masking when the target is "the sky" specifically. You can point SAM at a sky, and it works, but you're loading gigabytes to segment something that isn't actually ambiguous. A heuristic that keys on blueness and smoothness knows more about sky than a general object segmenter does.

Then wire the result into a Mask Preview to check it before you trust it, and into Mask Combine if you need to subtract water or add back a roof edge.

Install

ComfyUI Manager → search ComfyUI-JH-PixelPro → install → restart. Or:

cd ComfyUI/custom_nodes
git clone https://github.com/jetthuangai/ComfyUI-JH-PixelPro.git
cd ComfyUI-JH-PixelPro
pip install -r requirements.txt

Restart, then Add Node → ComfyUI-JH-PixelPro → mask. Dependencies for the whole pack are Python 3.10+, kornia>=0.7, MediaPipe, OpenCV headless and SciPy; this node itself is OpenCV plus Torch and needs no weights. The pack is Apache-2.0, 64 nodes, maintained by @jetthuangai, with bilingual per-node docs.

Where it goes wrong

Water at the horizon is included. Calm water that touches the sky reads as smooth and blue, so it gets taken in. The documented fix is to build a mask for the water and subtract it with Mask Combine - or drop sensitivity and accept a tighter sky. Don't expect the node to know about reflections.

A white wall touching the sky leaks in. The position test catches white walls low in the frame; one that runs up to the skyline can still sneak through. Lower sensitivity, then clean up with Mask Cleanup.

Textured or dramatic clouds get missed. They fail the smoothness test, which is exactly why sensitivity exists. Nudge it up in 0.05 steps while watching the mask in heatmap mode - this is the node where heatmap preview earns its keep, because you can see the difference between "half-weight" and "fully selected".

Shot into the sun through branches. Hard case by construction: little sky touches the top rows. The fallback (large, clearly blue regions anywhere) helps, but expect to hand-clean through the canopy.

A grey, flat overcast sky in a desaturated photo. The white/overcast path needs brightness and near-neutrality; a moody grey sky at 40% brightness can slip under the threshold. Raise sensitivity before you give up on it.

One expectation to set: this pack has no Reddit footprint, so there's no "here's my settings" folklore to find. The upside is that it documents its own heuristics honestly - the mechanism above is the author's, not my guess - so when it fails you can reason about which test failed instead of re-rolling parameters blindly.

CategoryComfyUI-JH-PixelPro/mask

Inputs (3)

NameTypeDefaultDescription
imageIMAGEPhoto with sky.
sensitivityFLOAT0.500–1Higher also takes hazy, textured or sunset sky; lower keeps only clear sky.
refine_edgesBOOLEANtrueFollow branches and roof lines at full resolution.

Outputs (1)

NameTypeDescription
sky_maskMASK—