当前位置: 首页 > news >正文

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

前置

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

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

相关操作最主要的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 nporigin = 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 nporigin = 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 nporigin = 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 nporigin = 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 nporigin = 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 nporigin = 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 nporigin = 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()

运行如下:

 

 

相关文章:

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

前置 形态学主要是从图像中提取分量信息,该分量信息通常是图像理解时所使用的最本质的形状特征,对于表达和描绘图像的形状有重要意义。 大体就是通过一系列操作让图像信息中的关键信息更加凸出。同时,形态学的操作都是基于灰度图进行。 相关操作最主要…...

DeepFaceLab 中Ubuntu(docker gpu) 部署

DeepFaceLab 在windows图形界面部署比较多,下面用ubuntu 部署在服务器上。部署过程中python版本,或者protobuf版本可能有问题,所以建议用docker 代码下载 cd /trainssdgit clone --depth 1 https://github.com/nagadit/DeepFaceLab_Linux.g…...

分析帆软填报报表点提交的逻辑

1 点提交这里首先会校验数据,校验成功后就去入库数据,这里不分析校验,分析下校验成功后数据是怎么入库的。 2 我们知道当点提交时,发送的请求中的参数为 op=fr_write,cmd=submit_w_report. 在帆软报表中op表示服务,cmd表示服务中的一个动作处理。比如op=fr_write这个服务…...

【ROS学习笔记9】ROS常用API

【ROS学习笔记9】ROS常用API 文章目录【ROS学习笔记9】ROS常用API前言一、 初始化二、 话题与服务相关对象三、 回旋函数四、时间函数五、其他函数Reference写在前面,本系列笔记参考的是AutoLabor的教程,具体项目地址在 这里 前言 ROS的常用API&#xf…...

客户关系管理挑战:如何保持客户满意度并提高业绩?

当今,各行业市场竞争愈发激烈,对于保持客户满意度并提高业绩是每个企业都面临的挑战。而客户关系管理则是实现这一目标的关键,因为它涉及到与客户的互动和沟通,以及企业提供优质的产品和服务。在本文中,我们将探讨客户…...

Cartesi 2023 年 2 月回顾

2023年2月28日,通过ETH Denver和Cartesi的在线全球黑客马拉松一起开启黑客马拉松赛季!ETH Denver 正在热火朝天的进行着,我们正在为3月25日开始的首个全球在线黑客马拉松做准备。但这并不是本月发生的所有事情。我们在继续扩展和发展在全世界各地的社区&…...

《爆肝整理》保姆级系列教程python接口自动化测试框架(二十六)--批量执行用例 discover(详解)

简介  我们在写用例的时候,单个脚本的用例好执行,那么多个脚本的时候,如何批量执行呢?这时候就需要用到 unittest 里面的 discover 方法来加载用例了。加载用例后,用 unittest 里面的 TextTestRunner 这里类的 run 方…...

Ubuntu学习篇

前言 环境:Ubuntu 20.4lts Ubuntu系统跟centos还是有很多区别的,笔者之前一直使用的是centos7.x版本。 镜像下载地址:https://ubuntu.com/download/server#downloads 其他版本下载地址:https://launchpad.net/ubuntu/cdmirrors&a…...

extern关键字

1、基本解释: extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中,提示编译器遇到此变量和数时在其他模块中寻找其定义。此外extern也可用来进行链接指定。 也就是说extern有两个作用。   第一个,当它与"C"一起…...

T3 出行云原生容器化平台实践

作者:林勇,就职于南京领行科技股份有限公司,担任云原生负责人,也是公司容器化项目的负责人。主要负责 T3 出行云原生生态相关的所有工作,如服务容器化、多 Kubernetes 集群建设、应用混部、降本增效、云原生可观测性基…...

从0开始学python -44

Python3 正则表达式 -2 检索和替换 Python 的re模块提供了re.sub用于替换字符串中的匹配项。 语法: re.sub(pattern, repl,string, count0, flags0)参数: pattern : 正则中的模式字符串。repl : 替换的字符串,也可为一个函数。string : …...

22- estimater使用 (TensorFlow系列) (深度学习)

知识要点 estimater 有点没理解透 数据集是泰坦尼克号人员幸存数据. 读取数据:train_df pd.read_csv(./data/titanic/train.csv) 显示数据特征:train_df.info() 显示开头部分数据:train_df.head() 提取目标特征:y_train tr…...

eKuiper 1.8.0 发布:零代码实现图像/视频流的实时 AI 推理

LF Edge eKuiper 是 Golang 实现的轻量级物联网边缘分析、流式处理开源软件,可以运行在各类资源受限的边缘设备上。eKuiper 的主要目标是在边缘端提供一个流媒体软件框架(类似于 Apache Flink )。eKuiper 的规则引擎允许用户提供基于 SQL 或基…...

