5. 形态变换

本文介绍了图像处理中的基本操作——侵蚀和膨胀,以及它们在去除噪声和调整对象尺寸方面的作用。同时讲解了形态变换,包括开运算、闭运算、形态梯度、顶帽和黑帽等,以及如何在Python中使用OpenCV实现这些操作。此外,还讨论了结构元素的选择和创建,以及它们对变换效果的影响。
摘要由CSDN通过智能技术生成

1. 侵蚀

侵蚀的基本思想就像土壤侵蚀一样,它侵蚀了前景物体的边界(始终尽量保持前景为白色)。那么它有什么作用呢?内核在图像中滑动(如在 2D 卷积中)。仅当内核下的所有像素都为 1 时,原始图像中的像素(1 或 0)才会被视为 1,否则它会被侵蚀(使其为零)。所以发生的事情是,根据内核的大小,边界附近的所有像素都将被丢弃。因此,前景对象的厚度或大小会减少,或者只是图像中的白色区域会减少。它对于去除小的白噪声、分离两个连接的对象等很有用。
python中用法:

dst	=	cv.erode(	src, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]]	)
参数描述
src输入图片矩阵
dst输出图片矩阵
kernel用于侵蚀的结构元素;如果 element=Mat(),则使用 3 x 3 矩形结构元素。可以使用 getStructuringElement 创建内核。
anchor元素内锚点的位置;默认值 (-1, -1) 表示锚点位于元素中心。
iterations应用侵蚀的次数
borderType像素外插方法,参见 BorderTypes。不支持 BORDER_WRAP。
borderValue边界不变的情况下的边界值
import cv2 as cv
import numpy as np
img = cv.imread('j.png',0)
kernel = np.ones((5,5),np.uint8) # 自定义内核
erosion = cv.erode(img,kernel,iterations = 1)
plt.subplot(1, 2, 1), plt.imshow(img, 'gray'), plt.title("Original")
plt.xticks([]), plt.yticks([])
plt.subplot(1, 2, 2), plt.imshow(erosion, 'gray'), plt.title("Erosion")
plt.xticks([]), plt.yticks([])
plt.show()

在这里插入图片描述

2.扩张

它与侵蚀正好相反。这里,如果内核下至少一个像素为“1”,则像素元素为“1”。所以它增加了图像中的白色区域或前景对象的大小增加。通常,在去除噪声等情况下,腐蚀之后是膨胀。因为,侵蚀去除了白噪声,但它也缩小了我们的对象。所以我们扩张它。由于噪音消失了,它们不会回来,但我们的对象区域会增加。它也可用于连接对象的损坏部分。
python中用法:

dst	=	cv.dilate(	src, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]]	)
参数描述
src输入图片矩阵
dst输出图片矩阵
kernel用于侵蚀的结构元素;如果 element=Mat(),则使用 3 x 3 矩形结构元素。可以使用 getStructuringElement 创建内核。
anchor元素内锚点的位置;默认值 (-1, -1) 表示锚点位于元素中心。
iterations应用膨胀的次数
borderType像素外插方法,参见 BorderTypes。不支持 BORDER_WRAP。
borderValue边界不变的情况下的边界值

在这里插入图片描述

3. 形态变换

morphologyEx()执行高级形态变换。函数 cv::morphologyEx 可以使用腐蚀和膨胀作为基本操作来执行高级形态变换。任何操作都可以就地完成。在多通道图像的情况下,每个通道都是独立处理的。

python中用法:

dst	=	cv.morphologyEx(	src, op, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]]	)
参数描述
src输入图片矩阵
dst输出图片矩阵
op形态操作的类型,参见 MorphTypes
kernel结构元素。它可以使用 getStructuringElement 创建。
anchor用内核锚定位置。负值表示anchor位于内核中心。
iterations应用腐蚀和膨胀的次数。
borderType像素外插方法,参见 BorderTypes。不支持 BORDER_WRAP。
borderValue边界不变的情况下的边界值

MorphTypes

