网站前台设计教程,智慧校园,注册的网站,上海影城改造升级OpenCV与图像处理学习六——图像形态学操作#xff1a;腐蚀、膨胀、开、闭运算、形态学梯度、顶帽和黑帽四、图像形态学操作4.1 腐蚀和膨胀4.1.1 图像腐蚀4.1.2 图像膨胀4.2 开运算与闭运算4.2.1 开运算4.2.2 闭运算4.3 形态学梯度#xff08;Gradient#xff09;4.4顶帽和黑…
OpenCV与图像处理学习六——图像形态学操作腐蚀、膨胀、开、闭运算、形态学梯度、顶帽和黑帽四、图像形态学操作4.1 腐蚀和膨胀4.1.1 图像腐蚀4.1.2 图像膨胀4.2 开运算与闭运算4.2.1 开运算4.2.2 闭运算4.3 形态学梯度Gradient4.4顶帽和黑帽有关图像处理前三次的笔记 OpenCV与图像处理学习三——图像基本操作1 OpenCV与图像处理学习四——图像基本操作2 OpenCV与图像处理学习五——图像基本操作3
这是有关图像基本操作的最后一次笔记有关图像形态学操作。
四、图像形态学操作
形态学是图像处理中应用最为广泛的技术之一主要用于从图像中提取对表达和描绘区域形状有意义的图像分量使后续的识别工作能够抓住目标对象最为本质的形状特征如边界和连通区域等。
下面会经常用到一个概念这里先进行说明
结构元素设有两幅图像BX若X是被处理的对象而B是用来处理X的则B称为结构元素structure element又被形象地称作刷子。结构元素通常都是一些比较小的图像。
下面将介绍形态学的几种常用操作腐蚀、膨胀、开运算和闭运算等。
4.1 腐蚀和膨胀
图像的膨胀Dilation和腐蚀Erosion是两种基本的形态学运算其中膨胀类似于“领域扩张”将图像中的白色部分进行扩张其运行结果图比原图的白色区域更大而腐蚀类似于“领域被蚕食”将图像中白色的部分进行缩减细化其运行结果图比原图的白色区域更小。
4.1.1 图像腐蚀
把结构元素B平移a后得到Ba若Ba包含于X我们记下这个a点所有满足上述条件的a点组成的集合称作X被B腐蚀Erosion的结果。如下图所示 其中X是被处理的对象B是结构元素。对于任意一个在阴影部分的点aBa包含于X所以X被B腐蚀的结果就是那个阴影部分。阴影部分在X的范围之内且比X小就像X被剥掉了一层似的。 腐蚀后的结果如下图黑色部分所示 相较于原来的灰色部分仿佛变瘦了。
OpenCV中的函数为
dst cv2.erode( src, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]] )参数为
src输入图像可以是灰度图或彩色图。kernel腐蚀操作的结构元素默认为一个3×3的简单矩阵。anchor锚点默认为结构元素的中心。iterations腐蚀次数默认为1。
下面看个例子
import cv2
import numpy as np
import matplotlib.pyplot as plt
img cv2.imread(./image/morphology.png)
img cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
kernel np.ones((3, 3), np.uint8)
erosion cv2.erode(img, kernel, iterations 1)
plt.subplot(121), plt.imshow(img), plt.title(Original)
plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(erosion), plt.title(erosion)
plt.xticks([]), plt.yticks([])
plt.show()结果如下所示 若将结构元素的尺寸扩大到7结果为 ps在构造结构元素的时候可以使用numpy也可以使用OpenCV提供的函数cv2.getStructuringElement()
函数
retval cv2.getStructuringElement( shape, ksize[, anchor] )参数
shape结构元素内部的结构有三种分别是矩形、十字形和椭圆形ksize结构元素的尺寸。anchor锚点位置默认为中心位置。
看一下例子
import numpy as np
import cv2kernel np.ones((5, 5), np.uint8)
print(kernel)[[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]]kernel cv2.getStructuringElement(cv2.MORPH_CROSS, (7,7))
print(kernel)[[0 0 0 1 0 0 0][0 0 0 1 0 0 0][0 0 0 1 0 0 0][1 1 1 1 1 1 1][0 0 0 1 0 0 0][0 0 0 1 0 0 0][0 0 0 1 0 0 0]]kernel cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (7,7))
print(kernel)[[0 0 0 1 0 0 0][0 1 1 1 1 1 0][1 1 1 1 1 1 1][1 1 1 1 1 1 1][1 1 1 1 1 1 1][0 1 1 1 1 1 0][0 0 0 1 0 0 0]]kernel cv2.getStructuringElement(cv2.MORPH_RECT, (7,7))
print(kernel)[[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 1 1 1][1 1 1 1 1 1 1][1 1 1 1 1 1 1][1 1 1 1 1 1 1]]我们可以用非矩形的结构元素来进行腐蚀操作
#!/usr/bin/env python3
import cv2image cv2.imread(./image/morphology.png)
gray cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
cv2.imshow(Gray Image, gray)kernel cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (7, 7))
eroded cv2.erode(gray.copy(), kernel, 10)
# eroded cv2.erode(gray.copy(), None, 10)cv2.imshow(Eroded Image, eroded)
cv2.waitKey(0)
cv2.destroyAllWindows()也是可以达到一定效果的但是比矩形的那种腐蚀程度低一些些因为毕竟结构元素里多了一些0。
4.1.2 图像膨胀
膨胀dilation可以看做是腐蚀的对偶运算其定义是把结构元素B平移后得到Ba若Ba与X有交集我们记下这个a点。所有满足上述条件的a点组成的集合称作X被B膨胀后的结果如下图所示 其中X是被处理的对象B是结构元素对于任意一个在阴影部分的点aBa与X有交集所以X被B膨胀后的结果就是那个阴影部分阴影部分包括X所有范围就像是X膨胀了一圈似的。 膨胀后的图像其中绿色是膨胀多出来的部分 在OpenCV中的函数为
dst cv2.dilate( src, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]] )参数
src输入图像可以是灰度图也可以是彩色图。kernel膨胀运算的结构元素默认为一个3×3的简单矩阵。anchor同上。iterations同上。
看个例子
import cv2
import numpy as np
import matplotlib.pyplot as plt
img cv2.imread(./image/morphology.png)
img cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
#kernel np.ones((3,),np.uint8)
kernel cv2.getStructuringElement(cv2.MORPH_RECT, (7,7))dilation cv2.dilate(img,kernel,iterations 1)
plt.subplot(121),plt.imshow(img),plt.title(origin)
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(dilation),plt.title(dilation)
plt.xticks([]), plt.yticks([])
plt.show()结果为 若将运算元素尺寸扩大一点扩大为11 原本断开的地方或小孔都被填上了。
4.2 开运算与闭运算
4.2.1 开运算
开运算 先腐蚀运算再膨胀运算看上去把细微连在一起的两块目标分开了开运算的效果图如下所示 开运算对一些细微的小点小块细条等部分是可以消去的因为先腐蚀消去它们导致它们消失了无法再通过膨胀变回来而一些比较大的块通过腐蚀操作只是会变瘦一点不会被完全抹去所以可以通过膨胀运算变回来那么总的效果就是开运算去除了这些孤立的小点细长的小条。
开运算总结
开运算能够去除孤立的小点毛刺和小条而总的位置和形状不变。开运算是一个基于几何运算的滤波器。结构元素大小的不同将导致滤波效果的不同。不同的结构元素的选择导致了不同的分割即提取出不同的特征。
开运算和闭运算都用如下函数来表示这个函数是OpenCV中图像形态学变化的通用函数
dst cv2.morphologyEx( src, op, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]] )参数如下所示
src输入图像灰度图或彩色图均可。op形态学操作的类型包括腐蚀、运算、开运算以及后面要提及的闭运算、形态学梯度、顶帽、黑帽等类型。kernel结构元素可以使用cv2.getStructuringElement函数来定义。anchor锚点位置一般都用中心位置。iterations腐蚀或膨胀的次数。
下面看个例子
import cv2
import numpy as np
import matplotlib.pyplot as plt
img cv2.imread(./image/open.png)
img cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
#kernel np.ones((5,5),np.uint8)
kernel cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
opening cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
plt.subplot(121), plt.imshow(img), plt.title(Original)
plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(opening), plt.title(opening)
plt.xticks([]), plt.yticks([])
plt.show()结果如下所示 一些细小的点被去除了很多但是开运算的结构元素的尺寸很重要太小可能去除效果不好太大可能会得到不想要的结果如将3改为9结果将变为 所以调节这个参数还是很关键的。
4.2.2 闭运算
闭运算 先膨胀运算再腐蚀运算看上去将两个细微连接的图块封闭在一起闭运算的效果图如下图所示 闭运算总结
闭运算能够填平小孔弥合小缝隙而总的位置和形状不变。闭运算是通过填充图像的凹角来滤波图像的。结构元素大小的不同将导致滤波效果的不同。不同结构元素的选择导致了不同的分割。
看个例子
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
img cv.imread(./image/close.png)
img cv.cvtColor(img,cv.COLOR_BGR2RGB)
# kernel np.ones((5,5),np.uint8)
kernel np.ones((7, 7), np.uint8)
closing cv.morphologyEx(img, cv.MORPH_CLOSE, kernel)
plt.subplot(121), plt.imshow(img), plt.title(Original)
plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(closing), plt.title(closing)
plt.xticks([]), plt.yticks([])
plt.show()结果如下所示 一些小孔被填满了。若把尺寸从7改为21结果为 就有点过了把不需要连接和填补的地方也给连接、填补了所以要合理选择参数。
4.3 形态学梯度Gradient
基础梯度基础梯度是用膨胀后的图像减去腐蚀后的图像得到的差值图像也是OpenCV中支持的计算形态学梯度的方法而此方法得到梯度又称为基本梯度。内部梯度是用原图减去腐蚀之后的图像得到的差值图像。外部梯度图形膨胀后再减去原来图像得到的差值图像。
用cv2.morphologyEx函数可以实现基础梯度操作看下面这个例子
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
img cv.imread(./image/morphology.png)
img cv.cvtColor(img, cv.COLOR_BGR2RGB)
kernel np.ones((3, 3), np.uint8)
gradient cv.morphologyEx(img, cv.MORPH_GRADIENT, kernel)
plt.subplot(121), plt.imshow(img), plt.title(Original)
plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(gradient), plt.title(gradient)
plt.xticks([]), plt.yticks([])
plt.show()结果如下所示
4.4顶帽和黑帽
顶帽Top Hat原图像与开运算图的差值突出原图像中比周围亮的区域。黑帽Black Hat闭运算图与原图的差值突出原图中比周围暗的区域。
看两个例子
顶帽
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
img cv.imread(./image/morphology.png)
img cv.cvtColor(img, cv.COLOR_BGR2RGB)
kernel np.ones((9, 9), np.uint8)
tophat cv.morphologyEx(img, cv.MORPH_TOPHAT, kernel)
plt.subplot(121), plt.imshow(img), plt.title(Original)
plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(tophat), plt.title(tophat)
plt.xticks([]), plt.yticks([])
plt.show()结果为 黑帽
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
img cv.imread(./image/morphology.png)
img cv.cvtColor(img, cv.COLOR_BGR2RGB)
kernel np.ones((9, 9), np.uint8)
tophat cv.morphologyEx(img, cv.MORPH_BLACKHAT, kernel)
plt.subplot(121), plt.imshow(img), plt.title(Original)
plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(tophat), plt.title(blackhat)
plt.xticks([]), plt.yticks([])
plt.show()图像处理之图像基本操作的笔记就暂时到这里后面将学习传统方法进行图像分割包括阈值分割、边缘检测算法、连通域分析以及一些其他区域生长算法。