Python 图像处理 OpenCV (9):图像处理形态学开运算、闭运算以及梯度运算
前文传送门:
「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」进行获取。
参考
https://blog.csdn.net/Eastmount/article/details/83651172
https://blog.csdn.net/hanshanbuleng/article/details/80657148
相关文章
- Python 图像处理 OpenCV (15):图像轮廓
- Python 图像处理 OpenCV (13): Scharr 算子和 LOG 算子边缘检测技术
- Python 图像处理 OpenCV (10):图像处理形态学之顶帽运算与黑帽运算
- Python 图像处理 OpenCV (5):图像的几何变换
- Python 图像处理 OpenCV (2):像素处理与 Numpy 操作以及 Matplotlib 显示图像
- Python 图像处理 OpenCV (1):入门
- 【OpenCV-Python】教程:1-5 TrackerBar
- 【OpenCV-Python】教程:1-4 鼠标交互事件
- Python的IDE:基于Eclipse/MyEclipse软件的PyDev插件配置python的开发环境(不同python项目加载不同版本的python)—从而实现Python编程图文教程之详细攻略
- Python之多线程:python多线程设计之同时执行多个函数命令详细攻略
- Py之cv2:cv2(OpenCV,opencv-python)库的简介、安装、使用方法(常见函数、图像基本运算等)最强详细攻略
- CV之IC:基于OpenCV的CascadeClassifier级联分类器利用python语言加载猫脸检测文件haarcascade_frontalcatface.xml实现对猫脸检测并标注文本标签
- Python之tkinter:动态演示调用python库的tkinter带你进入GUI世界(Button展示图片事件)
- 成功解决cv2.error: OpenCV(4.1.2) C:projectsopencv-pythonopencvmodulesimgprocsrccolor.cpp:182: err
- 已解决2.Set PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python (but this will use pure-Python parsing and wi
- opencv-python图像处理之轮廓算法
- Python-OpenCV分割图像查枸杞的个数
- Python图像处理丨基于OpenCV和像素处理的图像灰度化处理
- Python图像处理丨OpenCV+Numpy库读取与修改像素
- C++版本的OpenCV 5.x编译生成opencv-python==5.x(GPU版本)接口并进行调用
- Python-OpenCV图像处理-03-色彩空间
- Python-OpenCV图像处理-01-图像的加载和保存
- 人脸检测进阶:使用 dlib、OpenCV 和 Python 检测眼睛、鼻子、嘴唇和下巴等面部五官
- OpenCV-Python学习(21)—— OpenCV 图像几何变换之图像翻转(cv.flip、np.flip)
- Python&Opencv基于CNN手势识别玩恐龙跳小游戏(完整源码&自定义UI操作界面&视频教程)