前文传送门:

「Python 图像处理 OpenCV (1):入门」

「Python 图像处理 OpenCV (2):像素处理与 Numpy 操作以及 Matplotlib 显示图像」

「Python 图像处理 OpenCV (3):图像属性、图像感兴趣 ROI 区域及通道处理」

「Python 图像处理 OpenCV (4):图像算数运算以及修改颜色空间」

「Python 图像处理 OpenCV (5):图像的几何变换」

「Python 图像处理 OpenCV (6):图像的阈值处理」

「Python 图像处理 OpenCV (7):图像平滑(滤波)处理」

「Python 图像处理 OpenCV (8):图像腐蚀与图像膨胀」

引言

前面介绍了图像形态学的两种基础算法,图像腐蚀和图像膨胀,本篇接着介绍图像形态学中的开运算、闭运算以及梯度运算。

由于内容的连贯性,请先阅读前文「Python 图像处理 OpenCV (8):图像腐蚀与图像膨胀」,了解清楚图像的腐蚀与膨胀基础原理。

不然真的没办法理解开运算和闭运算。

第一件事情还是给图像增加噪声,思路沿用之前加噪声的思路,使用 Numpy 给图片添加黑白两种噪声点,代码如下:

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt # 读取图片
img = cv.imread("demo.png", cv.IMREAD_UNCHANGED)
source = cv.cvtColor(img, cv.COLOR_BGR2RGB)
rows, cols, chn = source.shape # 加噪声-白点噪声
for i in range(500):
x = np.random.randint(0, rows)
y = np.random.randint(0, cols)
source[x, y, :] = 255 # 图像保存 白点噪声图像
cv.imwrite("demo_noise_white.jpg", source)
print("白点噪声添加完成") # 重新读取图像
img1 = cv.imread("demo.png", cv.IMREAD_UNCHANGED)
source1 = cv.cvtColor(img1, cv.COLOR_BGR2RGB) # 加噪声-黑点噪声
for i in range(1000):
x = np.random.randint(0, rows)
y = np.random.randint(0, cols)
source1[x, y, :] = 0 # 图像保存 黑点噪声图像
cv.imwrite("demo_noise_black.jpg", source1)
print("黑点噪声添加完成") # 显示结果
titles = ['White Img','Black Img']
images = [source, source1] # matplotlib 绘图
for i in range(2):
plt.subplot(1, 2, i+1), plt.imshow(images[i],'gray')
plt.title(titles[i])
plt.xticks([]),plt.yticks([]) plt.show()

形态学开运算

图像开运算实际上是一个组合运算,开运算是图像先进行腐蚀,再进行膨胀的运算。

图像被腐蚀后,去除了噪声,但是也压缩了图像;接着对腐蚀过的图像进行膨胀处理,使得刚才在腐蚀过程中被压缩的图像得以恢复原状。

下面是一个图像开运算的流程图:

开运算的一些特性:

  • 开运算能够除去孤立的小点,毛刺和小桥,而总的位置和形状不便。
  • 开运算是一个基于几何运算的滤波器。
  • 结构元素大小的不同将导致滤波效果的不同。
  • 不同的结构元素的选择导致了不同的分割,即提取出不同的特征。

我们先不管开运算 OpenCV 为我们提供的函数是什么,先使用前面介绍过的图像腐蚀与膨胀处理看下结果:

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt # 读取图片
source = cv.imread("demo_noise_white.jpg", cv.IMREAD_GRAYSCALE) # 设置卷积核
kernel = np.ones((5, 5),np.uint8) # 图像腐蚀
erode_img = cv.erode(source, kernel) # 图像膨胀
dilate_result = cv.dilate(erode_img, kernel) # 显示结果
titles = ['Source Img','Erode Img','Dilate Img']
images = [source, erode_img, dilate_result] # matplotlib 绘图
for i in range(3):
plt.subplot(1, 3, i+1), plt.imshow(images[i],'gray')
plt.title(titles[i])
plt.xticks([]),plt.yticks([]) plt.show()

可以看到降噪的效果还是不错的。

接着看 OpenCV 为开运算提供的函数。

图像开运算主要使用到的函数是 morphologyEx() 它是形态学扩展的一组函数,而其中的 cv.MORPH_OPEN 对应的是开运算。

使用时语法如下:

dst = cv.morphologyEx(src, cv.MORPH_OPEN, kernel)
  • src: 原图形
  • cv2.MORPH_OPEN: 表示开运算
  • kernel: 卷积核

