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

OpenCV的imgproc 模块:形态学变换函数 cv2.erode、cv2.dilate、cv2.morphologyEx ——OpenCV官方教程翻译(全网最详细)

  • 一、目标(Goal)
  • 二、原理(Theory)
  • 三、形态学变换(Morphological Transformations)
    • 3.1 腐蚀(Erosion)
      • 3.1.1 cv2.erode()函数
      • 举例演示
    • 3.2 膨胀(Dilation)
      • 3.2.1 cv2.dilate()函数
      • 举例演示
    • 3.3 腐蚀、膨胀混合运算
      • 3.3.1 开运算(Opening)
        • 3.3.1.1 cv2.morphologyEx()函数cv2.MORPH_OPEN
      • 举例演示
      • 3.3.2 闭运算(Closing)
        • 3.3.2.1 cv2.morphologyEx()函数cv2.MORPH_CLOSE
      • 举例演示
      • 3.3.3 形态学梯度运算(Morphological Gradient)
        • 3.3.3.1 cv2.morphologyEx()函数cv2.MORPH_GRADIENT
      • 举例演示
  • 形态学梯度(cv2.MORPH_GRADIENT)
      • 3.3.4 礼帽(Top Hat)
        • 3.3.4.1 cv2.morphologyEx()函数cv2.MORPH_TOPHAT
      • 举例演示
      • 3.3.5 黑帽(Black Hat)
        • 3.3.5.1 cv2.morphologyEx()函数cv2.MORPH_BLACKHAT
      • 举例演示

一、目标(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_CONSTANT iiiiii-abcdefgh-iiiiiii with some specified i
cv2.BORDER_REPLICATE aaaaaa-abcdefgh-hhhhhhh
cv2.BORDER_REFLECT fedcba-abcdefgh-hgfedcb
cv2.BORDER_WRAP cdefgh-abcdefgh-abcdefg
cv2.BORDER_REFLECT_101 gfedcb-abcdefgh-gfedcba
cv2.BORDER_TRANSPARENT uvwxyz-abcdefgh-ijklmno
cv2.BORDER_REFLECT101 same as BORDER_REFLECT_101
cv2.BORDER_DEFAULT same as BORDER_REFLECT_101
cv2.BORDER_ISOLATED do 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)

运行结果:
【OpenCV-图像处理】形态学变换函数——OpenCV官方教程翻译(全网最详细)_第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()

运行结果:
【OpenCV-图像处理】形态学变换函数——OpenCV官方教程翻译(全网最详细)_第2张图片

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_ERODE see erode
cv2.MORPH_DILATE see dilate
cv2.MORPH_OPEN an opening operation ,dst=open(src,element)=dilate(erode(src,element))
cv2.MORPH_CLOSE a closing operation,dst=close(src,element)=erode(dilate(src,element))
cv2.MORPH_GRADIENT a 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()

运行结果:
【OpenCV-图像处理】形态学变换函数——OpenCV官方教程翻译(全网最详细)_第3张图片

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()

运行结果:【OpenCV-图像处理】形态学变换函数——OpenCV官方教程翻译(全网最详细)_第4张图片

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()

运行结果:
【OpenCV-图像处理】形态学变换函数——OpenCV官方教程翻译(全网最详细)_第5张图片

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()

运行结果:
【OpenCV-图像处理】形态学变换函数——OpenCV官方教程翻译(全网最详细)_第6张图片

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-图像处理】形态学变换函数——OpenCV官方教程翻译(全网最详细)_第7张图片

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

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

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

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

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

你可能感兴趣的:(OpenCV图像处理,opencv,计算机视觉,python,深度学习)