通过阈值化分割可以得到二值图,但往往会出现图像中物体形态不完整,变的残缺,可以通过形态学处理,使其变得丰满,或者去除掉多余的像素。常用的形态学处理算法包括:腐蚀,膨胀,开运算,闭运算,形态学梯度,顶帽运算和底帽运算。

1. 腐蚀

   腐蚀操作类似于中值平滑,也有一个核,但不进行卷积运算,而是取核中像素值的最小值代替锚点位置的像素值,这样就会使图像中较暗的区域面积增大,较亮的的区域面积减小。如果是一张黑底,白色前景的二值图,就会使白色的前景物体颜色变小,就像被腐蚀了一样。

   进行腐蚀操作的核,不仅可以是矩形,还可以是十字形和椭圆形,opencv提供getStructuringElement()函数来获得核,其参数如下:

kernel=cv2.getStructuringElement(shape,ksize,anchor)
shape:核的形状
cv2.MORPH_RECT: 矩形
cv2.MORPH_CROSS: 十字形(以矩形的锚点为中心的十字架)
cv2.MORPH_ELLIPSE:椭圆(矩形的内切椭圆) ksize: 核的大小,矩形的宽,高格式为(width,height)
anchor: 核的锚点,默认值为(-,-),即核的中心点

   opencv提供erode()函数进行腐蚀操作,其对应参数如下:

dst=cv2.erode(src,kernel,anchor,iterations,borderType,borderValue):
src: 输入图像对象矩阵,为二值化图像
kernel:进行腐蚀操作的核,可以通过函数getStructuringElement()获得
anchor:锚点,默认为(-,-)
iterations:腐蚀操作的次数,默认为1
borderType: 边界种类,有默认值
borderValue:边界值,有默认值

   腐蚀操作的代码和效果如下:

   可以看到二值化图像中白色的opencv字体面积变小了,就像被腐蚀了。注意这是黑底白字,如果是白底黑字,效果会相反,字体反而会膨胀。

#coding:utf-

import cv2 as cv

img = cv.imread(r"C:\Users\Administrator\Desktop\logo.png")
img_cvt = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
ret,img_thr = cv.threshold(img_cvt,,,cv.THRESH_BINARY_INV)
kernel = cv.getStructuringElement(cv.MORPH_RECT,(,))
dst = cv.erode(img_thr,kernel,iterations=) cv.imshow("img",img)
cv.imshow("img_thr",img_thr)
cv.imshow("dst",dst)
cv.waitKey()
cv.destroyAllWindows()

cv2.erode()

2.膨胀

  膨胀操作和腐蚀操作正好相反,是取核中像素值的最大值代替锚点位置的像素值,这样会使图像中较亮的区域增大,较暗的区域减小。如果是一张黑底,白色前景的二值图,就会使白色的前景物体颜色面积变大,就像膨胀了一样

    opencv提供dilate()函数进行膨胀操作,其对应参数如下:

dst = cv2.dilate(src,kernel,anchor,iterations,borderType,borderValue)
src: 输入图像对象矩阵,为二值化图像
kernel:进行腐蚀操作的核,可以通过函数getStructuringElement()获得
anchor:锚点,默认为(-,-)
iterations:腐蚀操作的次数,默认为1
borderType: 边界种类
borderValue:边界值

    膨胀操作的代码和效果如下:

    可以看到二值化图像中白色的opencv字体面积变大了,就像膨胀了

#coding:utf-

import cv2 as cv

img = cv.imread(r"C:\Users\Administrator\Desktop\logo.png")
img_cvt = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
ret,img_thr = cv.threshold(img_cvt,,,cv.THRESH_BINARY_INV)
kernel = cv.getStructuringElement(cv.MORPH_RECT,(,))
dst = cv.dilate(img_thr,kernel,iterations=) cv.imshow("img",img)
cv.imshow("img_thr",img_thr)
cv.imshow("dst",dst)
cv.waitKey()
cv.destroyAllWindows()

cv2.dilate()

3.开运算,闭运算,顶帽,顶帽

  开运算:先进行腐蚀操作,后进行膨胀操作,主要用来去除一些较亮的部分,即先腐蚀掉不要的部分,再进行膨胀。

  闭运算:先进行膨胀操作,后进行腐蚀操作,主要用来去除一些较暗的部分。

  形态学梯度:膨胀运算结果减去腐蚀运算结果,可以拿到轮廓信息。

  顶帽运算:原图像减去开运算结果。

  底帽运算:原图像减去闭运算结果。  

  进行开运算,闭运算,顶帽运算,底帽运算,形态学梯度,opencv提供了一个统一的函数cv2.morphologyEx(),其对应参数如下:

dst = cv2.morphologyEx(src,op,kernel,anchor,iterations,borderType,borderValue)
src: 输入图像对象矩阵,为二值化图像
op: 形态学操作类型
cv2.MORPH_OPEN 开运算
cv2.MORPH_CLOSE 闭运算
cv2.MORPH_GRADIENT 形态梯度
cv2.MORPH_TOPHAT 顶帽运算
cv2.MORPH_BLACKHAT 底帽运算 kernel:进行腐蚀操作的核,可以通过函数getStructuringElement()获得
anchor:锚点,默认为(-,-)
iterations:腐蚀操作的次数,默认为1
borderType: 边界种类
borderValue:边界值

  使用代码和对应效果如下:

#coding:utf-

import cv2 as cv
import matplotlib.pyplot as plt img = cv.imread(r"C:\Users\Administrator\Desktop\logo.png")
img_cvt = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
ret,img_thr = cv.threshold(img_cvt,,,cv.THRESH_BINARY_INV)
kernel = cv.getStructuringElement(cv.MORPH_RECT,(,))
open = cv.morphologyEx(img_thr,cv.MORPH_OPEN,kernel,iterations=)
close = cv.morphologyEx(img_thr,cv.MORPH_CLOSE,kernel,iterations=)
gradient = cv.morphologyEx(img_thr,cv.MORPH_GRADIENT,kernel,iterations=)
tophat = cv.morphologyEx(img_thr,cv.MORPH_TOPHAT,kernel,iterations=)
blackhat = cv.morphologyEx(img_thr,cv.MORPH_BLACKHAT,kernel,iterations=) images=[img_thr,open,close,gradient,tophat,blackhat]
titles=["img_thr","open","close","gradient","tophat","blackhat"]
for i in range():
plt.subplot(,,i+),plt.imshow(images[i],"gray")
plt.title(titles[i])
plt.xticks([]), plt.yticks([])
plt.show()

cv2.morphologyEx()

 

4.应用实例

  有如下一张中文图片,当我们进行字符切割时,常需要知道其中的汉字是否带下划线,方便进行后续处理。

  我们首先想到的可能是使用霍夫直线检测算法,但是直接检测时,会有很多干扰。我们可以通过采用一个横向的矩阵核,来腐蚀字体,使图片中只剩下下划线,然后再进行霍夫直线检测,这样干扰小,准确度会高很多。具体实现代码和效果如下:

#coding:utf-

import cv2 as cv

img = cv.imread(r"C:\Users\Administrator\Desktop\chinese.png")
img_cvt = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
ret,img_thr = cv.threshold(img_cvt,,,cv.THRESH_BINARY)
kernel = cv.getStructuringElement(cv.MORPH_RECT,(,)) #由于是1*30的矩阵,字体会被横向空隙的白色腐蚀掉,而下划线横向都是黑色,不会腐蚀
dst = cv.dilate(img_thr,kernel,iterations=) #由于是白底黑字,所有进行膨胀操作来去除黑色字体
cv.imshow("img_thr",img_thr)
cv.imshow("dst",dst)
cv.waitKey()
cv.destroyAllWindows()

  

(四)OpenCV-Python学习—形态学处理的更多相关文章

  1. 四、python学习-正则表达式

    正则表达式 import re lst = re.findall(正则表达式,需要匹配的字符串) findall 把所有匹配到的字符串都搜出来,返回列表 不能把分组内容和匹配内容同时显示出来 sear ...

  2. OpenCV之Python学习笔记

    OpenCV之Python学习笔记 直都在用Python+OpenCV做一些算法的原型.本来想留下发布一些文章的,可是整理一下就有点无奈了,都是写零散不成系统的小片段.现在看 到一本国外的新书< ...

  3. python学习心得第四章

     python 学习心得第四章 1.lambda表达式 1:什么是lambda表达式 为了简化简单函数的代码,选择使用lambda表达式 上面两个函数的表达式虽然不一样,但是本质是一样的,并且lamb ...

  4. Python之路【第二十四篇】:Python学习路径及练手项目合集

      Python学习路径及练手项目合集 Wayne Shi· 2 个月前 参照:https://zhuanlan.zhihu.com/p/23561159 更多文章欢迎关注专栏:学习编程. 本系列Py ...

  5. python学习笔记--Django入门四 管理站点--二

    接上一节  python学习笔记--Django入门四 管理站点 设置字段可选 编辑Book模块在email字段上加上blank=True,指定email字段为可选,代码如下: class Autho ...

  6. [Python学习笔记][第四章Python字符串]

    2016/1/28学习内容 第四章 Python字符串与正则表达式之字符串 编码规则 UTF-8 以1个字节表示英语字符(兼容ASCII),以3个字节表示中文及其他语言,UTF-8对全世界所有国家需要 ...

  7. Python学习笔记(十四)

    Python学习笔记(十四): Json and Pickle模块 shelve模块 1. Json and Pickle模块 之前我们学习过用eval内置方法可以将一个字符串转成python对象,不 ...

  8. Python学习笔记(四)

    Python学习笔记(四) 作业讲解 编码和解码 1. 作业讲解 重复代码瘦身 # 定义地图 nav = {'省略'} # 现在所处的层 current_layer = nav # 记录你去过的地方 ...

  9. python学习之路网络编程篇(第四篇)

    python学习之路网络编程篇(第四篇) 内容待补充

  10. python学习第四讲,python基础语法之判断语句,循环语句

    目录 python学习第四讲,python基础语法之判断语句,选择语句,循环语句 一丶判断语句 if 1.if 语法 2. if else 语法 3. if 进阶 if elif else 二丶运算符 ...

随机推荐

  1. 说说你对kubernetes的理解(简单)

    目录 整体概述 pod工作流程 k8s网络 flannel 网络策略,network proxy 几套证书理解 组件 master管理节点上组件 node节点 整体概述 k8s是一个编排工具,是谷歌的 ...

  2. 记一次SQL PLUS 不能登录的异常处理

    记一次SQL PLUS 不能登录的异常处理 现象 通过远程PLSQL Developer 访问数据发现卡死没响应. 通过Sqlplus 访问数据同样hang死在登录界面,且不能通过Ctrl+C取消 [ ...

  3. C#预处理器指令——学习

    若要详细了解如何使用 C# 预处理器指令选择性地编译代码段,请参阅 #define(C# 参考)和 #if(C# 参考). #define(C# 参考) 地址:https://docs.microso ...

  4. python函数式编程-装饰器

    在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator). 由于函数也是一个对象,而且函数对象可以赋值给变量,所以通过变量也能调用该函数. >>> def now() ...

  5. unity之中级必备知识

    Mask,Scroll Rect实现图拖拽:新建Imag,添加Mask,Scroll Rect组件:新建Image,托放在Scroll下的Content:新建Scroll Bar实现滚动条的同步:托放 ...

  6. PWA相关代码

    sw.js 文件 let CacheName = 'plus-v1'; var filesToCache = [ ]; self.addEventListener('install', functio ...

  7. BZOJ1997 HNOI2010 平面图判定 planar (并查集判二分图)

    题意 判断一个存在哈密顿回路的图是否是平面图. n≤200,m≤10000n\le200,m\le10000n≤200,m≤10000 题解 如果一定存在一个环,那么连的边要么在环里面要么在外面.那么 ...

  8. Linux文件权限符号说明

    为了控制权限,Linux首先对于将操作的用户分为:用户.用户组和其他,这三个概念. 每个文件都会属于某个用户,而一个用户可以属于多个用户组,而不属于该用户组的用户,则属于其他.因此,每个文件的操作权限 ...

  9. Mongo mongoexport/mongoimport介绍

    一.Mongoexport导出数据 1,导出json数据 mongoexport -d db -c collection -o save-file.dat 2,导出CSV数据 mongoexport ...

  10. 003_Python3 基本数据类型

    1.Python 中的变量不需要声明.每个变量在使用前都必须赋值,变量赋值以后该变量才会被创建. 在 Python 中,变量就是变量,它没有类型,我们所说的"类型"是变量所指的内存 ...