OpenCV-Python(17):图像形态学操作

目录

目标

形态学处理原理

腐蚀

原理

效果

影响

示例

膨胀

原理

效果

作用

开运算

闭运算

形态学梯度

礼帽

黑帽

形态学操作之间的关系

结构化元素

更多参考


背景说明

        形态学操作是图像处理中常用的一种操作,主要用于对图像进行形状和结构的改变。形态学操作常用于图像的降噪、边缘检测、图像分割等方面。在OpenCV中,形态学操作可以通过cv2模块中的函数来实现。

目标

  • 学习不同的形态学操作,例如膨胀、腐蚀、开运算、闭运算
  • 我们学习的函数有cv2.erode()、cv2.dilate()、cv2.morphologyEx()

形态学操作原理

        形态学操作是根据图像形状的简单操作。一般情况下对二值化图像的操作。需要输入两个参数,一个是原始图像,第二个称为结构化元素或核,它是用来决定操作的性的。两个基本的形态学操作是腐蚀和膨胀。他们的变体构成了开运算,闭运算、梯度等。我们会以下图为例来介绍它们。(白色是前景色,黑色是背景色)


腐蚀

原理

        卷积核沿着图像滑动如果与卷积核对应的原图像的所有像素值是 1,那么中心元素就保持原来的像素值,否则就变为0。 

效果

        就像土壤腐蚀一样,该操作会把前景物体的边界腐蚀掉(但是前景色仍然是白色),边界会变得更加清晰。

影响

        根据卷积核的大小,靠近前景色的所有像素都会腐掉变为0,所以前景物体会变小,整幅图像的白色区域会减少。对于去白噪声很有用,也可以用来断开两个连在一块的物体等。 

示例

        我们下面这个例子使用一个 5x5 的卷积核,其中所有的值是默认。 我们看看他是如何工作的。所用函数为:cv2.erode(),该函数接受两个参数:输入图像和腐蚀的核大小。

import cv2 
import numpy as np
img = cv2.imread('j.png',0) 
kernel = np.ones((5,5),np.uint8) 
erosion = cv2.erode(img,kernel,iterations = 1)

结果:

膨胀

原理

        与腐蚀相反,与卷积核对应的原图像的像素值中只要有一个是 1,中心元素的像素值就是 1。

效果

        该操作会增加图像中的白色区域前景,使边界变得模糊。

作用

        实际图像处理中先用腐蚀再用膨胀可以去除噪声。因为腐蚀在去掉白噪声的同时也会使前景相对变小,所以我们再对它膨胀,此时噪声已经去除了,不会再回来了,但是前景还在并会增加。膨胀也可以用来连接两个分开的物体。所用函数为:cv2.dilate(),该函数接受两个参数:输入图像和膨胀的核大小。

dilation = cv2.dilate(img,kernel,iterations = 1)

结果:

开运算

        先进行腐蚀再膨胀就叫做开算。就像我们上介绍的样它用来去噪声。我们用到的函数是 cv2.morphologyEx(),该函数接受三个参数:输入图像、操作类型(cv2.MORPH_OPEN)和运算核大小。

opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)

结果:

闭运算

        先膨胀再腐蚀。它经常用来填充前景物体中的小洞或者前景物体上的小点。该函数接受三个参数:输入图像、操作类型(cv2.MORPH_CLOSE)和运算核大小。

closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)

形态学梯度

        图像形态学梯度是一种形态学操作,它可以用来检测图像中的边缘或轮廓。形态学梯度可以通过膨胀和腐蚀操作之间的差异来计算,(其实就是一幅图像膨胀与腐的差别) 结果看上去就像前景物体的轮廓

形态学梯度的作用包括:

1.边缘检测:形态学梯度可以用来检测图像中的边缘或轮廓。由于形态学梯度突出了图像中的边界区域,因此在图像分割、目标检测等领域有广泛应用。

2.物体测量:形态学梯度可以用来测量物体的大小、形状和结构。通过计算形态学梯度,可以获取物体的边界信息,并进一步进行物体测量和分析。

3.形态学重建:形态学梯度可以用来进行形态学重建操作。形态学重建是一种基于形态学操作的图像处理技术,用于从图像中提取感兴趣的对象或区域。

4.形态学滤波:形态学梯度可以用来进行图像的滤波操作。通过选择合适的结构元素,可以实现对图像中的噪声或干扰的去除。

5.图像增强:形态学梯度可以用来增强图像的边缘或轮廓,从而使图像更加清晰和鲜明。

gradient = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)

礼帽

        原始图像与开运算之后得到的图像的差。主要实际应用场景如下:

  • 检测亮区域:礼帽运算可以用来检测图像中的亮区域或亮斑。亮区域可能是图像中的目标物体、光源或者其他特定区域。
  • 表面缺陷检测:礼帽运算可以用来检测表面缺陷,如划痕、凹陷等。通过与原始图像进行比较,可以突出表面缺陷的区域。
  • 细胞核分析:在细胞核分析中,礼帽运算可以用来检测细胞核的亮区域,并进一步进行细胞核的分割和分析。

