原文链接: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的结构元进行腐蚀,这时腐蚀会作用到垂直方向上,水平方向几乎不会被影响到,从而将高度较小的横线腐蚀掉,但是因为腐蚀操作将需要保留的符号也腐蚀掉了一部分,所以再用同样的结构元进行一次膨胀操作,就能复原出符号的形状。

扩展阅读:

  1. OpenCV-Python教程

OpenCV-Python教程:形态学变换~腐蚀和膨胀(erode,dilate)相关推荐

  1. OpenCV Python教程(3)(4)(5): 直方图的计算与显示 形态学处理 初级滤波内

    OpenCV Python教程(3.直方图的计算与显示) 本篇文章介绍如何用OpenCV Python来计算直方图,并简略介绍用NumPy和Matplotlib计算和绘制直方图 直方图的背景知识.用途 ...

  2. 9.1 Python图像处理之图像数学形态学-二值形态学(腐蚀、膨胀、开启、闭合)

    9.1 Python图像处理之图像数学形态学-二值形态学(腐蚀.膨胀.开启.闭合) 文章目录 9.1 Python图像处理之图像数学形态学-二值形态学(腐蚀.膨胀.开启.闭合) 1 算法原理 1.1 ...

  3. 图像形态学概要-腐蚀、膨胀、开运算、闭运算、形态学梯度(形态学边缘提取)、顶帽操作、黑帽操作

    图像处理开发需求.图像处理接私活挣零花钱,请加微信/QQ 2487872782 图像处理开发资料.图像处理技术交流请加QQ群,群号 271891601 图像形态学中两种最基本的操作就是对图形的腐蚀和膨 ...

  4. OpenCV Python教程(2、图像元素的访问、通道分离与合并)

    OpenCV Python教程之图像元素的访问.通道分离与合并 转载请详细注明原作者及出处,谢谢! 访问像素 像素的访问和访问numpy中ndarray的方法完全一样,灰度图为: [python] v ...

  5. opencv python 图像形态学操作/图像腐蚀/图像膨胀/开运算/闭运算/顶帽/黑帽

    Morphological Transformations 1图像腐蚀 腐蚀的基本思想:侵蚀前景物体的边界(总是试图保持前景为白色):内核在图像中滑动(如在2D卷积中).只有当内核下的所有像素都是1时 ...

  6. 【学习笔记】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, ...

  7. (自己编写函数)Python + Opencv 图像形态学处理(腐蚀、膨胀、开运算、闭运算)

    原理: 形态学运算是结构元素与图像进行逻辑运算,产生新的图像的图像处理方法.二值图像B和结构元素S是定义在笛卡儿网格上的集合,网格中值为1的点是集合的元素. 腐蚀 定义: 算法: a) 用3x3的结构 ...

  8. 形态学操作——腐蚀与膨胀

    预备知识 结构元(SE) 1.结构元的中心一般来说是放在其重心位置处,但原则上原点的选择是依赖于你要解决的问题的. 2.对图像操作时,我们要求结构元是矩形阵列.(在结构元的基础上添加较少的背景元素实现 ...

  9. 图像形态学(腐蚀、膨胀、开运算、闭运算、梯度、顶帽、黑帽)

    一.腐蚀: 消除图像中不重要的边缘信息. 二.膨胀: 可以看作为腐蚀的逆过程. 三.开运算: 开运算(open) ,先腐蚀后膨胀的过程.开运算可以用来消除小黑点,在纤细点处分离物体.平滑较大物体的边界 ...

最新文章

  1. 《python源码剖析》,看看
  2. 用python画梵高星空-python 梵高
  3. 对于python来说、一个模块就是一个文件-PYTHON中的包和模块
  4. odoo开发笔记:前端显示强制换行
  5. java的知识点17——java.util.Arrays类、多维数组
  6. ASP站点无法访问怎么办
  7. 【CF1189D】Add on a Tree【结论】【构造】
  8. Linux CentOS7.0 (01)在Vmvare Workstation上 安装配置
  9. Win32下的录音编程
  10. Loadrunner录制+运行+结果-【飞机订票系统实战】
  11. 【网络流】 HDU 4309 Seikimatsu Occult Tonneru 状压枚举边
  12. div 夸站点加载html,使用jQuery加载html页面到指定的div实现方法
  13. hdu 4006 The kth great number 很复杂的线段树,至少对于我来说,但也学会了很多!!!!!!!!!!
  14. 查找算法——插值查找
  15. 如何使用puttygen密钥远程登录服务器
  16. 怎么将EXCEL的网格线打印出来,教程在这里,EXCEL里的网格线如何打印出来
  17. java笔记5 抽象类和接口
  18. 《星际迷航 超越星辰》
  19. Mac ubuntu安装无线驱动
  20. ios系统和android比较大小,iOS系统和安卓系统对比,有哪些优势和不足?

热门文章

  1. 文书裁判文书网_使用上下文书签在上下文菜单中访问您的书签
  2. 使用OpenFiler来模拟存储配置RAC中ASM共享盘及多路径(multipath)的测试
  3. 目前最先进的神经网络算法,神经网络算法发展
  4. MATLAB产生阶跃信号
  5. linux上的一个玩具
  6. 如何利用系统OA进行企业员工人事档案管理
  7. 陇原战“疫“2021网络安全大赛 Web eaaasyphp
  8. 中国地理位置四至点及计算方法
  9. 测试用例驱动阅读Express源码
  10. 如何让培训更加生动化