Light-Tool: Morphological Transform
Dilate and erode — the mask cleanup you keep needing
- image
- image
Masks are never clean the way you want them. Inpainting regions have hairline gaps, segmentation masks have stray specks, and feathering eats the edge you were trying to protect. The classic fix is morphology - dilate (grow the white) or erode (shrink it) - and Light-Tool: MorphologicalTF is the pack's one-node version of that.
Inputs: image (required), option (dropdown: dilate or erode), kernel_x and kernel_y (kernel size in each dimension, default 3), and iterations (how many passes, default 1). Output: one image.
How it works. The image is converted to grayscale, then handed to OpenCV's dilate or erode with an all-ones kernel of your chosen size. Each iteration grows or shrinks the bright regions by roughly half the kernel size. The math is bog-standard morphology: every pixel is compared against its neighbors in the kernel window, and dilation keeps the maximum while erosion keeps the minimum. That's the whole mechanism, and it's the right one.
What the knobs actually do. Kernel size sets how aggressive each pass is - a 3×3 kernel nudges edges a pixel or two, 7×7 takes a real bite. iterations chains passes, so "erode twice at 3×3" erodes more than once at 3×3. The practical recipes: an erode pass kills speckle noise, a dilate pass closes small holes, and erode-then-dilate (opening) removes stray specks without shrinking the main shape. You can't chain both in one node - you'll wire two of these in sequence, which is exactly how it's meant to be used.
The gotchas. It expects an IMAGE, not a MASK - same convention as the rest of this pack's mask-flavored nodes, so route real masks through MaskToImage first (and optionally back through ImageToMask after). The kernel is always rectangular and all-ones; there's no ellipse or cross shape, which matters if you're doing careful anatomical masks where a square kernel leaves corners. And because it operates on grayscale, soft-edged masks get treated by threshold-adjacent logic rather than preserving their exact gradient - you'll see the feathering get chunkier as you apply passes. For crisp binary masks none of that bites.
When you'd reach for it. Growing an inpainting region so the repaint bleeds into surrounding context, shrinking a mask to strip background fringe, or cleaning a segmentation mask before it goes into a detailer. It's the quiet workhorse behind half of decent mask pipelines.
Installing. With the pack:
cd ComfyUI/custom_nodes
git clone https://github.com/ihmily/ComfyUI-Light-Tool.git
pip install -r requirements.txt
# restart ComfyUI
Or ComfyUI Manager → search ComfyUI-Light-Tool → Install. No models; opencv-python from the pack's requirements does the actual work.
Solid, predictable, and genuinely useful - the only real skill is remembering that two sequential nodes beat one clever one, and that IMAGE-not-MASK convention.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| option | COMBO | dilate | 2 options: dilate, erode |
| kernel_x | INT | 3 | — |
| kernel_y | INT | 3 | — |
| iterations | INT | 1 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |