【图像处理】OpenCV+Python图像处理入门教程(七)图像形态学操作
图像形态学主要从图像内提取分量信息,该分量信息通常对表达图像的特征具有重要意义。例如,在车牌号码识别中,能够使用形态学计算其重要特征信息,在进行识别时,只需对这些特征信息运算即可。图像形态学在目标视觉检测、医学图像处理、信息压缩提取等领域都有重要的应用。接下来,这篇随笔介绍使用OpenCV进行图像处理的第七章 图像形态学操作。
7 图像形态学操作
形态学操作主要包括:腐蚀、膨胀、开运算、闭运算、形态学梯度运算、顶帽运算(礼帽运算)、黑帽运算等操作。其中,腐蚀和膨胀是形态学中最基本的运算,其他方法都是基于这两种运算组合而成的。
7.1 腐蚀
腐蚀是最基本的形态学操作之一,能够消除图像中的边界,使图像沿边界向内收缩。
腐蚀时,有一个结构元逐个像素扫描原图像,根据结构元中心与原图像的关系来进行腐蚀。该结构元也被成为核。
核能够自定义生成,也可以使用函数cv2.getStructuringElement()构造不同结构的核,该核函数的shape参数有多种,能够生成不同的核,但相比于自定义核就稍有局限,所以本章内容全部默认基于自定义核,当然朋友们也可以尝试使用cv2.getStructuringElement()核函数来构造特定结构的核。
在OpenCV中,使用cv2.erode()函数进行腐蚀操作,举例程序如下:
1 #使用函数cv.erode()完成图像腐蚀
2 import cv2
3 import numpy as np
4 o=cv2.imread('E:\python_opencv/fushi.jpg',cv2.IMREAD_UNCHANGED)
5 kernel=np.ones((5,5),np.uint8) #核大小为5×5
6 erosion=cv2.erode(o,kernel) #使用kernel对原图像腐蚀
7 cv2.imshow('orriginal',o)
8 cv2.imshow('erosion',erosion)
9 cv2.waitKey()
10 cv2.destroyAllWindows()
在上面程序中,读取图片后先生成kernel结构元,是一个5×5大小且元素均为1的矩阵,再使用cv2.erode()函数进行腐蚀操作,运行结果如图所示:


左图是原始图像,右图是腐蚀图像。可以看到,腐蚀操作能将图片中的毛刺等腐蚀消掉。下面我们调节cv2.erode()函数的迭代次数,观察不同kernel核对图像的腐蚀效果。程序如下所示:
1 #调节函数cv2.erode()的参数,观察不同参数控制下的图像腐蚀效果
2 import cv2
3 import numpy as np
4 o=cv2.imread('E:\python_opencv/fushi.jpg',cv2.IMREAD_UNCHANGED)
5 kernel=np.ones((9,9),np.uint8) #核大小为9×9
6 #参数iteration等于5,是对cv2.erode()的迭代次数进行控制,让其迭代5次
7 erosion=cv2.erode(o,kernel,iterations=5)
8 cv2.imshow('orriginal',o)
9 cv2.imshow('erosion',erosion)
10 cv2.waitKey()
11 cv2.destroyAllWindows()
运行结果如下图,左为原图像,右为迭代5次后的腐蚀处理结果,图像已明显向内收缩。


在这段代码中,使用了更大的核、更多的迭代次数,所以图像被腐蚀的更严重了。
7.2 膨胀
膨胀操作是腐蚀的逆运算,能对图像从边界处向外扩张。如果图片中的两个目标相距较近,膨胀后两个目标可能会连通。膨胀操作经常应用在图像分割后的填充任务中。
图像膨胀也是使用一个kernel核,逐一对原图像素进行扫描,判断它们的位置关系来实现的。
在OpenCV中,使用cv2.dilate()函数进行膨胀操作,举例程序如下:
1 #使用函数cv2.dilate()完成图像膨胀操作
2 import cv2
3 import numpy as np
4 o=cv2.imread('E:\python_opencv/pengzhang.jpg',cv2.IMREAD_UNCHANGED)
5 kernel=np.ones((9,9),np.uint8) #核大小为9×9
6 dilation=cv2.dilate(o,kernel) #使用kernel对原图像膨胀
7 cv2.imshow('orriginal',o)
8 cv2.imshow('dilation',dilation)
9 cv2.waitKey()
10 cv2.destroyAllWindows()
运行结果如下图,左为原图像,右为图像膨胀处理结果,图像已由边界处向外扩张。


下面我们调节cv2.dilate()函数的迭代次数,观察不同kernel核对图像的腐蚀效果。代码如下:
1 #调节函数cv2.dilate()的参数,观察不同参数控制下的图像膨胀效果
2 import cv2
3 import numpy as np
4 o=cv2.imread('E:\python_opencv/pengzhang.jpg',cv2.IMREAD_UNCHANGED)
5 kernel=np.ones((5,5),np.uint8) #核大小为5×5
6 #参数iteration等于9,是对cv2.dilate()的迭代次数进行控制,迭代9次
7 dilation=cv2.dilate(o,kernel,iterations=9)
8 cv2.imshow('orriginal',o)
9 cv2.imshow('dilation',dilation)
10 cv2.waitKey()
11 cv2.destroyAllWindows()
运行结果如下图,左为原图像,右为迭代9次后的膨胀处理结果,图像已明显由边界处向外扩张。


7.3 开运算
开运算是先将图像腐蚀,再对腐蚀后的结果进行膨胀。开运算常应用于图像去噪等。
OpenCV提供了形态学函数cv2.morphologyEx()来实现各种形态学运算,内部op参数如下:

所以,使用函数cv2.morphologyEx()实现开运算举例代码如下:
1 #使用函数cv2.morphologyEx()实现开运算
2 import cv2
3 import numpy as np
4 img=cv2.imread('E:\python_opencv/kaiyunsuan.jpg')
5 kernel=np.ones((20,20),np.uint8)
6 #cv2.morphologyEx()函数的op参数设置为cv2.MORPH_OPEN
7 rst=cv2.morphologyEx(img,cv2.MORPH_OPEN,kernel)
8 cv2.imshow('img',img)
9 cv2.imshow('rst',rst)
10 cv2.waitKey()
11 cv2.destroyAllWindows()
运行结果如下图,左为原图像,右为开运算处理结果,图像两个目标已断开连接。

7.4 闭运算
闭运算是先将图像膨胀,再对膨胀后的结果进行腐蚀。闭运算常应用于去除图像上的小黑点、或者连接图中多个相距较近的目标等。
使用函数cv2.morphologyEx()实现闭运算,举例代码如下:
1 #使用函数cv2.morphologyEx()实现闭运算
2 import cv2
3 import numpy as np
4 img=cv2.imread('E:\python_opencv/biyunsuan.jpg')
5 kernel=np.ones((10,10),np.uint8)
6 #cv2.morphologyEx()函数的op参数设置为cv2.MORPH_CLOSE
7 rst=cv2.morphologyEx(img,cv2.MORPH_CLOSE,kernel,iterations=3)
8 cv2.imshow('img',img)
9 cv2.imshow('rst',rst)
10 cv2.waitKey()
11 cv2.destroyAllWindows()
运行结果如下图,左为原图像,右为闭运算处理结果,图像两个目标经过运算后连接在一起。


7.5 形态学梯度运算
形态学梯度运算是用图像的膨胀图像减去腐蚀图像的操作。形态学梯度运算经常用于获取前景图像的边缘信息。
使用函数cv2.morphologyEx()实现形态学梯度运算,举例代码如下:
1 #使用函数cv2.morphologyEx()实现形态学梯度运算
2 import cv2
3 import numpy as np
4 img=cv2.imread('E:\python_opencv/biyunsuan.jpg',cv2.IMREAD_UNCHANGED)
5 kernel=np.ones((5,5),np.uint8)
6 #cv2.morphologyEx()函数的op参数设置为cv2.MORPH_GRADIENT
7 rst=cv2.morphologyEx(img,cv2.MORPH_GRADIENT,kernel)
8 cv2.imshow('img',img)
9 cv2.imshow('rst',rst)
10 cv2.waitKey()
11 cv2.destroyAllWindows()
运行结果如下图,左为原图像,右为形态学梯度运算处理结果,获得了前景图像的边缘轮廓。


7.6 礼帽运算
礼帽运算是用原始图像减去其开运算图像的操作。礼帽运算经常用于获取图像的噪声信息和比原图像更亮的局部边缘信息。
使用函数cv2.morphologyEx()实现礼帽运算,举例代码如下:
1 #使用函数cv2.morphologyEx()实现礼帽运算
2 import cv2
3 import numpy as np
4 img=cv2.imread('E:\python_opencv/lena.jpg',cv2.IMREAD_UNCHANGED)
5 kernel=np.ones((5,5),np.uint8)
6 #cv2.morphologyEx()函数的op参数设置为cv2.MORPH_TOPHAT
7 rst=cv2.morphologyEx(img,cv2.MORPH_TOPHAT,kernel)
8 cv2.imshow('img',img)
9 cv2.imshow('rst',rst)
10 cv2.waitKey()
11 cv2.destroyAllWindows()
运行结果如下图,左为原图像,右为礼帽运算处理结果。


7.7 黑帽运算
黑帽运算是用闭运算图像减去原始图像的操作。黑帽运算能够获取图像内部的小黑点或小孔,得到比原图像更暗的边缘信息。
使用函数cv2.morphologyEx()实现黑帽运算,举例代码如下:
1 #使用函数cv2.morphologyEx()实现黑帽运算
2 import cv2
3 import numpy as np
4 img=cv2.imread('E:\python_opencv/lena.jpg',cv2.IMREAD_UNCHANGED)
5 kernel=np.ones((5,5),np.uint8)
6 #cv2.morphologyEx()函数的op参数设置为cv2.MORPH_BLACKHAT
7 rst=cv2.morphologyEx(img,cv2.MORPH_BLACKHAT,kernel)
8 cv2.imshow('img',img)
9 cv2.imshow('rst',rst)
10 cv2.waitKey()
11 cv2.destroyAllWindows()
运行结果如下图,左为原图像,右为黑帽运算处理结果。


可以看到,黑帽运算得到了比礼帽运算更暗的边缘信息。
这次内容就分享到这里了,下次继续更新第8章 图像梯度与Canny边缘检测,希望与各位老师和小伙伴们交流学习~
【图像处理】OpenCV+Python图像处理入门教程(七)图像形态学操作的更多相关文章
- Python爬虫入门教程 49-100 Appium安装+操作51JOB_APP(模拟手机操作之一)手机APP爬虫
爬前准备工作 在开始安装Appium之前,你要先知道Appium是做什么的?Appium 是一个自动化测试开源工具,看到没,做测试用的,它有点类似Selenium,可以自动操作APP实现一系列的操作. ...
- 【图像处理】OpenCV+Python图像处理入门教程(六)图像平滑处理
相信很多小伙伴都听过"滤波器"这个词,在通信领域,滤波器能够去除噪声信号等频率成分,然而在我们OpenCV中,"滤波"并不是对频率进行筛选去除,而是实现了图像的 ...
- 无废话ExtJs 入门教程七[登陆窗体Demo:Login]
无废话ExtJs 入门教程七[登陆窗体Demo:Login] extjs技术交流,欢迎加群(201926085) 在这节我们通过前几节讲的内容做一个登陆页面,把前几节讲的内容贯穿一下. 1.代码如下: ...
- Python基础入门教程
Python基础入门教程 Python基础教程 Python 简介 Python环境搭建 Python 基础语法 Python 变量类型 Python 运算符 Python 条件语句 Python 循 ...
- Python爬虫入门教程 48-100 使用mitmdump抓取手机惠农APP-手机APP爬虫部分
1. 爬取前的分析 mitmdump是mitmproxy的命令行接口,比Fiddler.Charles等工具方便的地方是它可以对接Python脚本. 有了它我们可以不用手动截获和分析HTTP请求和响应 ...
- Python爬虫入门教程 43-100 百思不得姐APP数据-手机APP爬虫部分
1. Python爬虫入门教程 爬取背景 2019年1月10日深夜,打开了百思不得姐APP,想了一下是否可以爬呢?不自觉的安装到了夜神模拟器里面.这个APP还是比较有名和有意思的. 下面是百思不得姐的 ...
- 2019-03-22 Python Scrapy 入门教程 笔记
Python Scrapy 入门教程 入门教程笔记: # 创建mySpider scrapy startproject mySpider # 创建itcast.py cd C:\Users\theDa ...
- RabbitMQ入门教程(七):主题交换机Topics
原文:RabbitMQ入门教程(七):主题交换机Topics 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog. ...
- 【图像处理】OpenCV+Python图像处理入门教程(四)几何变换
这篇随笔介绍使用OpenCV进行图像处理的第四章 几何变换. 4 几何变换 图像的几何变换是指将一幅图像映射到另一幅图像内.有缩放.翻转.仿射变换.透视.重映射等操作. 4.1 缩放 使用cv2. ...
随机推荐
- taro list render bug
taro list render bug 列表渲染 https://taro-docs.jd.com/taro/docs/list.html not support jsx map 垃圾微信 cons ...
- XML & XPath & XQuery
XML & XPath & XQuery full XPath demo https://www.w3.org/TR/xpath-full-text-30/ https://www.w ...
- vue & modal props & form data update bug
vue & modal props & form data update bug OK <div> <BindModal :dialogBindVisible=&qu ...
- NGK全网算力总量增加,SPC前景广阔
日前,根据NGK官方公布的数据显示,NGK全网算力总量达到550.96万,比早前预估的500万算力增加了50.96万,并且随着SPC空投的持续,还有不少生态建设者在持续涌入NGK算力市场.那么,是什么 ...
- NGK全球启动大会圆满落幕
加州时间2020年11月25日,NGK全球启动大会在美国硅谷圆满落幕.本次NGK全球启动大会为NGK正式在全球上线拉开了序幕. 百余位受邀嘉宾出席了本次NGK全球启动大会,其中包括NGK创始人.星盟投 ...
- Python算法_两数之和(01)
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但是,数组中同一个元素不能使用两遍. ...
- c#(winform)获取本地打印机
引用 using System.Drawing.Printing; //代码 PrintDocument prtdoc = new PrintDocument(); string strDefault ...
- 微信小程序(三)-事件绑定
小程序事件绑定 https://developers.weixin.qq.com/miniprogram/dev/framework/view/two-way-bindings.html 1.数据 / ...
- 第44天学习打卡(JUC 线程和进程 并发和并行 Lock锁 生产者和消费者问题 如何判断锁(8锁问题) 集合类不安全)
什么是JUC 1.java.util工具包 包 分类 业务:普通的线程代码 Thread Runnable 没有返回值.效率相比Callable相对较低 2.线程和进程 进程:一个程序.QQ.exe, ...
- 后端程序员之路 4、一种monitor的做法
record_t包含_sum._count._time_stamp._max._min最基础的一条记录,可以用来记录最大值.最小值.计数.总和metric_t含有RECORD_NUM(6)份recor ...