OpenCV-膨胀、腐蚀与形态学操作

本文详细介绍了OpenCV中的形态学操作,包括膨胀和腐蚀的基本概念及其作用,如去除噪声、平滑边缘和改变物体大小。通过示例展示了如何使用cv2.dilate和cv2.erode函数进行膨胀和腐蚀操作,并探讨了开运算、闭运算、顶帽和黑帽等高级形态学操作,以及它们在图像处理中的应用,如背景提取和边缘检测。
摘要由CSDN通过智能技术生成

膨胀与腐蚀

膨胀

与卷积核对应的原图像的像素值中只要有一个是1,中心元素的像素值就是1。会增加图像中的白色区域(前景)。一般在去噪声时先用腐蚀再用膨胀。因为腐蚀在去掉白噪声的同时,也会使前景对象变小。所以我们再对他进行膨胀。这时噪声已经被去除了,不会再回来了,但是前景还在并会增加。

作用:

  1. 对象的大小增加一个像素(3×3)
  2. 平滑对象边缘
  3. 减少或填充对象之间的边缘

cv2.dilate

使用特定的结构元素膨胀图像

dilate(src, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]]) -> dst
  • src:表示输入的图片
  • kernel:表示膨胀所用的结构元素的大小
  • iteration:表示迭代的次数

示例

对图像二值化并膨胀

def dilate(image):
    """膨胀"""
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)  # 二值化图像
    cv.imshow("binary", binary)

    # 构造5×5的结构元素,可选十字形、菱形、方形和X型等
    kernel = cv.getStructuringElement(cv.MORPH_RECT, (5, 5))  # 构造5×5的方形结构元素
    dst = cv.dilate(binary, kernel=kernel)  # 膨胀
    cv.imshow("dilate", dst)

结果
在这里插入图片描述
注意: 二值化图像的膨胀和腐蚀要注意是白色还是黑色作为前景

示例

对彩图进行膨胀

def dilate_color(image):
    """彩图膨胀"""
    kernel = cv.getStructuringElement(cv.MORPH_RECT, (5, 5))  # 构造5×5的方形结构元素
    dst = cv.dilate(image, kernel=kernel)  # 膨胀
    cv.imshow("dilate", dst)

结果:
在这里插入图片描述

腐蚀

卷积核沿着图像滑动,如果与卷积核对应的原图像的所有像素值都是1,那么中心元素就保持原来的像素值,否则就变为零。 根据卷积核的大小靠近前景的所有像素都会被腐蚀掉(变为0),所以前景物体会变小,整幅图像的白色区域会减少。

作用:

  1. 对象的大小减少一个像素(3×3)
  2. 平滑对象边缘
  3. 弱化或者分割对象之间的半岛型连接

cv2.erode

使用特定的结构元素腐蚀图像

erode(src, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]]) -> dst
  • src:表示输入的图片
  • kernel:表示腐蚀所用的结构元素的大小
  • iteration:表示迭代的次数

示例

对图像二值化并腐蚀

def erode(image):
    """腐蚀"""
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)  # 二值化图像
    cv.imshow("binary", binary)

    # 构造5×5的结构元素,可选十字形、菱形、方形和X型等
    kernel = cv.getStructuringElement(cv.MORPH_RECT, (5, 5))  # 构造5×5的方形结构元素
    dst = cv.erode(binary, kernel=kernel)  # 腐蚀
    cv.imshow("erode", dst)

结果
在这里插入图片描述

示例

对彩图进行腐蚀

def erode_color(image):
    """彩图腐蚀"""
    kernel = cv.getStructuringElement(cv.MORPH_RECT, (5, 5))  # 构造5×5的方形结构元素
    dst = cv.erode(image, kernel=kernel)  # 腐蚀
    cv.imshow("erode", dst)

结果
在这里插入图片描述

参考链接:

形态学操作

cv2.morphologyEx

执行形态学操作

  • 开运算:先进行腐蚀再进行膨胀就叫做开运算,它被用来去除噪声。
  • 闭运算:先膨胀再腐蚀。它经常被用来填充前景物体中的小洞,或者前景物体上的小黑点。
  • 顶帽:原图像与开操作之间的差值图像
  • 黑帽:闭操作与原图像之间的差值图像
  • 形态学梯度:其实就是一幅图像膨胀与腐蚀的差别。 结果看上去就像前景物体的轮廓
  • 基本梯度:膨胀后图像减去腐蚀后图像得到的差值图像。
  • 内部梯度:用原图减去腐蚀图像得到的差值图像。
  • 外部梯度:膨胀后图像减去原图像得到的差值图像
morphologyEx(src, op, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]]) -> dst
  • src:输入图像
  • op:操作类型
    • MORTH_OPEN:函数做开运算
    • MORTH_CLOSE:函数做闭运算
    • MORTH_GRADIENT:函数做形态学梯度运算
    • MORTH_TOPHAT:函数做顶帽运算
    • MORTH_BLACKHAT:函数做黑帽运算
    • MORTH_DILATE :函数做膨胀运算
    • MORTH_ERODE:函数做腐蚀运算
  • kernel :内核类型,用getStructuringElement函数得到。
    • 例如:采用开操作,kernel为(1, 15),提取垂直线,kernel为(15, 1),提取水平线

