【Opencv入门到项目实战】(三):图像腐蚀与膨胀操作

2023-08-04 21:43:28

1.腐蚀操作

腐蚀操作是图像处理中常用的一种形态学操作,我们通常用于去除图像中的噪声、分割连通区域、减小目标物体的尺寸等。腐蚀操作的原理是,在给定的结构元素下,遍历图像的每个像素,并将其值替换为该像素周围邻域内像素的最小值。结构元素控制了腐蚀的邻域范围和形状。邻域内的任何一个像素为黑色(0),则中心像素也将被置为黑色(0)。这样可以缩小或消除二值图像中的前景目标。在OpenCV中,我们可以使用cv2.erode()来实现腐蚀操作

语法如下:

cv2.erode(src, kernel, iterations)

参数说明:

  • src:输入的二值图像,通常为单通道灰度图像。
  • kernel:腐蚀操作的结构元素,用于定义腐蚀的邻域大小和形状。可以使用 cv2.getStructuringElement() 函数创建不同形状的结构元素。
  • iterations:腐蚀操作的迭代次数,表示应用腐蚀的重复次数。

接下来我们先来看一张图:

img = cv2.imread('JOJO.png')

cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

image-20230801204803636

大家可以看到,除了JOJO之外,它的周围还有很多斜线,我们可以利用腐蚀操作来消除。

# 创建结构元素 (3x3 方框形)
kernel = np.ones((3, 3), dtype=np.uint8)

# 执行腐蚀操作
eroded = cv2.erode(img, kernel, iterations=1)

# 显示结果
cv2.imshow('Eroded Image', eroded)
cv2.waitKey(0)
cv2.destroyAllWindows()

image-20230801204932943

可以看到,这些斜线变得很浅,因为被他周围的黑色所影响,并且原始图像的字母也变得更小了,因为腐蚀操作减少了一部分信息。

我们可以更改iterations的值,来增加迭代次数,迭代的次数越多,则腐蚀的越严重,具体结果如下

erosion_1 = cv2.erode(img,kernel,iterations = 1)#1次迭代
erosion_2 = cv2.erode(img,kernel,iterations = 2)#2次迭代
erosion_3 = cv2.erode(img,kernel,iterations = 3)#3次迭代
res = np.hstack((erosion_1,erosion_2,erosion_3))#水平堆砌
# 显示结果
cv2.imshow('res', res)
cv2.waitKey(0)
cv2.destroyAllWindows()

image-20230801205203117

腐蚀操作和膨胀(Dilation)操作相对应,二者经常组合使用以实现更复杂的形态学图像处理任务,接下来我们来看看膨胀操作。

2.膨胀操作

说完了腐蚀操作之后,我们再来看一下它的逆操作,膨胀操作。我们在上面的腐蚀操作中,在消除噪声的同时,把有价值的信息也减少了。因此我们希望将这些有价值的信息增大,这样就要利用到膨胀操作。

在 OpenCV 中,膨胀操作是通过 cv2.dilate() 函数实现的。该函数接受三个参数:输入图像、结构元素和迭代次数。

结构元素可以通过 cv2.getStructuringElement() 函数创建,它定义了膨胀操作的邻域大小和形状。常见的结构元素形状包括矩形、椭圆和十字形

我们还是用刚刚的例子

# 原始图像
img = cv2.imread('JOJO.png')
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

image-20230801212242852

接下来我们使用腐蚀操作消除细线

# 腐蚀操作
kernel = np.ones((5,5),np.uint8) 
dige_erosion = cv2.erode(img,kernel,iterations = 1)

cv2.imshow('erosion', erosion)
cv2.waitKey(0)
cv2.destroyAllWindows()

image-20230801212546418

我们可以看见其中字母也变小了,我们想恢复其原始信息。

# 膨胀操作
kernel = np.ones((3,3),np.uint8) 
dige_dilate = cv2.dilate(dige_erosion,kernel,iterations = 1)

cv2.imshow('dilate', dige_dilate)
cv2.waitKey(0)
cv2.destroyAllWindows()

image-20230801212556084

膨胀操作的效果取决于结构元素的形状和大小,以及迭代次数。增加迭代次数会使目标物体区域更大,边界更粗糙。通常情况下,一个或两个迭代次数就足够了。

膨胀操作通常与腐蚀操作结合使用,以在图像中执行形态学处理。这种组合的方法称为开运算(Opening)和闭运算(Closing),接下来我们来看看如何实现

