形态学操作其实就是改变物体的形状,比如腐蚀就是"变瘦",膨胀就是"变胖",看下图就明白了:

形态学操作一般作用于二值化图(也可直接作用于原图),来连接相邻的元素或分离成独立的元素。腐蚀和膨胀是针对图片中的白色部分!

腐蚀

腐蚀的效果是把图片"变瘦",其原理是在原图的小区域内取局部最小值。因为是二值化图,只有0和255,所以小区域内有一个是0该像素点就为0:

这样原图中边缘地方就会变成0,达到了瘦身目的

OpenCV中用cv2.erode()函数进行腐蚀,只需要指定核的大小就行:

img = cv2.imread('j.bmp', 0)
kernel = np.ones((5, 5), np.uint8)
erosion = cv2.erode(img, kernel) # 腐蚀

这个核也叫结构元素,因为形态学操作其实也是应用卷积来实现的。

结构元素可以是矩形/椭圆/十字形,可以用cv2.getStructuringElement()来生成不同形状的结构元素,比如:

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))  # 矩形结构
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5)) # 椭圆结构
kernel = cv2.getStructuringElement(cv2.MORPH_CROSS, (5, 5)) # 十字形结构

膨胀

膨胀与腐蚀相反,取的是局部最大值,效果是把图片"变胖":

dilation = cv2.dilate(img, kernel)  # 膨胀

开/闭运算

先腐蚀(瘦)后膨胀(胖)叫开运算(因为先腐蚀会分开物体,这样容易记住),其作用是:分离物体,消除小区域。这类形态学操作用cv2.morphologyEx()函数实现:

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))  # 定义结构元素

img = cv2.imread('j_noise_out.bmp', 0)
opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel) # 开运算

def open_demo(image):
print(image.shape)
gray = cv.cvtColor(image,cv.COLOR_BGR2GRAY)
ret , binary = cv.threshold(gray,0,255,cv.THRESH_BINARY|cv.THRESH_OTSU)
# kernel = np.ones((5,5),np.uint16)
kernel = cv.getStructuringElement(cv.MORPH_RECT,(5,5))
dst = cv.morphologyEx(binary,cv.MORPH_OPEN,kernel)
cv.imshow("open_demo",dst)

闭运算则相反:先膨胀后腐蚀先膨胀会使白色的部分扩张,以至于消除/"闭合"物体里面的小黑洞,所以叫闭运算

img = cv2.imread('j_noise_in.bmp', 0)
closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel) # 闭运算

def close_demo(image):
print(image.shape)
gray = cv.cvtColor(image,cv.COLOR_BGR2GRAY)
ret , binary = cv.threshold(gray,0,255,cv.THRESH_BINARY|cv.THRESH_OTSU)
cv.imshow("binary", binary)
# kernel = np.ones((5,5),np.uint16)
kernel = cv.getStructuringElement(cv.MORPH_RECT,(5,5))
dst = cv.morphologyEx(binary,cv.MORPH_CLOSE,kernel)
cv.imshow("close_demo",dst)

经验之谈:很多人对开闭运算的作用不是很清楚,看上图↑:
如果我们的目标物体外面有很多无关的小区域,就用开运算去除掉;
如果物体内部有很多小黑洞,就用闭运算填充掉。
开操作去掉外部小的干扰,用腐蚀也能做到,二者的区别在于开操作只去掉外部小的干扰而保留了其他部分不变

其他形态学操作

  • 形态学梯度:膨胀图减去腐蚀图,dilation - erosion,这样会得到物体的轮廓:
img = cv2.imread('school.bmp', 0)
gradient = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)

  • 顶帽(tophat):原图减去开操作后的图:src - opening
tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)
  • 黑帽(blackhat):闭运算图像与原图像差值:closing - src
blackhat = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)

def tophat_demo(image):
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY_INV | cv.THRESH_OTSU)
# kernel = np.ones((5,5),np.uint16)
kernel = cv.getStructuringElement(cv.MORPH_RECT, (5, 5))
dst = cv.morphologyEx(gray, cv.MORPH_GRADIENT, kernel)
# dst = cv.morphologyEx(binary, cv.MORPH_BLACKHAT, kernel)
"""给dst图像添加亮度"""
# cimage = np.array(gray.shape,np.uint8)
# cimage = 120
# dst = cv.add(dst,cimage)
cv.imshow("MORPH_GRADIENT_demo", dst)

对Binary二值图进行腐蚀 膨胀等形态学操作

def erode_demo(image):
print(image.shape)
gray = cv.cvtColor(image,cv.COLOR_BGR2GRAY)
ret , binary = cv.threshold(gray,0,255,cv.THRESH_BINARY|cv.THRESH_OTSU)
# kernel = np.ones((5,5),np.uint16)
kernel = cv.getStructuringElement(cv.MORPH_RECT,(5,5))
dst = cv.erode(binary,kernel=kernel)
cv.imshow("erode_demo",dst) def dilate_demo(image):
print(image.shape)
gray = cv.cvtColor(image,cv.COLOR_BGR2GRAY)
ret , binary = cv.threshold(gray,0,255,cv.THRESH_BINARY|cv.THRESH_OTSU)
cv.imshow("binary", binary)
# kernel = np.ones((5,5),np.uint16)
kernel = cv.getStructuringElement(cv.MORPH_RECT,(5,5))
dst = cv.dilate(binary,kernel=kernel)
cv.imshow("dilate_demo",dst)

对BGR原图直接进行腐蚀 膨胀等形态学操作