下的例子是用一个 9x9 的 核礼帽操作的结果。

tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)

黑帽

进行闭运算之后得到的图像与原始图像的差。主要用途如下:

  • 检测暗区域:黑帽运算可以用来检测图像中的暗区域或暗斑。暗区域可能是图像中的阴影、污渍或者其他特定区域。
  • 文字图像分割:在文字图像分割中,黑帽运算可以用来检测文字的阴影或背景干扰。通过与原始图像进行比较,可以突出文字区域。
  • 血管分割:在医学图像处理中,黑帽运算可以用来分割血管。血管通常呈现为暗区域,通过黑帽运算可以突出血管的形状和位置
blackhat = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)

形态学操作之间的关系

结构化元素

        在前的例子中我们使用 Numpy 构建的结构化元素它是正方形的。 有时我们需要构建一个椭圆形/圆形的核。为了实现这种需求。OpenCV 提供了函数 cv2.getStructuringElement()。你只告他你的核的形状和大小就可以。

# Rectangular Kernel
>>> cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))
array([[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1]], dtype=uint8)

# Elliptical Kernel
>>> cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))
array([[0, 0, 1, 0, 0],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[0, 0, 1, 0, 0]], dtype=uint8)

# Cross-shaped Kernel
>>> cv2.getStructuringElement(cv2.MORPH_CROSS,(5,5))
array([[0, 0, 1, 0, 0],
[0, 0, 1, 0, 0],
[1, 1, 1, 1, 1],
[0, 0, 1, 0, 0],
[0, 0, 1, 0, 0]], dtype=uint8)

更多参考

详细学习地点可以参考:https://homepages.inf.ed.ac.uk/rbf/HIPR2/morops.htm

下面是一个使用形态学操作的综合示例代码:

import cv2
import numpy as np

# 读取图像
image = cv2.imread("image.jpg", 0)

# 创建一个 5x5 的腐蚀核
kernel = np.ones((5, 5), np.uint8)

# 腐蚀操作
erosion = cv2.erode(image, kernel, iterations=1)

# 膨胀操作
dilation = cv2.dilate(image, kernel, iterations=1)

# 开运算操作
opening = cv2.morphologyEx(image, cv2.MORPH_OPEN, kernel)

# 闭运算操作
closing = cv2.morphologyEx(image, cv2.MORPH_CLOSE, kernel)

# 显示结果
cv2.imshow("Erosion", erosion)
cv2.imshow("Dilation", dilation)
cv2.imshow("Opening", opening)
cv2.imshow("Closing", closing)
cv2.waitKey(0)
cv2.destroyAllWindows()

        在上述代码中,首先使用cv2.imread函数读取一张灰度图像,然后创建一个 5x5 的腐蚀核,接着分别使用cv2.erode、cv2.dilate、cv2.morphologyEx函数实现腐蚀、膨胀、开运算、闭运算操作。最后,使用cv2.imshow函数显示结果,并使用cv2.waitKey和cv2.destroyAllWindows函数来保持图像窗口的显示。

要检测并提取亮斑区域,可以使用以下步骤: 1. 读取图像并转换为灰度图像。 2. 对灰度图像进行滤波处理,可以使用高斯滤波或中值滤波。 3. 对滤波后的图像进行二值化处理,可以使用自适应阈值或固定阈值。 4. 对二值化后的图像进行形态学处理,可以使用开运算或闭运算,以去除噪声和填补空洞。 5. 使用轮廓检测算法,如cv2.findContours()函数,来检测图像中的亮斑区域。 6. 对检测到的亮斑区域进行提取,可以使用cv2.drawContours()函数来绘制轮廓或cv2.boundingRect()函数来获取包围矩形。 以下是一个示例代码: ```python import cv2 # 读取图像并转换为灰度图像 img = cv2.imread('image.jpg') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 高斯滤波和自适应阈值二值化 blur = cv2.GaussianBlur(gray, (5, 5), 0) thresh = cv2.adaptiveThreshold(blur, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2) # 开运算和闭运算 kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3)) opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel) closing = cv2.morphologyEx(opening, cv2.MORPH_CLOSE, kernel) # 轮廓检测 contours, hierarchy = cv2.findContours(closing, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 提取亮斑区域 for contour in contours: x, y, w, h = cv2.boundingRect(contour) cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2) # 显示结果 cv2.imshow('Result', img) cv2.waitKey(0) cv2.destroyAllWindows() ``` 在这个示例中,我们首先读取图像并将其转换为灰度图像。然后使用高斯滤波和自适应阈值二值化来减少噪声和提高亮斑区域的对比度。接下来使用开运算和闭运算来进一步去除噪声并填补空洞。最后使用轮廓检测算法来检测亮斑区域,并使用cv2.boundingRect()函数来获取包围矩形。最终将结果显示在图像上。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

图灵追慕者

您的支持是我写作分享最大动力!

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

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

打赏作者

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

抵扣说明:

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

余额充值