【OpenCV 图像形态学】1.膨胀与腐蚀

本文转载自https://blog.****.net/weixin_41929524/article/details/81187173
在原文基础上稍有修改

图像的形态学操作

接着前面的图像入门,现在介绍一些简单的图像处理方法,同时在介绍方法之后,还会附上Python的实现,主要是基于OpenCV这一库来进行实现。

网上关于简单的图像处理的文章有很多很多,后面简单的图像处理系列博客中,或多或少的参考了下述这些大佬的分享:
https://blog.****.net/sn_gis/article/details/57414029
https://jingyan.baidu.com/article/f96699bbf99d9e894f3c1b4c.html
https://blog.****.net/swj110119/article/details/51123072
https://www.zhihu.com/question/19714540
https://zhuanlan.zhihu.com/p/19763358
https://blog.****.net/struggle_for_m/article/details/51207370
https://blog.****.net/jnulzl/article/details/47171549
https://blog.****.net/JohinieLi/article/details/69389980?locationNum=11&fps=1
https://blog.****.net/jjddss/article/details/72841141
https://blog.****.net/fengjiexyb/article/details/78031013
https://blog.****.net/xuyangcao123/article/details/81023732

在简单的图像处理中,我们会从最基础的图像形态学操作说起(平移、旋转、反射、剪裁等操作这里就不进行详细的说明了)。在这之前,我们先回顾一下图像的基本组成。
····················································································································································

1. 回顾:万物皆数

数字图像的组成单元都是由一个一个的数字构成的,每个数字我们也称之为像素。像素点越密,则图像越清晰;像素点越稀,则图像越模糊。另外,每个数字的大小代表颜色的深浅。就一张灰度图而言,其是一个图层的,上面的值越大,就说明图像这个点越白,255对应的就是白色。而值越小则代表着颜色越黑,0对应的就是黑色。具体如下图所示:
【OpenCV 图像形态学】1.膨胀与腐蚀
而彩色图对应的是三个图层,分别为R\G\B,每个层都是0-255之间,三个图层叠加,就是我们所看到的彩色数字图像了

2. 什么是形态学操作?

一系列操作基于形状来操作图像,形态学操作通过在图像上应用结构元素来产生输出图像。改变物体的形状,比如腐蚀就是“变瘦”,膨胀就是“变胖”,如下面这张图所示:
【OpenCV 图像形态学】1.膨胀与腐蚀
然后包括膨胀腐蚀在内,一系列的这两者各种叠加作用的操作都称为图像的形态学操作。

最基础的形态学操作就是腐蚀和膨胀。它包含广泛的应用:

  • 移除噪声
  • 孤立一些单独的元素和聚合一些分散的元素
  • 找到图像中的局部块状或者孔

我们使用下面这只可爱的小鸟,来对一系列的形态学操作进行说明。
【OpenCV 图像形态学】1.膨胀与腐蚀

3. 膨胀与腐蚀

膨胀

使用卷积核B对图片A进行卷积运算,求局部最大值,这个卷积核可以有任意的形状和大小,通常是一个方形或者圆形。
卷积核B通常有个锚点,通常位于卷积核的*位置。

随着卷积核扫描这个图像,我们计算叠加区域的最大像素值,并将锚点的位置用最大值替换。也就是最大化操作导致图片中的区域增长(所以这里面叫做膨胀)。
【OpenCV 图像形态学】1.膨胀与腐蚀
如上面两图所示,上面的第一个是针对二值图进行操作膨胀操作。可以发现,这一操作是使得白色区域“变胖”,黑色区域“变瘦”,从下图即可看出。
【OpenCV 图像形态学】1.膨胀与腐蚀
而针对彩色图像,可以想象,由于我们是只保留最大值,所以当选取的核越大时,图像整体会越模糊,并且会越偏向于白色(因为白色对应的值是255),下面两图分别是核为10*10以及核为50*50两种情况进行膨胀的效果,大家可以感受一下。

【OpenCV 图像形态学】1.膨胀与腐蚀
【OpenCV 图像形态学】1.膨胀与腐蚀

腐蚀

膨胀和腐蚀是一对好基友,是相反的一对操作,所以腐蚀就是求局部最小值的操作。腐蚀与膨胀类似,计算卷积核里面的最小元素。

随着卷积核B扫描图片,它会计算B叠加区域的最小像素值,并使用这个像素值替换锚点的值。与膨胀相似,对原始的图像应用腐蚀操作。你可以看到背景亮的区域变小,而黑的区域变得很大
【OpenCV 图像形态学】1.膨胀与腐蚀
在二值图上直观的体现,就是白色的部分变小,黑色的部分变大,正好与前面的膨胀相对。
【OpenCV 图像形态学】1.膨胀与腐蚀
而针对彩色图像,一样可以想象,由于我们是只保留最小值,所以当选取的核越大时,图像整体会越模糊,并且会越偏向于黑色(黑色对应的值是0),其中一些黑色的小元素也会被放大(例如下图中的小沙子),下面两图分别是核为10*10以及核为50*50两种情况进行腐蚀的效果,第二张非常惊悚。
【OpenCV 图像形态学】1.膨胀与腐蚀
【OpenCV 图像形态学】1.膨胀与腐蚀

4. Python实现

读入图片

载入依赖库:

import cv2         # 载入依赖库,用于图像处理
import os          # 载入依赖库,用于设置文件路径
import numpy as np # 载入依赖库,用于生成kernel

进行图片读取:

# 设置文件路径,类似R中的setwd()
os.chdir('E:/') 
# 读入图片
img = cv2.imread('bird.png') 

膨胀腐蚀

# 设置kernel,也可以利用getStructuringElement()函数指明它的形状
kernel = np.ones((5, 5), np.uint8) 
# 膨胀,iterations指的是腐蚀次数,省略是默认为1
dilation = cv2.dilate(img, kernel, iterations = 1)
# 腐蚀
erosion = cv2.erode(img, kernel)

查看与存储图片

显示图片(这里不推荐使用显示图片的代码,稍有不慎容易卡死,建议使用后面储存出来看图片):

cv2.imshow("dilation", dilation)
cv2.waitKey()
cv2.destroyAllWindows()

cv2.imshow("erosion", erosion)
cv2.waitKey()
cv2.destroyAllWindows()

存储图片:

cv2.imwrite("dilation.jpg", dilation)
cv2.imwrite("erosion.jpg", erosion)