Real thresholded masks are full of specks and holes; morphology fixes them before you count or measure objects.
Morphology treats a binary mask as a set of shapes and grows or shrinks them with a structuring element (kernel), created with cv2.getStructuringElement(cv2.MORPH_RECT | MORPH_ELLIPSE | MORPH_CROSS, (w, h)).
cv2.erode: a pixel stays white only if the whole kernel fits inside the white region. Shapes shrink, thin bridges break, small specks vanish.cv2.dilate: a pixel becomes white if the kernel touches any white. Shapes grow, small holes and gaps fill.
Combinations via cv2.morphologyEx(mask, op, kernel):
MORPH_OPEN(erode then dilate): removes small white noise while mostly keeping object sizeMORPH_CLOSE(dilate then erode): fills small black holes and joins nearby fragmentsMORPH_GRADIENT: dilation minus erosion, an outline of each shapeMORPH_TOPHATandMORPH_BLACKHAT: extract small bright or dark details relative to the background
The kernel size sets the scale of what gets removed: an opening with a 5x5 kernel deletes anything thinner than about 5 pixels. iterations= repeats the operation.
The conventions assume white foreground on black background. If your objects are dark, invert the mask first (or use THRESH_BINARY_INV), otherwise erode and dilate swap meanings.
Example
import cv2
import numpy as np
mask = np.zeros((40, 40), np.uint8)
mask[10:30, 10:30] = 255 # the object
mask[15, 15] = 0 # a hole inside it
mask[2, 35] = 255 # a stray speck
k = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
opened = cv2.morphologyEx(mask, cv2.MORPH_OPEN, k)
print(opened[2, 35]) # 0 speck removed
closed = cv2.morphologyEx(opened, cv2.MORPH_CLOSE, k)
print(closed[15, 15]) # 255 hole filled
print((mask == 255).sum()) # 400
print((cv2.erode(mask, k) == 255).sum()) # fewer: shapes shrank
print((cv2.dilate(mask, k) == 255).sum()) # more: shapes grew
edge = cv2.morphologyEx(closed, cv2.MORPH_GRADIENT, k)
print(edge[20, 10], edge[20, 20]) # 255 0 outline onlyRemember
- Erode shrinks white regions, dilate grows them
- Opening removes small specks, closing fills small holes
- Kernel size sets the scale of what gets removed
- Morphology assumes white objects on black
Watch out for
- Applying morphology to dark-on-light masks without inverting, which reverses the effect.