形态学变换(Morphological Transformations)是一种 基于外形的简单变换,它的处理对象通常是二值化图像。形态学变换有两个输入,一个输出:输入为 原图像、核(结构化元素),输出为形态学**变换后的图像。**其根本操纵有腐蚀和膨胀,这两种操纵是相反的,即较亮的像素会被腐蚀和膨胀。下面我们来说一下核、腐蚀与膨胀的概念。
1. 核
其实在上一章节自顺应二值化中,我们已经接触过核了,还记得吗?就是那个在原图中不断滑动计算的3*3的小区域,那其实就是一个3*3的核。
核(kernel)其实就是一个小区域,通常为3*3、5*5、7*7巨细,有着其自己的结构,比如矩形结构、椭圆结构、十字形结构,如下图所示。通过不同的结构可以对不同特征的图像进行形态学操纵的处理。
2.腐蚀(cv2.erode)
腐蚀操纵就是使用核在原图(二值化图)上进行从左到右、从上到下的滑动(也就是从图像的左上角开始,滑动到图像的右下角)。在滑动过程中,令核值为1的区域与被核覆盖的对应区域进行相乘,得到其最小值,该最小值就是卷积核覆盖区域的中央像素点的新像素值,接着继续滑动。由于操纵图像为二值图,所以不是黑就是白,这就意味着,在被核值为1覆盖的区域内,只要有黑色(像素值为0),那么该区域的中央像素点肯定为黑色(0)。这样做的结果就是会将二值化图像中的白色部分尽大概的压缩,如下图所示,该图经过腐蚀之后,“变瘦”了。
腐蚀操纵的详细流程
腐蚀原理的代码:
- '''腐蚀操作——原理'''
- img=np.zeros((10,10),dtype=np.uint8)
- img[3:7,3:7]=255
- img[2,2]=10
- print(img)
- print("="*20)
- kernel=np.ones((3,3),dtype=np.uint8)#填充了一个全1的核
- img2=cv2.erode(img,kernel=kernel)#第一个填入一个二值图,
- print(img2)
- '''
- [ 0 0 10 0 0 0 0 0 0 0]
- [ 0 0 0 255 255 255 255 0 0 0]
- [ 0 0 0 255 255 255 255 0 0 0]
- [ 0 0 0 255 255 255 255 0 0 0]
- [ 0 0 0 255 255 255 255 0 0 0]
- [ 0 0 0 0 0 0 0 0 0 0]
- [ 0 0 0 0 0 0 0 0 0 0]
- [ 0 0 0 0 0 0 0 0 0 0]]
- ====================
- [[ 0 0 0 0 0 0 0 0 0 0]
- [ 0 0 0 0 0 0 0 0 0 0]
- [ 0 0 0 0 0 0 0 0 0 0]
- [ 0 0 0 0 0 0 0 0 0 0]
- [ 0 0 0 0 255 255 0 0 0 0]
- [ 0 0 0 0 255 255 0 0 0 0]
- [ 0 0 0 0 0 0 0 0 0 0]
- [ 0 0 0 0 0 0 0 0 0 0]
- [ 0 0 0 0 0 0 0 0 0 0]
- [ 0 0 0 0 0 0 0 0 0 0]]
- '''
复制代码 由上面代码可以知道腐蚀是以每个元素为中央做一个3*3的全1的核找到最小值添补到核的中央
腐蚀操纵代码部分:
- '''腐蚀操作'''
- img=cv2.imread(r'../15day4.10\src\long.png',cv2.IMREAD_GRAYSCALE)
- kernel=np.ones((3,3),dtype=np.uint8)#填充了一个全1的核
- img_erode=cv2.erode(img,kernel=kernel,iterations=2)#表示进行腐蚀两次
- cv2.imshow('img',img)
- cv2.imshow("img_erode",img_erode)
- cv2.waitKey(0)
复制代码
注意:
- 腐蚀的本质是输出将一个以一个像素点为中央的核的最小值,如果上图则是白色被腐蚀了(白色变少了)
- 腐蚀可以去除图像中的白色噪点
3. 膨胀(cv2.dilate)
膨胀与腐蚀刚好相反,膨胀操纵就是使用核在原图(二值化图)上进行从左到右、从上到下的滑动(也就是从图像的左上角开始,滑动到图像的右下角),在滑动过程中,令核值为1的区域与被核覆盖的对应区域进行相乘,得到其最大值,该最大值就是核覆盖区域的中央像素点的新像素值,接着继续滑动。由于操纵图像为二值图,所以不是黑就是白,这就意味着,在卷积核覆盖的区域内,只要有白色(像素值为255),那么该区域的中央像素点肯定为白色(255)。这样做的结果就是会将二值化图像中的白色部分尽大概的扩张,如下图所示,该图经过膨胀之后,“变胖”了。
膨胀的详细操纵
膨胀原理代码:
- '''膨胀操作——原理'''
- img=np.zeros((10,10),dtype=np.uint8)
- img[3:7,3:7]=255
- img[2,2]=10
- img[2,4]=100
- print(img)
- print("="*20)
- kernel=np.ones((3,3),dtype=np.uint8)#填充了一个全1的核
- img2=cv2.dilate(img,kernel=kernel)#第一个填入一个二值图,
- print(img2)
- '''
- [[ 0 0 0 0 0 0 0 0 0 0]
- [ 0 0 0 0 0 0 0 0 0 0]
- [ 0 0 10 0 100 0 0 0 0 0]
- [ 0 0 0 255 255 255 255 0 0 0]
- [ 0 0 0 255 255 255 255 0 0 0]
- [ 0 0 0 255 255 255 255 0 0 0]
- [ 0 0 0 255 255 255 255 0 0 0]
- [ 0 0 0 0 0 0 0 0 0 0]
- [ 0 0 0 0 0 0 0 0 0 0]
- [ 0 0 0 0 0 0 0 0 0 0]]
- ====================
- [[ 0 0 0 0 0 0 0 0 0 0]
- [ 0 10 10 100 100 100 0 0 0 0]
- [ 0 10 255 255 255 255 255 255 0 0]
- [ 0 10 255 255 255 255 255 255 0 0]
- [ 0 0 255 255 255 255 255 255 0 0]
- [ 0 0 255 255 255 255 255 255 0 0]
- [ 0 0 255 255 255 255 255 255 0 0]
- [ 0 0 255 255 255 255 255 255 0 0]
- [ 0 0 0 0 0 0 0 0 0 0]
- [ 0 0 0 0 0 0 0 0 0 0]]
- '''
复制代码 由上面代码可以知道腐蚀是以每个元素为中央做一个3*3的全1的核找到最大值添补到核的中央
膨胀的操纵的代码:
- '''膨胀操作'''
- img=cv2.imread(r'../15day4.10\src\long.png',cv2.IMREAD_GRAYSCALE)
- kernel=np.ones((3,3),dtype=np.uint8)
- img_dilate=cv2.dilate(img,kernel=kernel,iterations=3)
- cv2.imshow('img',img)
- cv2.imshow("img_dilate",img_dilate)
- cv2.waitKey(0)
复制代码
注意:
- 膨胀的本质是输出将一个以一个像素点为中央的核的最大值,如果上图则是白色扩大了
- 膨胀可以去除图像中的黑色噪点
4. 开运算(cv.MORPH_OPEN)
开运算是先腐蚀后膨胀,其作用是:分离物体,消除小区域。特点:消除噪点,去除小的干扰块,而不影响原来的图像
代码如下:
- '''开运算:先腐蚀后膨胀'''
- img=cv2.imread(r'../15day4.10\src\open.png',cv2.IMREAD_GRAYSCALE)
- kernel=np.ones((3,3),dtype=np.uint8)
- img_open=cv2.morphologyEx(img,cv2.MORPH_OPEN,kernel=kernel)
- cv2.imshow('img',img)
- cv2.imshow("img_open",img_open)
- cv2.waitKey(0)
复制代码
5. 闭运算(cv2.MORPH_CLOSE)
闭运算与开运算相反,是先膨胀后腐蚀,作用是消除/“闭合”物体内里的孔洞,特点:可以添补闭合区域
代码如下:
- '''闭运算:先膨胀后腐蚀'''
- img=cv2.imread(r'../15day4.10\src\car.png',cv2.IMREAD_GRAYSCALE)
- kernel=np.ones((3,3),dtype=np.uint8)
- img_close=cv2.morphologyEx(img,cv2.MORPH_CLOSE,kernel=kernel)
- cv2.imshow('img',img)
- cv2.imshow("img_close",img_close)
- cv2.waitKey(0)
复制代码 6. 礼帽运算(找出增多的白色区域)
cv2.MORPH_TOPHAT
原图像与“开运算“的结果图之差,因为开运算带来的结果是放大了裂缝或者局部低亮度的区域,因此,从原图中减去开运算后的图,得到的效果图突出了比原图轮廓四周的区域更豁亮的区域,且这一操纵和选择的核的巨细相关。
礼帽运算用来分离比相近点亮一些的斑块。当一幅图像具有大幅的背景的时候,而微小物品比较有规律的环境下,可以使用礼帽运算进行背景提取(找到原图中的白色噪点)
代码如下:
- '''礼帽运算'''
- img=cv2.imread(r'../15day4.10\src\open.png',cv2.IMREAD_GRAYSCALE)
- kernel=np.ones((5,5),np.uint8)
- img2=cv2.morphologyEx(img,cv2.MORPH_TOPHAT,kernel=kernel)
- cv2.imshow('img',img)
- cv2.imshow('img2',img2)
- cv2.waitKey(0)
复制代码 7. 黑帽运算
cv2.MORPH_BLACKHAT
黑帽运算为”闭运算“的结果图与原图像之差,
黑帽运算后的效果图突出了比原图轮廓四周的区域更暗的区域,且这一操纵和选择的核的巨细相关。
黑帽运算用来分离比相近点暗一些的斑块
代码如下:
- '''黑帽运算'''
- img=cv2.imread(r'../15day4.10\src\car.png',cv2.IMREAD_GRAYSCALE)
- kernel=np.ones((3,3),np.uint8)
- img2=cv2.morphologyEx(img,cv2.MORPH_BLACKHAT,kernel=kernel)
- cv2.imshow('img',img)
- cv2.imshow('img2',img2)
- cv2.waitKey(0)
复制代码
8. 形态学梯度
cv2.MORPH_GRADIENT
形态学梯度是一个基于结构元素的图像处理方法,它通过比较原图像与膨胀图和腐蚀图之间的差异来突出图像边缘特征。详细来说,对于图像中的每个像素点,其形态学梯度值是该像素点在膨胀后的图像值与其在腐蚀后的图像值之差。这样得到的结果通常能够强化图像的边缘信息,而且对噪声有一定的抑制作用
代码如下:
- '''形态学梯度'''
- img=cv2.imread(r'../15day4.10\src\car.png',cv2.IMREAD_GRAYSCALE)
- kernel=np.ones((3,3),np.uint8)
- img2=cv2.morphologyEx(img,cv2.MORPH_GRADIENT,kernel=kernel) #gradient
- cv2.imshow('img',img)
- cv2.imshow('img2',img2)
- cv2.waitKey(0)
复制代码
形态学梯度是图像膨胀后与腐蚀后的差值,这样可以得到原图像的轮廓
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |