【OpenCV-图像处理】形态学变换函数——OpenCV官方教程翻译(全网最详细)

一、目标(Goal)

在这一章,
我们将学习不同的形态学操作,如侵蚀,膨胀,开运算,闭运算、梯度运算、礼帽、黑帽。
我们将学习以下不同的函数,如:cv2.erode()cv2.dilate()cv2.morphologyEx()等。

二、原理(Theory)

形态变换是一种基于图像形状的简单操作。它通常在二值图像上执行。它需要两个输入,一个是我们的原始图像,另一个被称为结构元素或内核,它决定了操作的性质。两个基本的形态算子是腐蚀和膨胀。然后还有它的混合运算形式,如开运算,闭运算、梯度运算、礼帽、黑帽也发挥不同的作用。
最基本的形态学操作有二:腐蚀与膨胀(Erosion 与 Dilation)。
他们的运用广泛:
· 消除噪声
· 分割(isolate)独立的图像元素,以及连接(join)相邻的元素。
· 寻找图像中的明显的极大值区域或极小值区域。

三、形态学变换(Morphological Transformations)

3.1 腐蚀(Erosion)

腐蚀的基本思想就像土壤腐蚀一样,它腐蚀了前景对象的边界(总是尽量保持前景为白色)。那么它有什么作用呢?内核在图像中滑动(如在2D卷积中)。只有当内核下的所有像素都为1时,原始图像中的一个像素(1或0)才会被认为是1,否则它就会被腐蚀(变为0)。
所以发生的是,所有靠近边界的像素都将被丢弃,这取决于kernel的大小。因此前景物体的厚度或大小减少,或者只是图像中的白色区域减少。它可以用来去除小的白噪声(如我们在colorspace章节中看到的),分离两个连接的物体等。

3.1.1 cv2.erode()函数

dst = cv2.erode	(	InputArray 	src,
					InputArray 	kernel,
					Point 	anchor = Point(-1,-1),
					int 	iterations = 1,
					int 	borderType = BORDER_CONSTANT,
					const Scalar & 	borderValue = morphologyDefaultBorderValue() 
)
参数说明
src输入图像;通道的数量可以是任意的,但是深度应该是CV_8U、CV_16U、CV_16S、CV_32F或CV_64F之一
dst输出与src相同大小和类型的图像
kernel用于腐蚀的结构元件;如果element=Mat(),则使用3 × 3的矩形结构单元。可以使用getStructuringElement创建内核
anchor锚点在元素中的位置;默认值(-1,-1)表示锚位于元素的中心
iterations应用腐蚀的次数
borderType像素外推方法,见BorderTypes。不支持BORDER_WRAP
borderValue边界为常量时的边界值

BorderTypes

BorderTypes参数说明
cv2.BORDER_CONSTANTiiiiii-abcdefgh-iiiiiii with some specified i
cv2.BORDER_REPLICATEaaaaaa-abcdefgh-hhhhhhh
cv2.BORDER_REFLECTfedcba-abcdefgh-hgfedcb
cv2.BORDER_WRAPcdefgh-abcdefgh-abcdefg
cv2.BORDER_REFLECT_101gfedcb-abcdefgh-gfedcba
cv2.BORDER_TRANSPARENTuvwxyz-abcdefgh-ijklmno
cv2.BORDER_REFLECT101same as BORDER_REFLECT_101
cv2.BORDER_DEFAULTsame as BORDER_REFLECT_101
cv2.BORDER_ISOLATEDdo not look outside of ROI

通过使用特定的结构元素来腐蚀图像。
该函数使用指定的结构元素来腐蚀源图像,该结构元素决定了取最小值的像素邻域的形状:
在这里插入图片描述
本功能支持就地模式。腐蚀可以应用多次(迭代)。对于多通道图像,每个通道都是独立处理的。

举例演示

import cv2
import numpy as np

# 腐蚀(cv2.erode())
img = cv2.imread('Xu.jpg')
kernel = np.ones((3,3),np.uint8)
erosion = cv2.erode(img,kernel,iterations = 1)

运行结果:
在这里插入图片描述

3.2 膨胀(Dilation)

它正好与腐蚀相反。在这里,如果内核下至少有一个像素是‘1’,那么像素元素就是‘1’。因此它增加了图像中的白色区域或前景物体的大小。通常,在去除噪声这样的情况下,腐蚀紧随而来的是膨胀。因为腐蚀除去了白噪音,但它也缩小了我们的物体。我们把它膨胀。因为噪音消失了,它们不会再回来,但是我们的目标区域增加了。它在连接对象的破碎部分时也很有用。

