OpenCV-Python教程:形态学变换~腐蚀和膨胀(erode,dilate)
原文链接:http://www.juzicode.com/opencv-python-erode-dilate
返回Opencv-Python教程
形态学变换是基于图像形状的变换过程,通常用来处理二值图像,当然也可以用在灰度图上。OpenCV中的形态学变换同平滑处理一样也是基于一种“滑动窗口”的操作,不过在形态学变换中“滑动窗口”有一个更专业的名词:“结构元”,也可以像平滑处理那样称呼为kernel,结构元的形状有方形、十字形、椭圆形等,其形状决定了形态学变换的特点。形态学变换主要有腐蚀、膨胀、开操作、闭操作等等。
1、腐蚀erode()
腐蚀操作可以将边界的白色(前景)像素“腐蚀”掉,但仍能保持大部分白色。类似平滑处理的滑动窗口,用某种结构元在图像上滑动,当结构元覆盖原始图像中的所有像素都为“1”时,新图像中该像素点的值才为“1”(CV8U为255)。腐蚀可以用来去除噪声、去掉“粘连”。
接口形式:
cv2.erode(src, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]]) ->dst
- 参数含义:
- src:通道数任意;图像深度只能是CV_8U, CV_16U, CV_16S, CV_32F or CV_64F;
- kernel:可以由getStructuringElement()构建;
- dst:输出图像,通道数和数据类型同src;
- anchor:锚点,默认使用(-1,-1)表示中心点;
- iterations:腐蚀次数;
- borderType:边界类型;
- borderValue:边界值;
下面是一个kernel大小为5和7的腐蚀例子:
import matplotlib.pyplot as plt
import cv2
print('VX公众号: 桔子code / juzicode.com')
print('cv2.__version__:',cv2.__version__)
plt.rc('font',family='Youyuan',size='9')img = cv2.imread('..\\samples\\picture\\mnist-7.jpg',cv2.IMREAD_GRAYSCALE)
_,img = cv2.threshold(img,127,255,0)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(5,5)) #ksize=5,5
img_ret1 = cv2.erode(img,kernel,iterations=1)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(7,7)) #ksize=7x7,
img_ret2 = cv2.erode(img,kernel,iterations=1)
img_ret3 = cv2.erode(img,kernel,iterations=2) #ksize=7x7,腐蚀2次#显示图像
fig,ax = plt.subplots(2,2)
ax[0,0].set_title('原图-mnist(juzicode.com)')
ax[0,0].imshow(cv2.cvtColor(img,cv2.COLOR_BGR2RGB)) #matplotlib显示图像为rgb格式
ax[0,1].set_title('erode ksize=5')
ax[0,1].imshow(cv2.cvtColor(img_ret1,cv2.COLOR_BGR2RGB))
ax[1,0].set_title('erode ksize=7')
ax[1,0].imshow(cv2.cvtColor(img_ret2,cv2.COLOR_BGR2RGB))
ax[1,1].set_title('erode ksize=7 iter=2')
ax[1,1].imshow(cv2.cvtColor(img_ret3,cv2.COLOR_BGR2RGB))
ax[0,0].axis('off');ax[0,1].axis('off');ax[1,0].axis('off');ax[1,1].axis('off')#关闭坐标轴显示
plt.show()
运行结果:
原图图源:mnist
从运行结果可以看到kernel的ksize越大,iterations次数越多,图像看起来越“廋”。
2、膨胀dilate()
膨胀是腐蚀的逆操作,可以将边界的白色(前景)像素“生长”扩大。滑动窗口经过白色像素时,只要结构元中有1个像素为“1”时,新图像中该像素点的值就为“1”(CV8U为255)。膨胀可以用来增强连接、填充凹痕。
接口形式:
cv2.dilate(src, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]]) ->dst
- 参数含义:
- src:通道数任意;图像深度只能是CV_8U, CV_16U, CV_16S, CV_32F or CV_64F;
- kernel:可以由getStructuringElement()构建;
- dst:输出图像,通道数和数据类型同src;
- anchor:锚点,默认使用(-1,-1)表示中心点;
- iterations:腐蚀次数;
- borderType:边界类型;
- borderValue:边界值;
下面是一个kernel大小为5和7的膨胀例子:
import matplotlib.pyplot as plt
import cv2
print('VX公众号: 桔子code / juzicode.com')
print('cv2.__version__:',cv2.__version__)
plt.rc('font',family='Youyuan',size='9')img = cv2.imread('..\\samples\\picture\\mnist-7-b.jpg',cv2.IMREAD_GRAYSCALE)
_,img = cv2.threshold(img,127,255,0)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))
img_ret1 = cv2.dilate(img,kernel,iterations=1)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(7,7))
img_ret2 = cv2.dilate(img,kernel,iterations=1)
img_ret3 = cv2.dilate(img,kernel,iterations=2) #显示图像
fig,ax = plt.subplots(2,2)
ax[0,0].set_title('原图-mnist(juzicode.com)')
ax[0,0].imshow(cv2.cvtColor(img,cv2.COLOR_BGR2RGB)) #matplotlib显示图像为rgb格式
ax[0,1].set_title('dilate ksize=5')
ax[0,1].imshow(cv2.cvtColor(img_ret1,cv2.COLOR_BGR2RGB))
ax[1,0].set_title('dilate ksize=7')
ax[1,0].imshow(cv2.cvtColor(img_ret2,cv2.COLOR_BGR2RGB))
ax[1,1].set_title('dilate ksize=7 iter=2')
ax[1,1].imshow(cv2.cvtColor(img_ret3,cv2.COLOR_BGR2RGB))
ax[0,0].axis('off');ax[0,1].axis('off');ax[1,0].axis('off');ax[1,1].axis('off')#关闭坐标轴显示
plt.show()
运行结果:
原图图源:mnist
从运行结果可以看到kernel的ksize越大,iterations次数越多,图像看起来越“胖”。
3、结构元生成getStructuringElement()
结构元生成函数用来生成形态学变换的kernel参数。
接口形式:
cv2.getStructuringElement(shape, ksize[, anchor]) ->retval
- 参数含义:
- shape:结构元(kernel)的形状;
- ksize:结构元(kernel)的大小;
- anchor:锚点,默认使用(-1,-1)表示中心点;
其中shape属性有可选的3种形状:
cv2.MORPH_RECT | 方形,所有的数值均为1 |
cv2.MORPH_CROSS | 十字交叉形,在锚点坐标的水平和竖直方向的元素为1,其他为0 |
cv2.MORPH_ELLIPSE | 椭圆形 |
下面是一个kernel大小为7,形状不同的膨胀例子:
import matplotlib.pyplot as plt
import cv2
print('VX公众号: 桔子code / juzicode.com')
print('cv2.__version__:',cv2.__version__)
plt.rc('font',family='Youyuan',size='9')img = cv2.imread('..\\samples\\picture\\mnist-7-b.jpg',cv2.IMREAD_GRAYSCALE)
_,img = cv2.threshold(img,127,255,0)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(7,7))
print('MORPH_RECT kernel:\n',kernel)
img_ret1 = cv2.dilate(img,kernel,iterations=1)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(7,7))
print('MORPH_ELLIPSE kernel:\n',kernel)
img_ret2 = cv2.dilate(img,kernel,iterations=1)
kernel = cv2.getStructuringElement(cv2.MORPH_CROSS,(7,7))
print('MORPH_CROSS kernel:\n',kernel)
img_ret3 = cv2.dilate(img,kernel,iterations=1) #显示图像
fig,ax = plt.subplots(2,2)
ax[0,0].set_title('原图-mnist(juzicode.com)')
ax[0,0].imshow(cv2.cvtColor(img,cv2.COLOR_BGR2RGB)) #matplotlib显示图像为rgb格式
ax[0,1].set_title('MORPH_RECT kernel')
ax[0,1].imshow(cv2.cvtColor(img_ret1,cv2.COLOR_BGR2RGB))
ax[1,0].set_title('MORPH_ELLIPSE kernel')
ax[1,0].imshow(cv2.cvtColor(img_ret2,cv2.COLOR_BGR2RGB))
ax[1,1].set_title('MORPH_CROSS kernel')
ax[1,1].imshow(cv2.cvtColor(img_ret3,cv2.COLOR_BGR2RGB))
ax[0,0].axis('off');ax[0,1].axis('off');ax[1,0].axis('off');ax[1,1].axis('off')#关闭坐标轴显示
plt.show()
运行结果:
VX公众号: 桔子code / juzicode.com
cv2.__version__: 4.5.3
MORPH_RECT 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]]
MORPH_ELLIPSE 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]]
MORPH_CROSS 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]]
原图图源:mnist
从运行结果可以看到当使用方形MORPH_RECT的结构元时,新图像的边界看起来仍然是方方正正的,但是使用十字形MORPH_CROSS和椭圆形MORPH_ELLIPSE的结构元时,边界要显得“圆滑”的多。
4、实际应用的例子
下面是一个用腐蚀去除噪声的例子:
import matplotlib.pyplot as plt
import cv2
print('VX公众号: 桔子code / juzicode.com')
print('cv2.__version__:',cv2.__version__)
plt.rc('font',family='Youyuan',size='9')img = cv2.imread('..\\samples\\picture\\mnist-7-noise.jpg',cv2.IMREAD_GRAYSCALE)
_,img = cv2.threshold(img,127,255,0)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(7,7))
img_ret1 = cv2.erode(img,kernel,iterations=2) #显示图像
fig,ax = plt.subplots(1,2)
ax[0].set_title('原图 (juzicode.com)')
ax[0].imshow(cv2.cvtColor(img,cv2.COLOR_BGR2RGB)) #matplotlib显示图像为rgb格式
ax[1].set_title('erode ksize=7 iter=2')
ax[1].imshow(cv2.cvtColor(img_ret1,cv2.COLOR_BGR2RGB))
ax[0].axis('off');ax[1].axis('off')
plt.show()
原图图源:mnist
在原图中白色小点表示的噪声通过腐蚀操作被去除掉了。
下面是一个在五线谱中去除横线的例子:
import matplotlib.pyplot as plt
import cv2
print('VX公众号: 桔子code / juzicode.com')
print('cv2.__version__:',cv2.__version__)
plt.rc('font',family='Youyuan',size='9')img = cv2.imread('..\\samples\\data\\notes.png',cv2.IMREAD_GRAYSCALE)
_,img_bin = cv2.threshold(img,127,255,1)#二值反色
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(1,7))
img_erode = cv2.erode(img_bin,kernel,iterations=1)
img_dilate = cv2.dilate(img_erode,kernel,iterations=1) #显示图像
fig,ax = plt.subplots(3,1)
ax[0].set_title('原图 (juzicode.com)')
ax[0].imshow(cv2.cvtColor(img,cv2.COLOR_BGR2RGB)) #matplotlib显示图像为rgb格式
ax[1].set_title('img_erode')
ax[1].imshow(cv2.cvtColor(img_erode,cv2.COLOR_BGR2RGB))
ax[2].set_title('img_dilate')
ax[2].imshow(cv2.cvtColor(img_dilate,cv2.COLOR_BGR2RGB))
ax[0].axis('off');ax[1].axis('off');ax[2].axis('off')
plt.show()
因为横线是水平方向的,高度小长度大,先用一个1×7的结构元进行腐蚀,这时腐蚀会作用到垂直方向上,水平方向几乎不会被影响到,从而将高度较小的横线腐蚀掉,但是因为腐蚀操作将需要保留的符号也腐蚀掉了一部分,所以再用同样的结构元进行一次膨胀操作,就能复原出符号的形状。
扩展阅读:
- OpenCV-Python教程
OpenCV-Python教程:形态学变换~腐蚀和膨胀(erode,dilate)相关推荐
- OpenCV Python教程(3)(4)(5): 直方图的计算与显示 形态学处理 初级滤波内
OpenCV Python教程(3.直方图的计算与显示) 本篇文章介绍如何用OpenCV Python来计算直方图,并简略介绍用NumPy和Matplotlib计算和绘制直方图 直方图的背景知识.用途 ...
- 9.1 Python图像处理之图像数学形态学-二值形态学(腐蚀、膨胀、开启、闭合)
9.1 Python图像处理之图像数学形态学-二值形态学(腐蚀.膨胀.开启.闭合) 文章目录 9.1 Python图像处理之图像数学形态学-二值形态学(腐蚀.膨胀.开启.闭合) 1 算法原理 1.1 ...
- 图像形态学概要-腐蚀、膨胀、开运算、闭运算、形态学梯度(形态学边缘提取)、顶帽操作、黑帽操作
图像处理开发需求.图像处理接私活挣零花钱,请加微信/QQ 2487872782 图像处理开发资料.图像处理技术交流请加QQ群,群号 271891601 图像形态学中两种最基本的操作就是对图形的腐蚀和膨 ...
- OpenCV Python教程(2、图像元素的访问、通道分离与合并)
OpenCV Python教程之图像元素的访问.通道分离与合并 转载请详细注明原作者及出处,谢谢! 访问像素 像素的访问和访问numpy中ndarray的方法完全一样,灰度图为: [python] v ...
- opencv python 图像形态学操作/图像腐蚀/图像膨胀/开运算/闭运算/顶帽/黑帽
Morphological Transformations 1图像腐蚀 腐蚀的基本思想:侵蚀前景物体的边界(总是试图保持前景为白色):内核在图像中滑动(如在2D卷积中).只有当内核下的所有像素都是1时 ...
- 【学习笔记】opencv的python接口 形态学操作 腐蚀 膨胀 通用形态学函数
腐蚀 img=np.zeros((5,5),np.uint8) img[1:4,1:4]=1 kernel=np.ones((3,1),np.uint8) erosion=cv2.erode(img, ...
- (自己编写函数)Python + Opencv 图像形态学处理(腐蚀、膨胀、开运算、闭运算)
原理: 形态学运算是结构元素与图像进行逻辑运算,产生新的图像的图像处理方法.二值图像B和结构元素S是定义在笛卡儿网格上的集合,网格中值为1的点是集合的元素. 腐蚀 定义: 算法: a) 用3x3的结构 ...
- 形态学操作——腐蚀与膨胀
预备知识 结构元(SE) 1.结构元的中心一般来说是放在其重心位置处,但原则上原点的选择是依赖于你要解决的问题的. 2.对图像操作时,我们要求结构元是矩形阵列.(在结构元的基础上添加较少的背景元素实现 ...
- 图像形态学(腐蚀、膨胀、开运算、闭运算、梯度、顶帽、黑帽)
一.腐蚀: 消除图像中不重要的边缘信息. 二.膨胀: 可以看作为腐蚀的逆过程. 三.开运算: 开运算(open) ,先腐蚀后膨胀的过程.开运算可以用来消除小黑点,在纤细点处分离物体.平滑较大物体的边界 ...
最新文章
- 《python源码剖析》,看看
- 用python画梵高星空-python 梵高
- 对于python来说、一个模块就是一个文件-PYTHON中的包和模块
- odoo开发笔记:前端显示强制换行
- java的知识点17——java.util.Arrays类、多维数组
- ASP站点无法访问怎么办
- 【CF1189D】Add on a Tree【结论】【构造】
- Linux CentOS7.0 (01)在Vmvare Workstation上 安装配置
- Win32下的录音编程
- Loadrunner录制+运行+结果-【飞机订票系统实战】
- 【网络流】 HDU 4309 Seikimatsu Occult Tonneru 状压枚举边
- div 夸站点加载html,使用jQuery加载html页面到指定的div实现方法
- hdu 4006 The kth great number 很复杂的线段树,至少对于我来说,但也学会了很多!!!!!!!!!!
- 查找算法——插值查找
- 如何使用puttygen密钥远程登录服务器
- 怎么将EXCEL的网格线打印出来,教程在这里,EXCEL里的网格线如何打印出来
- java笔记5 抽象类和接口
- 《星际迷航 超越星辰》
- Mac ubuntu安装无线驱动
- ios系统和android比较大小,iOS系统和安卓系统对比,有哪些优势和不足?