Nodes/opencv-comfyui/OpenCV morphologyEx_0
ComfyUI Node

OpenCV morphologyEx_0

Kill specks, fill holes, and extract edges

By geroldmeisinger·Created about a year ago·Updated about a year ago· 35
OpenCV morphologyEx_0
  • src
  • kernel
  • dst
  • nparray
op
anchor
iterations
borderType
borderValue

If you do anything with masks - SAM outputs, depth thresholds, inpaint regions - you know they come out noisy. Stray specks, pinhole gaps, fuzzy edges. morphologyEx_0 wraps cv2.morphologyEx, which is the classic toolkit for fixing exactly that: it erodes and dilates a binary image in combinations that remove specks, close holes, and extract edges. It's the single most practically useful node in this whole auto-generated pack, so it's worth learning its raw edges.

The operations (the op input)

op is a raw INT - there's no dropdown, and that's the pack's most user-hostile decision (the author has literally acked that "we should use COMBO"). The codes:

  • 2 = ERODE - shrinks white regions, strips thin protrusions
  • 3 = DILATE - grows white regions, thickens shapes
  • 4 = OPEN - erode then dilate: removes white specks/salt noise. The most-used one for masks
  • 5 = CLOSE - dilate then erode: fills small holes/pepper noise
  • 6 = GRADIENT - dilate minus erode: extracts edges of shapes
  • 7 = TOPHAT - src minus open: pulls out small bright details
  • 8 = BLACKHAT - close minus src: pulls out small dark details
  • 9 = HITMISS - exact pattern matching; almost never what you want here

The classic mask-cleanup chain is OPEN (kill specks) then CLOSE (fill holes), often with iterations bumped to 2–3 for dirtier masks. Gradient is how you turn a mask into an edge map.

Inputs that matter

  • src (NPARRAY) - the mask. Grayscale/single-channel is the norm; that's what a mask already is.
  • op - one of the codes above.
  • kernel (NPARRAY) - the structuring element, the shape the operation uses. You build it with getStructuringElement_0 from this same pack (it takes a shape code and a size literal like (5, 5)). Bigger kernel = more aggressive effect.
  • anchor (STRING) - a literal like (-1, -1) for "center of the kernel". Default and usually fine.
  • iterations (INT) - how many times to apply.
  • borderType (INT) - edge handling; 0 is usually fine.
  • borderValue (STRING) - a literal Scalar, e.g. (0, 0, 0, 0). Only matters for constant borders.
  • dst (optional NPARRAY) - the out-parameter; leave it unconnected.

Output: nparray, which goes back through Nparrays2Image to view.

Literals, the recurring gotcha

anchor and borderValue are typed as strings and parsed with ast.literal_eval. Type them exactly like Python: (-1, -1) or (0, 0, 0, 0). A typo - missing paren, wrong brackets - gives invalid syntax (<unknown>, line 0) and the node won't run.

Installing

Part of geroldmeisinger/opencv-comfyui. Via ComfyUI Manager (search "opencv-comfyui") or:

cd ComfyUI/custom_nodes
git clone https://github.com/geroldmeisinger/opencv-comfyui

restart. Dependency: opencv-contrib-python (usually already present).

Pipeline and troubleshooting

IMAGE → Image2Nparray → morphologyEx_0 → Nparrays2Image → IMAGE. Image2Nparray handles RGB→BGR and only accepts batch_size==1.

  • "Can't find the kernel input type" - you need getStructuringElement_0 to make a kernel array; there's no widget for it.
  • invalid syntax (<unknown>, line 0) - check your literal strings: (-1, -1), not (-1, -1 .
  • Mask looks like it's doing nothing - check that op is a number in the list above, and that your kernel size isn't (1, 1) (a 1×1 kernel is a no-op).
Categoryimage/OpenCV

Inputs (8)

NameTypeDefaultDescription
srcNPARRAY
opINT
kernelNPARRAY
anchorSTRING
iterationsINT
borderTypeINT
borderValueSTRING
dstoptNPARRAY

Outputs (1)

NameTypeDescription
nparrayNPARRAY