3.2.1 cv2.dilate()函数

dst = cv2.dilate	(	InputArray 	src,
						InputArray 	kernel,
						Point 	anchor = Point(-1,-1),
						int 	iterations = 1,
						int 	borderType = BORDER_CONSTANT,
						const Scalar & 	borderValue = morphologyDefaultBorderValue() 
)	
参数说明
src输入图像;通道的数量可以是任意的,但是深度应该是CV_8U、CV_16U、CV_16S、CV_32F或CV_64F之一
dst输出与src相同大小和类型的图像
kernel用于膨胀的结构单元;如果elemenat=Mat(),则使用一个3 × 3的矩形结构单元。可以使用getStructuringElement创建内核
anchor锚点在元素中的位置;默认值(-1,-1)表示锚位于元素的中心
iterations应用膨胀的次数
borderType像素外推方法,见BorderTypes。不支持BORDER_WRAP
borderValue边界为常量时的边界值

用特定的结构元素放大图像。
该函数使用指定的结构元素来扩展源图像,该结构元素决定了取最大值的像素邻域的形状:
在这里插入图片描述
本功能支持就地模式。膨胀可以应用多次(迭代)。对于多通道图像,每个通道都是独立处理的。

举例演示

# 膨胀(cv2.dilate())
img = cv2.imread('Xu.jpg')
kernel = np.ones((3,3),np.uint8)
dilate = cv2.dilate(img,kernel,iterations = 1)

cv2.imshow('Original',img)
cv2.imshow('dilate',dilate)

cv2.waitKey(0) 
cv2.destroyAllWindows()

运行结果:
在这里插入图片描述

3.3 腐蚀、膨胀混合运算

3.3.1 开运算(Opening)

开口只是侵蚀和扩张的另一种说法(先腐蚀,再膨胀)。正如我们上面所解释的,它在消除噪声方面是有用的。这里我们用函数,cv2.morphologyEx().

3.3.1.1 cv2.morphologyEx()函数cv2.MORPH_OPEN
dst = cv2.morphologyEx	(	InputArray 	src,
							int 	op,
							InputArray 	kernel,
							Point 	anchor = Point(-1,-1),
							int 	iterations = 1,
							int 	borderType = BORDER_CONSTANT,
							const Scalar & 	borderValue = morphologyDefaultBorderValue() 
)	
参数说明
src输入图像;通道的数量可以是任意的,但是深度应该是CV_8U、CV_16U、CV_16S、CV_32F或CV_64F之一
dst输出与src相同大小和类型的图像
op形态操作的类型,请参见MorphTypes
kernel结构元素。它可以使用getStructuringElement创建。
anchor与内核的锚定位置。负值表示锚点在核中心。
iterations施加侵蚀和膨胀的次数。
borderType像素外推方法,见BorderTypes。不支持BORDER_WRAP。
borderValue边界为常量时的边界值。默认值有特殊含义。

MorphTypes

MorphTypes参数说明
cv2.MORPH_ERODEsee erode
cv2.MORPH_DILATEsee dilate
cv2.MORPH_OPENan opening operation ,dst=open(src,element)=dilate(erode(src,element))
cv2.MORPH_CLOSEa closing operation,dst=close(src,element)=erode(dilate(src,element))
cv2.MORPH_GRADIENTa morphological gradient,dst=morph_grad(src,element)=dilate(src,element)−erode(src,element)
cv2.MORPH_TOPHAT“top hat”,dst=tophat(src,element)=src−open(src,element)
cv2.MORPH_BLACKHAT“black hat”,dst=blackhat(src,element)=close(src,element)−src
cv2.MORPH_HITMISS“hit or miss” .- Only supported for CV_8UC1 binary images. A tutorial can be found in the documentation

执行高级形态转换。
函数cv2.morphologyEx()可以使用侵蚀和扩张作为基本操作来执行高级形态学转换。
任何操作都可以就地完成。对于多通道图像,每个通道都是独立处理的。

注意:迭代次数是应用腐蚀或膨胀操作的次数。例如,具有两个迭代的打开操作(MORPH_OPEN)等效于连续应用:腐蚀->腐蚀->膨胀->膨胀(而不是腐蚀->膨胀->腐蚀->膨胀)。

举例演示

# 开运算(cv2.MORPH_OPEN)
img = cv2.imread('Xu_3.jpg')
kernel = np.ones((3,3),np.uint8)
opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)

cv2.imshow('Original',img)
cv2.imshow('opening',opening)

cv2.waitKey(0) 
cv2.destroyAllWindows()