开操作

先进行腐蚀再进行膨胀就叫做开运算,它被用来去除噪声。

示例

开操作

def open_image(image):
	"""开操作"""
    # print(image.shape)
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY_INV | cv.THRESH_OTSU)  # 二值化图像
    cv.imshow("binary", binary)

    kernel = cv.getStructuringElement(cv.MORPH_RECT, (5, 5))  # 构造5×5的方形结构元素
    dst = cv.morphologyEx(binary, cv.MORPH_OPEN, kernel=kernel)  # 执行形态学操作(此时为开操作)
    cv.imshow("open_image", dst)

结果
在这里插入图片描述

闭操作

先膨胀再腐蚀。它经常被用来填充前景物体中的小洞,或者前景物体上的小黑点。

示例

闭操作

def close_image(image):
	"""闭操作"""
    # print(image.shape)
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)  # 二值化图像
    cv.imshow("binary", binary)

    kernel = cv.getStructuringElement(cv.MORPH_RECT, (5, 5))  # 构造5×5的方形结构元素
    dst = cv.morphologyEx(binary, cv.MORPH_CLOSE, kernel=kernel)  # 执行形态学操作(此时为闭操作)
    cv.imshow("close_image", dst)

结果:
在这里插入图片描述

顶帽

原图像与开操作之间的差值图像
d s t = t o p h a t ( s r c , r l r m e n t ) = s r c − o p e n ( s r c , r l r m e n t ) dst = tophat(src,rlrment) = src - open(src,rlrment) dst=tophat(src,rlrment)=srcopen(src,rlrment)

因为开运算带来的结果是放大了裂缝或者局部低亮度的区域,因此,从原图中减去开运算后的图,得到的效果图突出了比原图轮廓周围的区域更明亮的区域,且这一操作和选择的核的大小相关。

顶帽运算往往用来分离比邻近点亮一些的斑块。当一幅图像具有大幅的背景的时候,而微小物品比较有规律的情况下,可以使用顶帽运算进行背景提取。

示例

def tophat_image(image):
    """顶帽操作"""
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    kernel = cv.getStructuringElement(cv.MORPH_RECT, (5, 5))  # 构造5×5的方形结构元素
    dst = cv.morphologyEx(gray, cv.MORPH_TOPHAT, kernel=kernel)  # 执行形态学操作(此时为顶帽操作)
    cv.imshow("tophat_image", dst)

结果:
在这里插入图片描述

示例

直接二值化图像
在这里插入图片描述
发现右下角细节缺失

发现原图右下角的字体与背景的亮度都有些高,所以会出现这种情况,现在想让字体与背景分离出来,我们可以用顶帽操作对前景进行明亮化。

因此先进行顶帽再二值化

def comprehensive_example(image):
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    cv.imshow("gray", gray)
    kernel = cv.getStructuringElement(cv.MORPH_RECT, (30, 30))  # 构造30×30的方形结构元素
    dst = cv.morphologyEx(gray, cv.MORPH_TOPHAT, kernel=kernel)  # 执行形态学操作(此时为顶帽操作)
    cv.imshow("tophat_image", dst)
    ret, binary = cv.threshold(dst, 0, 255, cv.THRESH_BINARY_INV | cv.THRESH_OTSU)  # 二值化图像
    cv.imshow("binary", binary)

结果:
在这里插入图片描述

黑帽

闭操作与原图像之间的差值图像
d s t = b l a c k h a t ( s r c , r l r m e n t ) = c l o s e ( s r c , r l r m e n t ) − s r c dst = blackhat(src,rlrment) = close(src,rlrment) - src dst=blackhat(src,rlrment)=close(src,rlrment)src

黑帽运算后的效果图突出了比原图轮廓周围的区域更暗的区域,且这一操作和选择的核的大小相关。

所以,黑帽运算用来分离比邻近点暗一些的斑块。可以得到轮廓效果图。

示例

def blackhat_image(image):
    """黑帽操作"""
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    kernel = cv.getStructuringElement(cv.MORPH_RECT, (5, 5))  # 构造5×5的方形结构元素
    dst = cv.morphologyEx(gray, cv.MORPH_BLACKHAT, kernel=kernel)  # 执行形态学操作(此时为黑帽操作)
    cv.imshow("blackhat_image", dst)

结果:
在这里插入图片描述

形态学梯度

本质上就是对图像的边缘提取,也可以说是膨胀的结果减去腐蚀的结果

示例

def gardient_image(image):
    """形态学梯度操作"""
    gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
    kernel = cv.getStructuringElement(cv.MORPH_RECT, (5, 5))  # 构造5×5的方形结构元素
    dst = cv.morphologyEx(gray, cv.MORPH_GRADIENT, kernel=kernel)  # 执行形态学操作(此时为形态学梯度操作)
    cv.imshow("blackhat_image", dst)

结果:
在这里插入图片描述

参考链接:

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

咬着棒棒糖闯天下

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值