3.开运算和闭运算

开运算是先进行腐蚀操作,再进行膨胀操作。它主要用于去除图像中的噪点、小的干扰物或者分离连通的对象。

闭运算是先进行膨胀操作,再进行腐蚀操作。它主要用于填充图像中的小洞孔或者连接分离的对象。

开运算

opencv中,通过调用cv2.morphologyEx()函数,并指定操作类型为cv2.MORPH_OPEN,实现开运算

# 开:先腐蚀,再膨胀
img = cv2.imread('dige.png')

kernel = np.ones((5,5),np.uint8) 
opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)

cv2.imshow('opening', opening)
cv2.waitKey(0)
cv2.destroyAllWindows()

image-20230801214242345

可以看到开运算可以让我们先去除边缘细线,然后再增加信息恢复到原始结果。

闭运算

opencv中,通过调用cv2.morphologyEx()函数,并指定操作类型为cv2.MORPH_CLOSE,实现闭运算

# 闭:先膨胀,再腐蚀
img = cv2.imread('JOJO.png')

kernel = np.ones((5,5),np.uint8) 
closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)

cv2.imshow('closing', closing)
cv2.waitKey(0)
cv2.destroyAllWindows()


image-20230801215925376

在闭运算中,由于一开始我们加粗了边缘细线,导致后续我们即使做了腐蚀操作也不能完全去除。

这两种方法可以用来改善图像的质量、去除噪声或者填充空洞,具体根据我们的需求进行更改。

4.礼帽与黑帽

  • 礼帽 = 原始输入-开运算结果
  • 黑帽 = 闭运算-原始输入

通过使用礼帽和黑帽操作,可以突出图像中细微的亮或暗结构,或者检测背景中的亮或暗区域。

礼帽操作

opencv中,我们通过调用 cv2.morphologyEx() 函数,并指定操作类型为 cv2.MORPH_TOPHAT,执行礼帽操作

#礼帽
img = cv2.imread('JOJO.png')
tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)
cv2.imshow('tophat', tophat)
cv2.waitKey(0)
cv2.destroyAllWindows()

黑帽操作

黑帽操作是礼帽操作的相反过程,用于突出图像中微小结构或背景中的暗区域。在Opencv中,通过调用 cv2.morphologyEx() 函数,并指定操作类型为cv2.MORPH_BLACKHAT,执行黑帽操作。

#黑帽
img = cv2.imread('JOJO.png')
blackhat  = cv2.morphologyEx(img,cv2.MORPH_BLACKHAT, kernel)
cv2.imshow('blackhat ', blackhat )
cv2.waitKey(0)
cv2.destroyAllWindows()

image-20230801221528105

5.梯度运算

  • 梯度 = 膨胀-腐蚀

首先,我们分别实现膨胀和腐蚀操作

# 梯度=膨胀-腐蚀
img = cv2.imread('JOJO.png')
kernel = np.ones((5,5),np.uint8) 
dilate = cv2.dilate(img,kernel,iterations = 1)
erosion = cv2.erode(img,kernel,iterations = 1)

res = np.hstack((dilate,erosion))

cv2.imshow('res', res)
cv2.waitKey(0)
cv2.destroyAllWindows()

image-20230801214951601

接下来我们实现梯度运算

# 梯度运算
gradient = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)

cv2.imshow('gradient', gradient)
cv2.waitKey(0)
cv2.destroyAllWindows()

image-20230801214854244

大家可以看出这个图片就是用膨胀操作-腐蚀操作的结果。

🔎本章的介绍到此介绍,如果文章对你有帮助,请多多点赞、收藏、评论、订阅支持!!《Opencv入门到项目实战》

更多推荐

举例说明用 easylanguage 语言,编写抄底公式

EasyLanguage语言在金融领域被广泛使用,尤其是用于编写交易策略和算法。以下是一个简单的抄底公式示例:swift复制//定义变量和参数DimStopLossPriceAsDoubleDimTakeProfitPriceAsDoubleDimInitialPositionAsDoubleDimSafetyZone

网络基础(一)

网络基础(一)在本篇文章中,我会详细介绍网络的一些基础知识,之后也会有持续的更新来帮助大家学习网络,希望大家可以通过博客学到更多的知识!了解网络去百度查询可以知道,网络是由若干节点和连接这些节点的链路构成的,表示诸多对象及其相互之间的联系。那么网络在我们生活中起到了举足轻重的作用,我们平时的一系列上网行为都离不开网络,