我们再使用 morphologyEx() 函数去重新实现下刚才的图像开运算,看下和之前的结果有啥区别:

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt # 读取图片
source = cv.imread("demo_noise_white.jpg", cv.IMREAD_GRAYSCALE) # 设置卷积核
kernel = np.ones((5, 5),np.uint8) #图像开运算
dst = cv.morphologyEx(source, cv.MORPH_OPEN, kernel) # 显示结果
titles = ['Source Img','Dst Img']
images = [source, dst] # matplotlib 绘图
for i in range(2):
plt.subplot(1, 2, i+1), plt.imshow(images[i],'gray')
plt.title(titles[i])
plt.xticks([]),plt.yticks([]) plt.show()

至少从肉眼的角度上看不出来和之前的方式有啥区别,实际上也没啥区别。

形态学闭运算

与开运算相反的是闭运算,闭运算是图像先膨胀,后腐蚀,它有助于关闭前景物体内部的小孔,或物体上的小黑点。

先看下图像闭运算的流程图:

闭运算的一些特性:

  • 闭运算能够填平小湖(即小孔),弥合小裂缝,而总的位置和形状不变。
  • 闭运算是通过填充图像的凹角来滤波图像的。
  • 结构元素大小的不同将导致滤波效果的不同。
  • 不同结构元素的选择导致了不同的分割。

首先还是用 dilate()erode() 函数实现一下图像闭运算,代码如下:

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt # 读取图片
source = cv.imread("demo_noise_black.jpg", cv.IMREAD_GRAYSCALE) # 设置卷积核
kernel = np.ones((5, 5),np.uint8) # 图像膨胀
dilate_result = cv.dilate(source, kernel) # 图像腐蚀
erode_img = cv.erode(dilate_result, kernel) # 显示结果
titles = ['Source Img','Dilate Img','Erode Img']
images = [source, dilate_result, erode_img] # matplotlib 绘图
for i in range(3):
plt.subplot(1, 3, i+1), plt.imshow(images[i],'gray')
plt.title(titles[i])
plt.xticks([]),plt.yticks([]) plt.show()

如果想要使用形态学扩展的函数 morphologyEx() 则需要把里面的参数换成 MORPH_CLOSE ,同样,既然是形态学扩展函数,那么图像腐蚀和图像膨胀也有对应的参数:

  • 图像腐蚀: MORPH_ERODE
  • 图像膨胀: MORPH_DILATE

接着还是使用 MORPH_CLOSE 参数来实现下图像的闭运算:

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt # 读取图片
source = cv.imread("demo_noise_black.jpg", cv.IMREAD_GRAYSCALE) # 设置卷积核
kernel = np.ones((5, 5),np.uint8) # 图像闭运算
dst = cv.morphologyEx(source, cv.MORPH_CLOSE, kernel) # 显示结果
titles = ['Source Img','Dst Img']
images = [source, dst] # matplotlib 绘图
for i in range(2):
plt.subplot(1, 2, i+1), plt.imshow(images[i],'gray')
plt.title(titles[i])
plt.xticks([]),plt.yticks([]) plt.show()

形态学梯度运算

图像形态学的梯度运算和前面的开运算闭运算是一样的,都是组合函数。

梯度运算实际上是图像膨胀减去图像腐蚀后的结果,最终我们得到的是一个类似于图像轮廓的图形。

梯度运算在 morphologyEx() 函数中的参数是 MORPH_GRADIENT ,示例代码如下:

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt # 读取图片
source = cv.imread("demo.png", cv.IMREAD_GRAYSCALE) # 设置卷积核
kernel = np.ones((5, 5), np.uint8) # 图像梯度运算
dst = cv.morphologyEx(source, cv.MORPH_GRADIENT, kernel) # 显示结果
titles = ['Source Img','Dst Img']
images = [source, dst] # matplotlib 绘图
for i in range(2):
plt.subplot(1, 2, i+1), plt.imshow(images[i],'gray')
plt.title(titles[i])
plt.xticks([]),plt.yticks([]) plt.show()

示例代码

如果有需要获取源码的同学可以在公众号回复「OpenCV」进行获取。

参考

http://www.woshicver.com/

https://blog.csdn.net/Eastmount/article/details/83651172

https://blog.csdn.net/hanshanbuleng/article/details/80657148

