第三章-OpenCV基础-7-形态学

news2024/11/16 17:34:55

前置

形态学主要是从图像中提取分量信息,该分量信息通常是图像理解时所使用的最本质的形状特征,对于表达和描绘图像的形状有重要意义。

大体就是通过一系列操作让图像信息中的关键信息更加凸出。同时,形态学的操作都是基于灰度图进行。

相关操作最主要的2种操作为腐蚀/膨胀,后面又延伸了综合操作-开运算/闭运算/形态学梯度/礼帽/黑帽等等。

腐蚀

腐蚀是最基本的形态学操作之一,能够去除图像的边界点,使图像沿着边界向内收缩,对于小于指定结构元的部分会去除。

所以,通过腐蚀可以达到去除一些外部噪音、元素分割等功能。

腐蚀原理说明 :

结构元 : 就是拥有一个中心位置并且有一定范围的结构,说白了就是一个二维数组。

扫描图像中的每一个像素点,结构元和扫描点重合,用结构元元素与覆盖的二值图做"与"运算,都为1则图像的像素值不变,否则改为0。

图示如下:

a图为原图,b图为结构元,当扫描到第2行,由于第一行存在2/3/4列的数据为0,所以经过腐蚀后,第2行的2/3/4列的1都变成了0,同理第4行。

扫描到第三行的2/3/4列时,由于都是1,第3行的2/3/4列分别不变,最终结果如d图所示。

函数语法说明: dst = cv2.erode( src,kernel,anchor,iterations,borderType,borderValue)

  • kernel : 腐蚀时使用的结构体,可以自己生成,也可以通过cv2.getStructuringElement()生成,就是个二维数组空间
  • anchor : 锚点位置,默认为(-1,-1),在核的中心位置
  • iterations : 腐蚀操作迭代次数,默认为1,只进行1次腐蚀操作
  • borderType : 边界处理方式,一般采用默认BORDER_CONSTANT
  • borderValue : 边界填充值,一般采用默认值

所以经常简化为 dst = cv2.erode( src ,kernel )

程序实例如下:

import cv2 as cv
import numpy as np

origin = cv.imread("erode.bmp")
# 使用了一个3*3的结构元,结构元面积越大,腐蚀的越厉害,结果图就越小
kernel_3 = np.ones((3, 3), np.uint8)

# 不大明显,但有些触角已经变短了
erode_3 = cv.erode(origin, kernel_3)
# 反复刷了三次,图像进一步腐蚀减小,边角已经腐蚀掉了
erode_3_3 = cv.erode(origin, kernel_3, iterations=3)

cv.imshow("origin", origin)
cv.imshow("erode_3", erode_3)
cv.imshow("erode_3_3", erode_3_3)

cv.waitKey()
cv.destroyAllWindows()

运行结果如下:

 膨胀

膨胀操作同样是形态学的一种基本操作,膨胀和腐蚀的作用是相反的,膨胀操作能对边界进行扩张。膨胀操作可以将较近的2个对象连通在一起,也有利于填补

图片分割后图像内的空白处。

膨胀原理说明:

使用结构元扫描图像中的每一个像素点,结构元和扫描点重合,用结构元元素与覆盖的二值图做"与"运算,都为0则图像的像素值为0,否则改为1,这样图片边缘位置就会紧跟结构元进行扩张。

函数语法说明: dst = cv2.dilate( src ,kernel,anchor,iterations,borderType,borderValue)

函数参数与腐蚀参数完全一致,不做过多解释。方法可以简化为 dst = cv2.dilate( src,kernel )

程序实例如下:

import cv2 as cv
import numpy as np

origin = cv.imread("dilation.png")
# 使用了一个3*3的结构元,结构元面积越大,膨胀的越厉害,结果图就越大
kernel = np.ones((3, 3), np.uint8)
erode_3 = cv.dilate(origin, kernel)
# 连续膨胀3次
erode_3_3 = cv.dilate(origin, kernel, iterations=9)
cv.imshow("origin", origin)
cv.imshow("dilation_3", erode_3)
cv.imshow("dilation_3_3", erode_3_3)

cv.waitKey()
cv.destroyAllWindows()

运行如下:

 

开运算

开运算是先进行腐蚀操作,后再进行膨胀操作。进行腐蚀操作可以把图像中目标外的噪声去掉,膨胀后再恢复目标的大小。

函数语法说明: dst = cv2.morphologyEx( src,cv2.MORPH_OPEN,kernel)

src,dst分别是原始图像和处理后的结果图像

cv2.MORPH_OPEN : 做开运算的标识

kernel : 运算使用的结构元

程序如下:

import cv2 as cv
import numpy as np

origin = cv.imread("open_pic.png", 0)
kernel = np.ones((5, 5), np.uint8)
open_pic = cv.morphologyEx(origin, cv.MORPH_OPEN, kernel) # 开运算
cv.imshow("origin", origin)
cv.imshow("open", open_pic)

cv.waitKey()
cv.destroyAllWindows()

运行如下:

 

