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()
运行之后效果依次如下,从左到右分别是原图,二值化图,腐蚀图。
如果直接对原图进行腐蚀,效果并不十分明显。
如果调整腐蚀迭代次数参数,例如下述代码,图像将全部腐蚀完毕。
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()
最后还学到一些技术,例如在去噪声时先用腐蚀再用膨胀,也可以不进行灰度与二值化处理,直接对彩色图像进行腐蚀和膨胀,但是效果不是很理想。
膨胀的作用虽然还没有完全接触到,但是可以先记录下(腐蚀与其相反):
- 对象大小增加一个像素(3x3);
- 平滑对象边缘;
- 减少或者填充对象之间的距离。
相关阅读
技术专栏
- Python 爬虫 100 例教程,超棒的爬虫教程,立即订阅吧
- Python 爬虫小课,精彩 9 讲