类型描述
MORPH_ERODE Python: cv.MORPH_ERODE参考erode
MORPH_DILATE Python: cv.MORPH_DILATE参考dilate
MORPH_OPENPython: cv.MORPH_OPEN开运算
d s t = o p e n ( s r c , e l e m e n t ) = d i l a t e ( e r o d e ( s r c , e l e m e n t ) ) dst=open(src,element)=dilate(erode(src,element)) dst=open(src,element)=dilate(erode(src,element))
MORPH_CLOSE Python: cv.MORPH_CLOSE闭运算
d s t = c l o s e ( s r c , e l e m e n t ) = e r o d e ( d i l a t e ( s r c , e l e m e n t ) ) dst=close(src,element)=erode(dilate(src,element)) dst=close(src,element)=erode(dilate(src,element))
MORPH_GRADIENT Python: cv.MORPH_GRADIENT形态梯度
d s t = m o r p h g r a d ( s r c , e l e m e n t ) = d i l a t e ( s r c , e l e m e n t ) − e r o d e ( s r c , e l e m e n t ) dst=morph_grad(src,element)=dilate(src,element)−erode(src,element) dst=morphgrad(src,element)=dilate(src,element)erode(src,element)
MORPH_TOPHAT Python: cv.MORPH_TOPHAT顶帽
d s t = t o p h a t ( s r c , e l e m e n t ) = s r c − o p e n ( s r c , e l e m e n t ) dst=tophat(src,element)=src−open(src,element) dst=tophat(src,element)=srcopen(src,element)
MORPH_BLACKHAT Python: cv.MORPH_BLACKHAT黑帽
d s t = b l a c k h a t ( s r c , e l e m e n t ) = c l o s e ( s r c , e l e m e n t ) − s r c dst=blackhat(src,element)=close(src,element)−src dst=blackhat(src,element)=close(src,element)src
MORPH_HITMISS Python: cv.MORPH_HITMISS“命中或未命中” .- 仅支持 CV_8UC1 二进制图像。可以在文档中找到教程

3.1 开运算

开运算只是侵蚀后膨胀的另一个名称。正如我们上面所解释的,它在消除噪声方面很有用。这里我们使用函数cv.morphologyEx()

opening = cv.morphologyEx(img, cv.MORPH_OPEN, kernel)

在这里插入图片描述

3.2 闭运算

闭运算与开运算、膨胀和侵蚀相反。它可用于关闭前景对象内的小孔或对象上的小黑点。

closing = cv.morphologyEx(img, cv.MORPH_CLOSE, kernel)

在这里插入图片描述

3.3 形态梯度

这是图像膨胀和腐蚀之间的区别。结果看起来像是图像的轮廓

gradient = cv.morphologyEx(img, cv.MORPH_GRADIENT, kernel)

3.4 顶帽

它是输入图像和输入图像开运算之间的差异。下面的例子是针对一个9x9的内核做的。

kernel = np.ones((9, 9), np.uint8)
tophat = cv.morphologyEx(img, cv.MORPH_TOPHAT, kernel)

在这里插入图片描述

3.5 黑帽

它是输入图像和输入图像的闭运算之间的差异。

blackhat = cv.morphologyEx(img, cv.MORPH_BLACKHAT, kernel)

在这里插入图片描述

结构元素

在前面的例子中,我们在Numpy的帮助下手动创建了一个结构化元素。它是长方形的。但在某些情况下,你可能需要椭圆/圆形的内核。所以为了这个目的,OpenCV有一个函数,cv.getStructuringElement()。你只需传递内核的形状和大小,就可以得到所需的内核

# Rectangular Kernel,矩形内核
>>> cv.getStructuringElement(cv.MORPH_RECT,(5,5))
array([[1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1]], dtype=uint8)
# Elliptical Kernel,椭圆内核
>>> cv.getStructuringElement(cv.MORPH_ELLIPSE,(5,5))
array([[0, 0, 1, 0, 0],
       [1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1],
       [0, 0, 1, 0, 0]], dtype=uint8)
# Cross-shaped Kernel,十字内核
>>> cv.getStructuringElement(cv.MORPH_CROSS,(5,5))
array([[0, 0, 1, 0, 0],
       [0, 0, 1, 0, 0],
       [1, 1, 1, 1, 1],
       [0, 0, 1, 0, 0],
       [0, 0, 1, 0, 0]], dtype=uint8)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值