闭运算

闭运算是先进行膨胀操作,后再进行腐蚀操作。主要针对情景为图像中关键信息内部有小洞,膨胀操作会填充小洞。

函数语法说明: dst = cv2.morphologyEx( src,cv2.MORPH_CLOSE,kernel)

闭运算和开运算使用一样的函数,仅通过标识不同来实现不同操作。

cv2.MORPH_OPEN : 做闭运算的标识

程序如下:

import cv2 as cv
import numpy as np

origin = cv.imread("close_pic.png", 0)
kernel = np.ones((5, 5), np.uint8)
open_pic = cv.morphologyEx(origin, cv.MORPH_CLOSE, kernel) # 闭运算
cv.imshow("origin", origin)
cv.imshow("open", open_pic)

cv.waitKey()
cv.destroyAllWindows()

运行结果如下:

 

形态学梯度

其实就是一副图像膨胀和腐蚀的差别,看起来就是前景物体的轮廓。

函数语法说明:dst = cv2.morphologyEx( src,cv2.MORPH_GRADIENT,kernel)

函数同开闭运算一样,只有样式不一样。

cv2.MORPH_GRADIENT : 形态学梯度的关键字

程序如下:

import cv2 as cv
import numpy as np

origin = cv.imread("abcdefg.png")
kernel = np.ones((5, 5), np.uint8)
open_pic = cv.morphologyEx(origin, cv.MORPH_GRADIENT, kernel)  # 形态学梯度
cv.imshow("origin", origin)
cv.imshow("gradient", open_pic)

cv.waitKey()
cv.destroyAllWindows()

效果图如下:

 

礼帽

开运算是先腐蚀再膨胀,会消除图像中的噪声,而礼帽是原始图片与进行开运算后的得到的图像的差,也就是消除掉的噪声。

函数语法说明: dst = cv2.morphologyEx( src,cv2.MORPH_TOPHAT,kernel)

import cv2 as cv
import numpy as np

origin = cv.imread("open_pic.png")
kernel = np.ones((5, 5), np.uint8)
open_pic = cv.morphologyEx(origin, cv.MORPH_TOPHAT, kernel)  # 礼帽
cv.imshow("origin", origin)
cv.imshow("tophat", open_pic)

cv.waitKey()
cv.destroyAllWindows()

运行如下:

 

黑帽

闭运算是先膨胀再腐蚀,具有填充内部小洞的功能,而黑帽是进行闭运算得到的图片与原始图像的差,所以显示的是之前补上的小洞图片。

函数语法说明: dst = cv2.morphologyEx( src,cv2.MORPH_BLACKHAT,kernel)

程序如下:

import cv2 as cv
import numpy as np

origin = cv.imread("close_pic.png")
kernel = np.ones((5, 5), np.uint8)
open_pic = cv.morphologyEx(origin, cv.MORPH_BLACKHAT, kernel)  # 黑帽
cv.imshow("origin", origin)
cv.imshow("blackhat", open_pic)

cv.waitKey()
cv.destroyAllWindows()

运行如下:

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/381295.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Filebeat处理多行换行的问题

问题:在使用filebeatelabscience或者filebeatelk 又或者其他桥接器的时候,因为filbeat默认使用单行显示的原因,但日志出现堆栈错误或其他多行日志时会出现如下错误处理办法:1.固定日志格式 这里不展开说明2.匹配日志 找到你的file…

【Flutter入门到进阶】Flutter基础篇---布局

1 GridView网格布局组件 1.1 说明 1.1.1 图例 1.1.2 说明 GridView网格布局在实际项目中用的也是非常多的,当我们想让可以滚动的元素使用矩阵方式排列的时 候。此时我们可以用网格列表组件GridView实现布局 GridView创建网格列表主要有下面三种方式 1、可以通过Gr…

纳睿雷达在科创板上市:总市值达93亿元,2022年营收约2亿元

3月1日,广东纳睿雷达科技股份有限公司(下称“纳睿雷达”,SH:688522)在科创板上市。本次上市,纳睿雷达的发行价为46.68元/股,发行数量为3866.68万股,募资总额约为18.05亿元。 上市首日&#xff…

关于“腺样体面容”的两大认知误区,你需要了解一下

仅供医学专业人士阅读参考看完不要再中招了!随着父母越来越重视孩子的外表和健康成长,“腺样脸”几乎成为聚会上不可避免的热门话题。在各种交流和讨论中,你经常听到朋友焦虑有点高兴地说:“虽然我的孩子总是张嘴睡觉,…

pandas: 三种算法实现递归分析Excel中各列相关性

目录 前言 目的 思路 代码实现 1. 循环遍历整个SDGs列,两两拿到数据 2. 调用pandas库函数直接进行分析 完整源码 运行效果 总结 前言 博主之前刚刚被学弟邀请参与了2023美赛,这也是第一次正式接触数学建模竞赛,现在已经提交等待结果…

【自动化测试】一位自动化测试工程师居然不会封装框架?神秘自动化测试框架......

