在这一章,
我们将学习不同的形态学操作,如侵蚀,膨胀,开运算,闭运算、梯度运算、礼帽、黑帽。
我们将学习以下不同的函数,如:cv2.erode(),cv2.dilate(), cv2.morphologyEx()等。
形态变换是一种基于图像形状的简单操作。它通常在二值图像上执行。它需要两个输入,一个是我们的原始图像,另一个被称为结构元素或内核,它决定了操作的性质。两个基本的形态算子是腐蚀和膨胀。然后还有它的混合运算形式,如开运算,闭运算、梯度运算、礼帽、黑帽也发挥不同的作用。
最基本的形态学操作有二:腐蚀与膨胀(Erosion 与 Dilation)。
他们的运用广泛:
· 消除噪声
· 分割(isolate)独立的图像元素,以及连接(join)相邻的元素。
· 寻找图像中的明显的极大值区域或极小值区域。
腐蚀的基本思想就像土壤腐蚀一样,它腐蚀了前景对象的边界(总是尽量保持前景为白色)。那么它有什么作用呢?内核在图像中滑动(如在2D卷积中)。只有当内核下的所有像素都为1时,原始图像中的一个像素(1或0)才会被认为是1,否则它就会被腐蚀(变为0)。
所以发生的是,所有靠近边界的像素都将被丢弃,这取决于kernel的大小。因此前景物体的厚度或大小减少,或者只是图像中的白色区域减少。它可以用来去除小的白噪声(如我们在colorspace章节中看到的),分离两个连接的物体等。
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)
它正好与腐蚀相反。在这里,如果内核下至少有一个像素是‘1’,那么像素元素就是‘1’。因此它增加了图像中的白色区域或前景物体的大小。通常,在去除噪声这样的情况下,腐蚀紧随而来的是膨胀。因为腐蚀除去了白噪音,但它也缩小了我们的物体。我们把它膨胀。因为噪音消失了,它们不会再回来,但是我们的目标区域增加了。它在连接对象的破碎部分时也很有用。
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()
开口只是侵蚀和扩张的另一种说法(先腐蚀,再膨胀)。正如我们上面所解释的,它在消除噪声方面是有用的。这里我们用函数,cv2.morphologyEx()
.
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()
闭合与打开相反,扩张之后是侵蚀(先膨胀,再腐蚀)。
它在关闭前景物体内部的小洞或物体上的小黑点时很有用。
闭运算使用函数和开运算相同,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()
梯度=膨胀-腐蚀=边界
结果将看起来像对象的轮廓。
闭运算使用函数和开运算相同,MorphTypes属性改成cv2.MORPH_GRADIENT
,函数细节介绍在<开运算3.3.2.1 cv2.morphologyEx()函数cv2.MORPH_CLOSE>这一小节
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()
礼帽=原始输入-开运算结果
礼帽又称为顶帽。
因为开运算到来的结果是放大了裂痕或者局部低亮度的区域,因此,从原图中减去运算后的图,得到的效果图突出了比原图轮廓周围的区域更明亮的区域,且这一操作和选择的核的大小相关。
顶帽运算往往用来分离比邻近点亮一些的斑块。当一幅图像具有大幅的背景的时候,而微小物品比较有规律的情况下,可以使用顶帽运算进行背景提取。
闭运算使用函数和开运算相同,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()
黑帽 = 闭运算-原始输入
黑帽运算之后的效果图突出了与原图像轮廓周围的区域更暗的区域,且这一操作和选择的核大小相关。所以黑帽运算用来分离比邻近点暗一些的斑块。
闭运算使用函数和开运算相同,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-图像处理】相关内容,如果需要,可持续关注我哦~> |
<翻译和整理不易,留个赞或评论支持一下我吧^^>
如有疑问,欢迎批评指正^^