运行结果:
在这里插入图片描述

3.3.2 闭运算(Closing)

闭合与打开相反,扩张之后是侵蚀(先膨胀,再腐蚀)。
它在关闭前景物体内部的小洞或物体上的小黑点时很有用。

3.3.2.1 cv2.morphologyEx()函数cv2.MORPH_CLOSE

闭运算使用函数和开运算相同,MorphTypes属性改成cv2.MORPH_CLOSE,函数细节介绍在<开运算3.3.2.1 cv2.morphologyEx()函数cv2.MORPH_CLOSE>这一小节

举例演示

# 闭运算(cv2.MORPH_CLOSE)
img = cv2.imread('Xu_2.jpg')
kernel = np.ones((3,3),np.uint8)
closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)

cv2.imshow('Original',img)
cv2.imshow('closing',closing)

cv2.waitKey(0) 
cv2.destroyAllWindows()

运行结果:在这里插入图片描述

3.3.3 形态学梯度运算(Morphological Gradient)

梯度=膨胀-腐蚀=边界

结果将看起来像对象的轮廓

3.3.3.1 cv2.morphologyEx()函数cv2.MORPH_GRADIENT

闭运算使用函数和开运算相同,MorphTypes属性改成cv2.MORPH_GRADIENT,函数细节介绍在<开运算3.3.2.1 cv2.morphologyEx()函数cv2.MORPH_CLOSE>这一小节

举例演示

形态学梯度(cv2.MORPH_GRADIENT)

img = cv2.imread('Xu.jpg')
kernel = np.ones((3,3),np.uint8)
gradient = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)

cv2.imshow('Original',img)
cv2.imshow('gradient',gradient)

cv2.waitKey(0) 
cv2.destroyAllWindows()

运行结果:
在这里插入图片描述

3.3.4 礼帽(Top Hat)

礼帽=原始输入-开运算结果
礼帽又称为顶帽。
因为开运算到来的结果是放大了裂痕或者局部低亮度的区域,因此,从原图中减去运算后的图,得到的效果图突出了比原图轮廓周围的区域更明亮的区域,且这一操作和选择的核的大小相关。
顶帽运算往往用来分离比邻近点亮一些的斑块。当一幅图像具有大幅的背景的时候,而微小物品比较有规律的情况下,可以使用顶帽运算进行背景提取。

3.3.4.1 cv2.morphologyEx()函数cv2.MORPH_TOPHAT

闭运算使用函数和开运算相同,MorphTypes属性改成cv2.MORPH_TOPHAT,函数细节介绍在<开运算3.3.2.1 cv2.morphologyEx()函数cv2.MORPH_CLOSE>这一小节

举例演示

# 礼帽(cv2.MORPH_TOPHAT)
img = cv2.imread('Xu_3.jpg')
kernel = np.ones((3,3),np.uint8)
tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)

cv2.imshow('Original',img)
cv2.imshow('tophat',tophat)

cv2.waitKey(0) 
cv2.destroyAllWindows()

运行结果:
在这里插入图片描述

3.3.5 黑帽(Black Hat)

黑帽 = 闭运算-原始输入

黑帽运算之后的效果图突出了与原图像轮廓周围的区域更暗的区域,且这一操作和选择的核大小相关。所以黑帽运算用来分离比邻近点暗一些的斑块。

3.3.5.1 cv2.morphologyEx()函数cv2.MORPH_BLACKHAT

闭运算使用函数和开运算相同,MorphTypes属性改成cv2.MORPH_BLACKHAT,函数细节介绍在<开运算3.3.2.1 cv2.morphologyEx()函数cv2.MORPH_CLOSE>这一小节

举例演示

# 黑帽(cv2.MORPH_BLACKHAT)
img = cv2.imread('Xu_2.jpg')
kernel = np.ones((3,3),np.uint8)
blackhat = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)

cv2.imshow('Original',img)
cv2.imshow('blackhat',blackhat)

cv2.waitKey(0) 
cv2.destroyAllWindows()

运行结果:
在这里插入图片描述

主要参考于OpenCV官方网站:http://www.opencv.org.cn/

目前博主已更新OpenCV平滑处理函数的的详细介绍,链接如下:
【OpenCV-图像处理】图像平滑处理函数——OpenCV官方教程翻译(全网最详细)

<后续还会继续翻译和整理【OpenCV-图像处理】相关内容,如果需要,可持续关注我哦~>

<翻译和整理不易,留个赞或评论支持一下我吧^^>

如有疑问,欢迎批评指正^^

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

路遥_.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值