形态学操作是根据图像形状进行的简单操作。一般情况下对二值化图像/灰度图像进行操作。它需要输入两个操作,一个是原始图像,另一个被称为结构化元素或核,它是用来决定操作的性质的。两个基本的形态学操作是腐蚀和膨胀,它们的变体构成了开运算、闭运算和梯度等。简言之,形态学操作其实就是改变物体的形状,比如腐蚀就是"变瘦",膨胀就是"变胖",注意腐蚀和膨胀是针对图片中的白色部分。效果展示如下图:
腐蚀的效果是把图片"变瘦",其原理是在原图的小区域内取局部最小值。因为是二值化图,只有 0 和 255,所以小区域内有一个是 0 该像素点就为 0:
OpenCV 中用cv2.erode()
函数进行腐蚀,只需要指定核的大小即可:
img = cv2.imread('j.bmp', 0)
kernel = np.ones((5, 5), np.uint8)
erosion = cv2.erode(img, kernel)
这个核也叫结构元素,因为形态学操作其实也是应用卷积来实现的。结构元素可以是矩形/椭圆/十字形,可以用cv2.getStructuringElement()
来生成不同形状的结构元素,比如:
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5)) # 矩形结构
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5)) # 椭圆结构
kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (5, 5)) # 十字形结构
膨胀与腐蚀相反,取的是局部最大值,效果是把图片"变胖"。OpenCV 中用cv2.dilate()
函数进行腐蚀,只需要指定核的大小即可:
dilation = cv2.dilate(img, kernel)
开运算:先腐蚀后膨胀,可用以消除黑色背景中的白点杂质,如下图左边所示。该操作用cv2.morphologyEx()
函数实现。
img = cv2.imread('j_noise_out.bmp', 0)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
闭运算:先膨胀后腐蚀,可用以消除白色前景中的黑点杂质,如下图右边所示。该操作用cv2.morphologyEx()
函数实现。
img = cv2.imread('j_noise_out.bmp', 0)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
形态学梯度:膨胀图减去腐蚀图 (dilation - erosion),得到物体轮廓。
- 基本梯度:基本梯度是用膨胀后的图像减去腐蚀后的图像得到差值图像,成为梯度图像。也是 opencv 中支持的计算形态学梯度的方法,而此方法得到的梯度又被成为基本梯度。
- 内部梯度:用原图像减去腐蚀后的图像得到的差值图像,称为图像的内部梯度。
- 外部梯度:原图像膨胀后减去原图像得到的差值图像,称为图像的外部梯度。
img = cv2.imread('school.bmp', 0)
gradient = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)
顶帽:原图减去开运算后的图 (src - opening)。
tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)
黑帽:闭运算后的图减去原图 (closing - src)。
blackhat = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)
【参考】