R语言CalibrationCurves包绘制带可信区间的校准曲线

校准曲线图表示的是预测值和实际值的差距,作为预测模型的重要部分,目前很多函数能绘制校准曲线。一般分为两种,一种是通过Hosmer-Lemeshow检验,把P值分为10等分,求出每等分的预测值和实际值的差距。一种是绘制连续的校准曲线。我们既往已经通过多篇文章介绍了校准曲线绘制,连续的和等分的都有介绍,今天咱们来介绍一下C

群体智能的实现与优化: 使用Metal技术在Swift中打造高效模型

1.群体智能简介群体智能是自然选择过程中形成的一种智能行为。你可以在鸟群飞翔、蚂蚁觅食、鱼群游动中看到这种行为。它们没有集中的控制中心,但却能通过局部互动实现整体的协同。这种行为为许多现代算法,如粒子群优化(PSO)和蚁群算法(ACO)提供了灵感。在这篇文章中,我们将探讨如何利用Apple的Metal技术,在Swift

【CSS3】CSS3 动画 ⑥ ( 动画属性示例 | 精灵图帧动画效果实现 )

文章目录一、需求说明二、代码分析1、动画属性2、布局分析3、动画实现三、完整代码示例一、需求说明给定一张精灵图,其中有多个动画帧对应的图片,下图的大小是1600x100像素,截图展示如下:实际图片:二、代码分析1、动画属性使用上图实现逐帧动画效果;实现逻辑是设置元素的animation-timing-function动

【CSS3】CSS3 3D 转换 ① ( CSS3 3D 转换简介 | 3D 物体与 2D 物体区别 | 3D 空间坐标系 | 常用的 3D 转换属性 | 3D 位移转换语法 | 代码示例 )

文章目录一、CSS33D转换简介1、3D物体与2D物体区别2、2D平面坐标系3、3D空间坐标系4、常用的3D转换属性二、3D位移转换1、3D位移转换语法2、代码示例分析三、代码示例1、代码示例-没有进行3D平移的参考示例代码示例执行结果2、代码示例-3D平移示例代码示例执行结果3、代码示例-3D平移简写形式示例代码示例

软件测试需求分析

1.1需求的重要性1.1.1软件缺陷的8020原则1)在软件测试过程中,从需求分析开始到集成测试阶段引入测试手段,能发现所有缺陷的80%;系统测试阶段引入测试手段,能发现剩余缺陷中80%的缺陷;在运行维护阶段经过长时间、大量运行软件后,能够发现最后剩余的20%的缺陷。1.2软件需求1.2.1软件需求的定义1)IEE软件

【错误记录】exe4j 打包程序无法设置 jar 包依赖的问题 ( 将源码 和 依赖库打包到同一个 jar 包中 )

文章目录一、问题描述二、解决方案一、问题描述在【错误记录】IntelliJIDEA导出可执行jar包执行报错(java.lang.ClassNotFoundException|打包时没有选择依赖库)博客中遇到java.lang.ClassNotFoundException:com.microsoft.sqlserver

【错误记录】Android Studio 中 Kotlin 版本报错 ( Module was compiled with an incompatible version of Kotlin. T )

文章目录一、报错信息二、问题分析三、解决方案1、低版本Gradle配置2、高版本Gradle配置一、报错信息在AndroidStudio中,编译应用,报如下错误:C:/Users/octop/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-s

设计模式Java实战

文章目录一、前置1.1目的1.2面向对象1.3接口和抽象类二、七大设计原则2.1单一职责2.2接口隔离原则2.3依赖倒转原则2.4里氏替换原则2.5开闭原则2.6不要重复原则2.7迪米特最少知道法则三、23种设计模式3.1创建型:创建对象3.1.1单例模式定义最佳实践场景线程级别的单例缺点3.1.2工厂模式(简单工厂)

DolphinDB x 龙蜥社区,打造多样化的数据底座

近日,浙江智臾科技有限公司(以下简称“DolphinDB”)正式签署CLA贡献者许可协议,加入龙蜥社区(OpenAnolis)。DolphinDB主创团队从2012年开始投入研发产品。作为一款基于高性能时序数据库,DolphinDB支持复杂分析与流处理的实时计算平台,集成了功能强大的编程语言和高吞吐率的流数据分析系统,

热文推荐