"""BGR图像直接进行腐蚀 膨胀"""
src0 = cv.imread('beauty1.jpg')
cv.imshow('input_image',src0)
kernel = cv.getStructuringElement(cv.MORPH_RECT,(5,5))
dilate_dst = cv.dilate(src0,kernel=kernel)
cv.imshow("dilate_dst",dilate_dst)
erode_dst = cv.erode(src0,kernel=kernel)
cv.imshow("erode_dst",erode_dst)

参考:

https://docs.opencv.org/3.0-beta/doc/py_tutorials/py_imgproc/py_morphological_ops/py_morphological_ops.html#morphological-ops

https://www.jianshu.com/p/05ef50ac89ac

【python-opencv】17-形态学操作-腐蚀与膨胀的更多相关文章

  1. opencv:形态学操作-腐蚀与膨胀

    #include <opencv2/opencv.hpp> #include <iostream> using namespace cv; using namespace st ...

  2. OpenCV图像处理篇之腐蚀与膨胀

    转载请注明出处:http://xiahouzuoxin.github.io/notes 腐蚀与膨胀 腐蚀和膨胀是图像的形态学处理中最主要的操作,之后遇见的开操作和闭操作都是腐蚀和膨胀操作的结合运算. ...

  3. OpenCV学习 7:图像形态学:腐蚀、膨胀

    原创文章,欢迎转载,转载请注明出处 首先什么是图像形态学?额,这个抄下百度到的答案.基本思想:    用具有一定形态的结构元素去度量和提取图像中的对应形状已达到对图像分析和识别的目的,形态学图像处理表 ...

  4. python实现其它形态学操作

    目录: (一) 顶帽(原图像与开操作图像的差值)(二) 黑帽(原图像与闭操作图像的差值)(三) 形态学梯度  (1)基本梯度(膨胀后的图像与腐蚀后的图像差值)  (2)内部梯度(原图像减去腐蚀后的图像 ...

  5. python opencv入门-形态学转换

    目标: 学习不同的形态操作 例如 腐蚀.膨胀.开运算.闭运算 等. 我们要学习的函数有 cv2.erode(),cv2.dilate(),cv2.morphologyEx() 等. 原理 :一般对二值 ...

  6. opencv —— erode、dilate 腐蚀与膨胀

    腐蚀与膨胀是形态学滤波.其中,腐蚀是最小值滤波,膨胀是最大值滤波,即分别选取内核中的最小值与最大值赋值给锚点.若内核为 N×1 或 1×N 形状,可用于横纵方向直线检测. 膨胀:dilate 函数 v ...

  7. 机器学习进阶-图像形态学操作-腐蚀操作 1.cv2.erode(进行腐蚀操作)

    1.cv2.erode(src, kernel, iteration) 参数说明:src表示的是输入图片,kernel表示的是方框的大小,iteration表示迭代的次数 腐蚀操作原理:存在一个ker ...

  8. python opencv:像素操作

    图片的像素 像素:组成图片的单位 RGB:颜色由 RGB三种颜色组成 颜色深度:对于8bit的颜色深度来说,它可以表示的颜色范围是 0 ~ 255,对于RGB图片来说,8位颜色深度可以表示 (2^8) ...

  9. python Opencv图像基础操作

    读取并显示图像 如果读取图像首先要导入OpenCV包,方法为: import cv2 读取并显示图像 img = cv2.imread("C:\test1.jpg") OpenCV ...

随机推荐

  1. C语言的声明的优先级规则

    C语言的声明的优先级规则如下: A 声明从它的名字开始读取,然后按照优先级顺序依次读取 B 优先级从高到低依次是:   B.1 声明中被括号括起来的那一部分   B.2 后缀操作符[圆括号 ()表示这 ...

  2. Outlook 2007 实现自动添加密送的方法

    1)在Outlook里面键入Alt+F11打开VBA编辑器:     2)激活左边的工程面板,展开并双击上面的“Project (VbaProject.OTM)/Microsoft Office Ou ...

  3. sqlite3常用指令

    一.建立数据库 sqlite3.exe test.db 二.双击sqlite-3_6_16目录下的程序sqlite3.exe,即可运行 三.退出 .exit 或者 .quit 四.SQLite支持如下 ...

  4. 【Java并发编程一】线程安全和共享对象

    一.什么是线程安全 当多个线程访问一个类时,如果不用考虑这些线程在运行时环境下的调度和交替执行,并且不需要额外的同步及在调用代码代码不必作其他的协调,这个类的行为仍然是正确的,那么称这个类是线程安全的 ...

  5. STL源码剖析—顺序容器

    一.vector 1.vector简介: vector的数据安排及其操作方式与数组非常相似,微小的差别在于空间的使用,数组是静态空间,一旦配置了就不能改变.vector是动态空间,随着元素的加入,它的 ...

  6. 【PHP】常见算法

    1 冒泡排序 思路:在要排序的一组数中,对当前还未排好的序列,从前往后对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒. 即,每当两相邻的数比较后发现它们的排序与排序要求相反时,就将它 ...

  7. vuex - 常用命令学习及用法整理

    https://vuex.vuejs.org/zh-cn/api.html 命令 用途 备注 this.$store 组件中访问store实例 store.state.a 获取在state对象中的数据 ...

  8. VIM 如何使用系统的剪切板

    想要将系统剪贴板里的内容复制到 vi 编辑的文档中怎么办? 例如,在网页上复制了一段文字,想贴到本地的某个文件中. 使用 vi 打开本地文件,在 输入 模式下,按 Shift + Insert 详细可 ...

  9. POJ 3579 Median(二分答案)

    Median Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 11599 Accepted: 4112 Description G ...

  10. Unity3D protobuf-net使用方式

    1.下载protobuf-net 2.创建Unity工程,创建一个Plugins文件夹,将protobuf-net解压把里面得protobuf-net放到Plugins 3.创建一个名为mcs的文本文 ...