Nodes/ComfyUI SAM3/Mask Outline
ComfyUI Node

Mask Outline

Turn any mask into a clean outline

By wouterverweirder·Created 10 months ago·Updated 8 months ago· 77
Mask Outline
  • mask
  • outline_mask
outline_width5
modeinside

Mask Outline does exactly one thing: feed it a mask and it hands back only the border ring - the stroke around the shape, not the shape. A MASK goes in, a MASK comes out, and the output is just the outline. It's about as small a job as a custom node can have, but you'd be surprised how often it's the missing step.

The use case that makes it click is in the pack's own example workflow ("rectangle around subject"): you want a selection border, not a filled region. Image-edit models and some inpainting setups respond to a clean boundary around an object - a ring that marks "affect this edge, not this interior." The same trick gets you an easy visual check of exactly where a mask's boundary sits, which matters more than you'd think when a SAM run has handed you a mask you don't fully trust. And if you're using this pack's SAM3Segmentation node, its per-object mask batch flows straight in here.

How it works is classic morphology rather than anything fancy. The node erodes the mask (shrinks it by outline_width-ish pixels) and subtracts the result from the original to get an inside ring, or dilates (grows) and subtracts the original to get an outside ring. The structuring element is an ellipse, cv2.MORPH_ELLIPSE, which is why the strokes come out smooth instead of blocky. The one bit of real engineering: masks that touch the image edge are padded with zeros before the erosion, so you still get a proper inner outline on shapes that run off the canvas - a corner case that silently breaks most hand-rolled versions of this node. It also processes batches frame by frame, so video masks work without splitting anything up.

The inputs that matter are few. mask is any MASK tensor, batch or single. outline_width (default 5, range 1–100) sets the thickness in pixels. mode picks inside, outside, or both, defaulting to inside. Inside is usually the right call: the ring stays on the object, so background pixels never leak in, even at the image border. The single output is outline_mask, a float32 MASK you can wire into a mask-combine, an inpaint node, or a preview.

Install. It ships in the ComfyUI SAM3 pack, so ComfyUI Manager covers it - search "ComfyUI SAM3" - or do it by hand:

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

Then restart ComfyUI. Fair warning: this node never touches the SAM3 model, but the pack's nodes.py imports the sam3 library at module load, so you still pay for the whole dependency tree - timm, decord, pycocotools, iopath, and triton (or triton-windows on Windows, which is the classic install hurdle there). No checkpoint, no HuggingFace login, nothing gated - the model friction is entirely for the SAM3Segmentation node, not this one.

Troubleshooting. The heavy lifting is OpenCV, which ComfyUI already bundles, so cv2 errors are rare. If the node won't appear at all, the pack's dependencies failed to install - check for the Triton failure specifically on Windows. If the outline looks too thick or thin for what you asked, remember the elliptical kernel means the visible ring is roughly outline_width pixels, and both mode doubles it (inside plus outside). Output is explicitly float32, so you won't hit autocast surprises feeding it into downstream models.

It's a utility, not a headliner - but when you need a stroke around a segmented object for an edit or inpaint boundary, it's the one you reach for, and it does the fiddly edge cases right.

CategorySAM3

Inputs (3)

NameTypeDefaultDescription
maskMASKInput mask to create outline from
outline_widthINT51–100Width of the outline in pixels
modeCOMBOinsideCreate outline inside, outside, or on both sides of the mask boundary

Outputs (1)

NameTypeDescription
outline_maskMASK