Python 图像处理 OpenCV (9):图像处理形态学开运算、闭运算以及梯度运算的更多相关文章

  1. Python 图像处理 OpenCV (10):图像处理形态学之顶帽运算与黑帽运算

    前文传送门: 「Python 图像处理 OpenCV (1):入门」 「Python 图像处理 OpenCV (2):像素处理与 Numpy 操作以及 Matplotlib 显示图像」 「Python ...

  2. 【OpenCV新手教程之十一】 形态学图像处理(二):开运算、闭运算、形态学梯度、顶帽、黑帽合辑

    本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接:http://blog.csdn.net/poem_qianmo/article/details/23184547 作者:毛星云(浅墨) ...

  3. opencv 4 图像处理(2 形态学滤波:腐蚀与膨胀,开运算、闭运算、形态学梯度、顶帽、黑帽)

    腐蚀与膨胀 膨胀(求局部最大值)(dilate函数) #include <opencv2/core/core.hpp> #include <opencv2/highgui/highg ...

  4. 学习 opencv---(10)形态学图像处理(2):开运算,闭运算,形态学梯度,顶帽,黒帽合辑

    上篇文章中,我们重点了解了腐蚀和膨胀这两种最基本的形态学操作,而运用这两个基本操作,我们可以实现更高级的形态学变换. 所以,本文的主角是OpenCV中的morphologyEx函数,它利用基本的膨胀和 ...

  5. Python 图像处理 OpenCV (4):图像算数运算以及修改颜色空间

    前文传送门: 「Python 图像处理 OpenCV (1):入门」 「Python 图像处理 OpenCV (2):像素处理与 Numpy 操作以及 Matplotlib 显示图像」 「Python ...

  6. Python 图像处理 OpenCV (12): Roberts 算子、 Prewitt 算子、 Sobel 算子和 Laplacian 算子边缘检测技术

    前文传送门: 「Python 图像处理 OpenCV (1):入门」 「Python 图像处理 OpenCV (2):像素处理与 Numpy 操作以及 Matplotlib 显示图像」 「Python ...

  7. Python 图像处理 OpenCV (13): Scharr 算子和 LOG 算子边缘检测技术

    前文传送门: 「Python 图像处理 OpenCV (1):入门」 「Python 图像处理 OpenCV (2):像素处理与 Numpy 操作以及 Matplotlib 显示图像」 「Python ...

  8. Python 图像处理 OpenCV (14):图像金字塔

    前文传送门: 「Python 图像处理 OpenCV (1):入门」 「Python 图像处理 OpenCV (2):像素处理与 Numpy 操作以及 Matplotlib 显示图像」 「Python ...

  9. Python 图像处理 OpenCV (15):图像轮廓

    前文传送门: 「Python 图像处理 OpenCV (1):入门」 「Python 图像处理 OpenCV (2):像素处理与 Numpy 操作以及 Matplotlib 显示图像」 「Python ...

随机推荐

  1. mysql操作之二:fetchone与获取lastrowid

    import mySQLdb conn = mySQLdb.connect(host='127.0.0.1',user='root',passwd='123456')cur = conn.cursor ...

  2. 解决el-tree横向滚动条问题

    代码如下 效果如图 仅做下记录,不做过多解释

  3. Hyperledger fabric MSP成员管理

    Hyperledger fabric 1.0 基于 PKI(Public Key Infrastructure)体系,引入了MSP模块(Membership Service Provider): 成员 ...

  4. POJ2516

    题目链接:http://poj.org/problem?id=2516 解题思路: 最小费用最大流,这个没什么疑问.但此题小难点在于读题,大难点在于建图. 首先,供应量小于需求量的时候直接输出“-1” ...

  5. 剑指Offer之二进制中1的个数

    题目描述 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示.     解法1:使用Integer.toBinanryString()返回int变量的二进制表示的字符串. [在Intege ...

  6. win上的python

    #启用浏览器,最大化窗口 #coding = utf-8 from selenium import webdriver class MyClass(object): ''' classdocs ''' ...

  7. idea本地Maven仓库不能下载依赖jar包的解决方案

    1.确认maven是否正正常安装,是否配置了环境变量,可以通过命令 mvn -version 看是否显示maven的版本信息. 2.检查maven的setting.xml配置文件中本地仓库位置配置是否 ...

  8. 01 . Memcached简介及部署

    Memcached简介 memcached是一个自由开源,高性能,分布式内存对象存储系统 基于内存的key-valued存储,用来存储小块的任意数据(字符串,对象) 他是一个简洁的key-value存 ...

  9. pix三接口配置

    拓扑 R1 R1#conf t Enter configuration commands, one per line. End with CNTL/Z. R1(config)#int f0/0 R1( ...

  10. java中的垃圾处理机制

    1.何为垃圾在Java中,如果对象实体没有引用指向的话,存储该实体的内存便成为垃圾.JVM会有一个系统线程专门负责回收垃圾.垃圾同时包括分配对象内存间的碎片块 2.垃圾处理包含的算法 Java语言规范 ...