Python OpenCV 图像的膨胀与腐蚀,图像处理取经之旅第 38 篇

Python OpenCV 365 天学习计划,与橡皮擦一起进入图像领域吧。本篇博客是这个系列的第 38 篇。
该系列文章导航参考:https://blog.csdn.net/hihell/category_10688961.html

基础知识铺垫

图像的腐蚀与膨胀是图像形态学运算的知识,形态学橡皮擦也是第一次接触到,寻找了一些简单的说明,基本含义是改变图像中物体的形状,一般在二值图中用来连接相邻的元素或分离成独立的元素,简单看一下说明,果然跟没学一样。

我们依旧先把腐蚀与膨胀应用层学会,掌握之后在去反推课程。

图像腐蚀(Erosion )

基本原理为:选择一个卷积核沿着图像移动,如果卷积核对应的原图像所有像素都是 1,那中心元素就保持原来的像素值,否则变为 0。

腐蚀图像需要传入两个内容,一个是二值图像,另一个就是卷积核了。

它可以断开图像中连接在一起的物体,该操作会导致前景物体会变小,整幅图像的白色区域会减少,直观的感觉就是原图中高亮部分被腐蚀掉了,然后图像区域变瘦了。

函数原型

图像腐蚀(erosion )的函数原型如下:

dst = cv2.erode(src, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]])

参数说明如下:

  • src:待腐蚀的二值图;
  • kernel:腐蚀操作的内核,默认是 3X3 矩阵,也可以使用 cv2.getStructuringElement 函数指明形状,下文具体说明;
  • anchor:核矩阵锚点,不传值或传值为 (-1,-1) 则取核矩阵的中心位置作为锚点;
  • iterations:腐蚀次数,默认为 1;
  • borderType

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)) :十字形结构。

测试代码如下,可以依据注释再次进行学习。

import cv2 as cv
import numpy as np

# 图像读取
src = cv.imread("./t2.png")
# 灰度图片
gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
# 二值化
ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY_INV | cv.THRESH_OTSU)
cv.imshow("binary", binary)
# 卷积核
kernel = np.ones((3, 3), np.uint8)

# 进行图像腐蚀,默认迭代 1 次
dst = cv.erode(binary, kernel)

# 图像显示
cv.imshow("src", src)
cv.imshow("dst", dst)

cv.waitKey(0)
cv.destroyAllWindows()

运行之后效果依次如下,从左到右分别是原图,二值化图,腐蚀图。

20210213225621781[1].png

如果直接对原图进行腐蚀,效果并不十分明显。

20210213225726627[1].png

如果调整腐蚀迭代次数参数,例如下述代码,图像将全部腐蚀完毕。

dst = cv.erode(binary, kernel,iterations=3)

图像膨胀(dilation )

有了腐蚀的概念之后,再学习膨胀就很容易理解了,这个是一对相反的概念。

膨胀就是用卷积核覆盖位置下,最大的像素替代中心位置的像素。

实现原理是:在卷积核的中心点逐个扫描原始图像中的每一个像素点时候,如果发现被扫描到的原始图像中的像素点有一个值为 1, 则为 1 ,否则为 0 ,膨胀可以用来连接两个分开的物体。

函数原型

dst = cv2.dilate(src, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]])

参数不在说明,与腐蚀内容一致。
使用下述代码运行之后,最终的图明显胖了一圈。

import cv2 as cv
import numpy as np


# 图像读取
src = cv.imread("./t2.png")
# 灰度图片
gray = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
# 二值化
ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY_INV | cv.THRESH_OTSU)

# 卷积核
kernel = np.ones((3, 3), np.uint8)

# 进行图像膨胀,默认迭代 1 次
dst = cv.dilate(binary, kernel)

# 图像显示
cv.imshow("src", src)
cv.imshow("binary", binary)

cv.imshow("dst", dst)

cv.waitKey(0)
cv.destroyAllWindows()
20210213230538428[1].png

最后还学到一些技术,例如在去噪声时先用腐蚀再用膨胀,也可以不进行灰度与二值化处理,直接对彩色图像进行腐蚀和膨胀,但是效果不是很理想。

膨胀的作用虽然还没有完全接触到,但是可以先记录下(腐蚀与其相反):

  • 对象大小增加一个像素(3x3);
  • 平滑对象边缘;
  • 减少或者填充对象之间的距离。

相关阅读


技术专栏

  1. Python 爬虫 100 例教程,超棒的爬虫教程,立即订阅吧
  2. Python 爬虫小课,精彩 9 讲

你可能感兴趣的:(Python OpenCV 图像的膨胀与腐蚀,图像处理取经之旅第 38 篇)