[Ansible系列]ansible JinJia2过滤器

目录 一. JinJia2简介 二. JinJia2模板使用 2.1 在play中使用jinjia2 2.2 template模块使用 2.3 jinjia2条件语句 2.4 jinjia2循环语句 2.5 jinjia2过滤器 2.5.1 default过滤器 2.5.2 字符串操作相关过滤器 2.5.3 数字操作相关过滤器 2.5.4 列表操作…...

Cookie、Session、Token区分

一开始接触这三个东西,肯定会被绕的不知道都是干什么的。1、为什么要有它们?首先,由于HTTP协议是无状态的,所谓的无状态,其实就是 客户端每次想要与服务端通信,都必须重新与服务端连接,这就意味…...

回暖!“数”说城市烟火气背后

“人间烟火气,最抚凡人心”。在全国各地政策支持以及企业的积极生产运营下,经济、社会、生活各领域正加速回暖,“烟火气”在城市中升腾,信心和希望正在每个人心中燃起。 发展新阶段,高效统筹经济发展和公共安全&#…...

JS逆向-百度翻译sign

前言 本文是该专栏的第36篇,后面会持续分享python爬虫干货知识,记得关注。 有粉丝留言,近期需要做个翻译功能,考虑到百度翻译语言语种比较全面,但是它的参数被逆向加密了,对于这种情况需要怎么处理呢?所以本文以它为例。 废话不多说,跟着笔者直接往下看正文详细内容。…...

Fiddler抓包之Fiddler过滤器(Filters)调试

Filters:过滤器,帮助我们过滤请求。 如果需要过滤掉与测试项目无关的抓包请求,更加精准的展现抓到的请求,而不是杂乱的一堆,那功能强大的 Filters 过滤器能帮到你。 2、Filters界面说明 fiddler中的过滤 说明&#…...

【xib文件的加载过程 Objective-C语言】

一、xib文件的加载过程: 1.xib文件,是不是在这里啊: View这个文件夹里, 然后呢,我们加载xib是怎么加载的呢, 是不是在控制器里,通过我们这个类方法,加载xib: TestAppView *appView = [TestAppView appView]; + (instancetype)appView{NSBundle *rootBundle = [N…...

react setState学习记录

react setState学习记录1.总体看来2.setState的执行是异步的3.函数式setState1.总体看来 (1). setState(stateChange, [callback])------对象式的setState 1.stateChange为状态改变对象(该对象可以体现出状态的更改) 2.callback是可选的回调函数, 它在状态更新完毕、界面也更新…...

深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法

深入浅出:JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中,随机数的生成看似简单,却隐藏着许多玄机。无论是生成密码、加密密钥,还是创建安全令牌,随机数的质量直接关系到系统的安全性。Jav…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练

前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1):从基础到实战的深度解析-CSDN博客,但实际面试中,企业更关注候选人对复杂场景的应对能力(如多设备并发扫描、低功耗与高发现率的平衡)和前沿技术的…...

【项目实战】通过多模态+LangGraph实现PPT生成助手

PPT自动生成系统 基于LangGraph的PPT自动生成系统,可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析:自动解析Markdown文档结构PPT模板分析:分析PPT模板的布局和风格智能布局决策:匹配内容与合适的PPT布局自动…...

leetcodeSQL解题:3564. 季节性销售分析

leetcodeSQL解题:3564. 季节性销售分析 题目: 表:sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...

零基础设计模式——行为型模式 - 责任链模式

第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...

今日科技热点速览

🔥 今日科技热点速览 🎮 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售,主打更强图形性能与沉浸式体验,支持多模态交互,受到全球玩家热捧 。 🤖 人工智能持续突破 DeepSeek-R1&…...

实现弹窗随键盘上移居中

实现弹窗随键盘上移的核心思路 在Android中&#xff0c;可以通过监听键盘的显示和隐藏事件&#xff0c;动态调整弹窗的位置。关键点在于获取键盘高度&#xff0c;并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容

目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法&#xff0c;当前调用一个医疗行业的AI识别算法后返回…...

华硕a豆14 Air香氛版,美学与科技的馨香融合

在快节奏的现代生活中&#xff0c;我们渴望一个能激发创想、愉悦感官的工作与生活伙伴&#xff0c;它不仅是冰冷的科技工具&#xff0c;更能触动我们内心深处的细腻情感。正是在这样的期许下&#xff0c;华硕a豆14 Air香氛版翩然而至&#xff0c;它以一种前所未有的方式&#x…...

GruntJS-前端自动化任务运行器从入门到实战

Grunt 完全指南&#xff1a;从入门到实战 一、Grunt 是什么&#xff1f; Grunt是一个基于 Node.js 的前端自动化任务运行器&#xff0c;主要用于自动化执行项目开发中重复性高的任务&#xff0c;例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...