目录:导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜)前言 自动化测试框架 自…

02 Android基础--service

02 Android基础--service什么是service?service的demo使用Service的种类前台service的使用背景什么是service? Service(服务)是一个一种可以在后台执行长时间运行操作而没有用户界面的应用组件。 服务分为两种形式:非绑定状态与绑定状态。 非…

深入Linux内核理解NIO与Epoll

目录 深入Linux内核理解NIO与Epoll IO模型 BIO(Blocking IO) 代码演示: 缺点: BIO总结: NIO(Non Blocking IO) NIO非阻塞代码示例: 使用telnet客户端Debug代码演示: 总结: NIO引入多路复用器Selector的代码演…

Python - 模块、包

模块 什么是模块(module) 是一个Python文件模块包含:函数、类、变量、可执行的代码模块分类: 内置标准模块(又称标准库)第三方开源模块自定义模块 导入模块的方式 几种方式: import [模块名…

git版本控制流程

git在生产中的版本控制流程 git介绍:Git是一个开源的分布式版本控制系统,可以有效、高速地处理从很小到非常大的项目版本管理。 那么git是如何在生产中进行版本控制的? 首先在整个git管理的项目中会分为四个分支 dev(开发分支&…

【Python】元组与集合

一、元组Python 的元组与列表类似,不同之处在于元组的元素不能修改。元组使用小括号,列表使用方括号。元组创建很简单,只需要在括号中添加元素,并使用逗号隔开即可定义空元组print(tuple()) print(())# 元组是一个不可变的序列&am…

【Flutter入门到进阶】Flutter基础篇---基础组件

1 Container容器组件 1.1 属性说明 1.1.1 alignment topCenter:顶部居中对齐 topLeft:顶部左对齐 topRight:顶部右对齐 center:水平垂直居中对齐 centerLeft:垂直居中水平居左对齐 centerRight:垂直居中水…

python自学之《21天学通Python》(17)——第20章 案例1 做一个Windows 上的360工具

Python的语法简洁而清晰,具有丰富和强大的类库及第三方库。它能够很轻松地将各种语言模块联结在一起,所以被称为“胶水”语言。当然,Python也能够方便快捷地编写一些常用的工具程序,而用其他程序设计语言需要编写很复杂的代码来完…

算法训练营 day60 动态规划 回文子串 最长回文子序列

算法训练营 day60 动态规划 回文子串 最长回文子序列 回文子串 647. 回文子串 - 力扣(LeetCode) 给你一个字符串 s ,请你统计并返回这个字符串中 回文子串 的数目。 回文字符串 是正着读和倒过来读一样的字符串。 子字符串 是字符串中的…

DIY-BETAFPV和DIY(ESP-01F+E19-900M20S2模块)915MHz信号测试对比

DIY-BETAFPV和DIY(ESP-01FE19-900M20S2模块)915MHz信号测试对比1. 前提条件2. 实测效果2.1 起点附近(距离3m左右)2.2 30m米距离(树梢)2.3 80米距离3. 整体比较4. PCBA分析4.1 DIY-BETAFPV4.2 DIY&#xff0…

node的多版本控制器,nvm,nvm使用,nvm安装

缘起 拿到新项目,第一步当然是启动项目,对于超大型项目,一个npm install 成功与失败,就是五五开。 原因如下: karma1.7.1: wanted: {"node":"0.10 || 0.12 || 4 || 5 || 6 || 7 || 8"} (curren…

rewrite 复现细节以及相关配置

github链接:https://github.com/kaonashi-tyc/Rewrite 网络的结构框架以及相关参数: 每个卷积层后面是一个批处理归一化层,然后是一个ReLu层,一直到零填充。 正如Erik的博客中提到的,该网络针对预测输出和地面真相之间的像素级MAE(平均绝对误差)最小化,而不是更常用的M…

Spring boot ResponseBodyAdvice接口全局统一返回控制,Api返回值是String 类型时异常

ResponseBodyAdvice简介在大部分前后端分离项目中,后端的返回值基本都需要包装成一个GlobalResponse,其中属性有code、message、data等,来供前端使用。这样就导致大部分Api写完后都需要手动构建一个GlobalResponse对象并填充属性返回&#xf…

如何使用BWASP对Web应用程序进行安全漏洞手工分析

关于BWASP BWASP是一款针对Web应用程序安全的开源工具,在该工具的帮助下,广大研究人员可以通过手工方式对Web应用程序进行漏洞分析。 BWASP工具可以通过对漏洞的分析来给广大研究人员提供预测信息,而无需对目标执行实际的渗透测试。 BWASP…

【STM32】cmsis-dap调试器-OpenOCD功能集成进CubeIDE中

前言 被自己买的Jlink真是要整烦了 一下连不上,一下固件掉升级,一下说是D版不给调试 于是乎决定,我买了个CMSIS-DAP调试器,决定放弃JLink这等#$%^&货… CMSIS-DAP 调试器 这个是开源调试器,硬件软件开源&#x…