【OpenCV入门】第六部分——腐蚀与膨胀
文章结构
- 腐蚀
- 膨胀
- 开运算
- 闭运算
- 形态学方法
- 梯度运算
- 顶帽运算
- 黑帽运算
腐蚀
腐蚀操作可以让图像沿着自己的边界向内收缩。OpenCV通过”核“来实现收缩计算。“核”在形态学中可以理解为”由n个像素组成的像素块“,像素块包含一个核心(通常在中央位置,也可以定义在其他位置)。像素块会在图像的边缘移动,在移动过程中,核会将图像边缘那些与核重合但又没有越过核心的像素点都抹除,效果如下:
OpenCV将腐蚀操作封装成了erode()方法:
dst = ccv2.erode(src, kernel, anchor, iterations, borderType, borderValue)
- src: 原始图像
- kernel: 腐蚀使用的核
- anchor:(可选)核的锚点位置
- iteration:(可选)腐蚀操作的迭代次数,默认值为1
- borderType:(可选)边界样式,建议默认
- borderValue:(可选)边界值,建议默认
- dst :经过腐蚀之后的图像
在OpenCV做腐蚀或其他形态学操作时,通常使用NumPy模块来创建核数组,例如:
import numpy as np
k = np.ones((5,5), np.uint8)
这两行代码创建了一个数组,可以当作erode()方法的核参数。除了5×5的结构,还可以使用3×3、9×9等其他结构,行列数越大,计算出来的效果就越粗糙,行列数越小,计算出的效果就越精细。
实例1: 将仙人球图像中的刺都抹除掉
import cv2
import numpy as np
img = cv2.imread("cactus.jpg") # 读取原图
k = np.ones((3, 3), np.uint8) # 创建3*3的数组作为核
cv2.imshow("img", img) # 显示原图
dst = cv2.erode(img, k) # 腐蚀操作
cv2.imshow("dst", dst) # 显示腐蚀效果
cv2.waitKey() # 按下任何键盘按键后
cv2.destroyAllWindows() # 释放所有窗体
结果如下:
如果是(1,1),等于没削;如果是(5,5),直接削皮了。
膨胀
膨胀操作与腐蚀操作正好相反,膨胀操作可以让图像沿着自己的边界向外扩张。同样是通过核计算,当核在图像的边缘移动时,核会将图像边缘填补新的像素,效果如下:
dst = cv2.dilate(src, kernel, anchor, iterations, borderType, borderValue)
- src: 原始图像
- kernel: 膨胀使用的核
- iteration:(可选)膨胀操作的迭代次数,默认值为1
- borderType:(可选)边界样式,建议默认
- borderValue:(可选)边界值,建议默认
- dst :经过膨胀之后的图像
实例2: 将图像加工成”近视眼“效果
import cv2
import numpy as np
img = cv2.imread("sunset.jpg") # 读取原图
k = np.ones((9, 9), np.uint8) # 创建9*9的数组作为核
cv2.imshow("img", img) # 显示原图
dst = cv2.dilate(img, k) # 膨胀操作
cv2.imshow("dst", dst) # 显示膨胀效果
cv2.waitKey() # 按下任何键盘按键后
cv2.destroyAllWindows() # 释放所有窗体
结果如下:
开运算
开运算就是先将图像进行腐蚀操作,再进行膨胀操作。开运算可以用来抹除图像外部的细节(或者噪声)
例如图 7.13 是一个简单的二叉树,父子节点之间都有线连接。如果对此图像进行腐蚀操作,可以得出如图 7.14 所示的图像,连接线消失了,节点也比原图节点小一圈。此时再执行膨胀操作,让缩小的节点膨胀回原来的大小,就得出了如图 7.15 所示的效果。
这三张图就是开运算的过程,从结果可以明显地看出: 经过开运算之后,二叉树中的连接线消失了,只剩下光秃秃的节点。因为连接线被核当成“细节”抹除了,所以利用检测轮廓的方法就可以统计出二叉树节点数量,也就是说在某些情况下,开运算的结果还可以用来做数量统计。
实例3: 抹除黑种草图像中的针状叶子
import cv2
import numpy as np
img = cv2.imread("nigella.png") # 读取原图
k = np.ones((5, 5), np.uint8) # 创建5*5的数组作为核
cv2.imshow("img", img) # 显示原图
dst = cv2.erode(img, k) # 腐蚀操作
dst = cv2.dilate(dst, k) # 膨胀操作
cv2.imshow("dst", dst) # 显示开运算结果
cv2.waitKey() # 按下任何键盘按键后
cv2.destroyAllWindows() # 释放所有窗体
结果如下:
闭运算
闭运算就是将图像先进行膨胀操作,再进行腐蚀操作。闭运算可以抹除图像内部的细节(或者噪声)。
例如图 7.19 是一个身上布满斑点的小蜘蛛,这些斑点就是图像的内部细节。先将图像进行膨胀操作,小蜘蛛身上的斑点 (包括小眼睛)就被抹除掉,效果如图 7.20 所示。然后再将图像进行腐蚀操作,让膨胀的小蜘蛛缩回原来的大小,效果如图 7.21 所示。
闭运算除了会抹除图像内部的细节,还会让一些里的较近的区域合并成一块区域。
形态学方法
OpenCV提供了一个morphologyEx()形态学方法,包含了所有常用的运算。
dst = cv2.morphologyEx(src, op, kernel, anchor, iterations, borderType, borderValue)
- src: 原始图像
- op: 操作类型
参数值 | 含义 |
---|---|
cv2.MORPH_ERODE | 腐蚀操作 |
cv2.MORPH_DILATE | 膨胀操作 |
cv2.MORPH_OPEN | 开运算,先腐蚀后膨胀 |
cv2.MORPH_CLOSE | 闭运算,先膨胀后腐蚀 |
cv2.MORPH_GRADIENT | 梯度运算,膨胀图减腐蚀图,可以得出简易的轮廓 |
cv2.MORPH_TOPHAT | 顶帽运算,原始图像减开运算图像 |
cv2.MORPH_BLACKHAT | 黑帽运算,闭运算图像减原始图像 |
- kernel: 操作过程中所使用的核
- anchor:(可选),核的锚点位置
- iteration:(可选)操作的迭代次数,默认值为1
- borderType:(可选)边界样式,建议默认
- borderValue:(可选)边界值,建议默认
- dst :操作之后得到的图像
梯度运算
这里的梯度指的是图像梯度,可以简单地理解为像素的变化程度。几个连续的像素,其像素值跨度越大,则梯度值越大。
梯度运算就是让原图的膨胀图像减去原图的腐蚀图像。因为膨胀图比原图大,腐蚀图像比原图小,利用腐蚀图像将膨胀图像掏空,就得到了原图的 轮廓图像(大概,并不精准)。
实例4: 通过梯度运算画出小蜘蛛的轮廓
import cv2
import numpy as np
img = cv2.imread("spider.png") # 读取原图
k = np.ones((5,5), np.uint8) # 创建5*5的数组作为核
cv2.imshow("img", img) # 显示原图
dst = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, k) # 进行梯度运算
cv2.imshow("dst", dst) # 显示梯度运算结果
cv2.waitKey() # 按下任何键盘按键后
cv2.destroyAllWindows() # 释放所有窗体
结果如下:
顶帽运算
顶帽运算就是让原图减去原图的开运算图像,得到图像的外部细节。
实例5: 通过顶帽运算画出小蜘蛛的腿
import cv2
import numpy as np
img = cv2.imread("spider.png") # 读取原图
k = np.ones((5, 5), np.uint8) # 创建5*5的数组作为核
cv2.imshow("img", img) # 显示原图
dst = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, k) # 进行顶帽运算
cv2.imshow("dst", dst) # 显示顶帽运算结果
cv2.waitKey() # 按下任何键盘按键后
cv2.destroyAllWindows() # 释放所有窗体
结果如下:
黑帽运算
黑帽运算就是让原图的闭运算图像减去原图,得到原图像的内部细节。
实例6: 通过黑帽运算画出小蜘蛛身上的花纹
import cv2
import numpy as np
img = cv2.imread("spider2.png") # 读取原图
k = np.ones((5, 5), np.uint8) # 创建5*5的数组作为核
cv2.imshow("img", img) # 显示原图
dst = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, k) # 进行黑帽运算
cv2.imshow("dst", dst) # 显示黑帽运算结果
cv2.waitKey() # 按下任何键盘按键后
cv2.destroyAllWindows() # 释放所有窗体
结果如下:
相关文章:

【OpenCV入门】第六部分——腐蚀与膨胀
文章结构 腐蚀膨胀开运算闭运算形态学方法梯度运算顶帽运算黑帽运算 腐蚀 腐蚀操作可以让图像沿着自己的边界向内收缩。OpenCV通过”核“来实现收缩计算。“核”在形态学中可以理解为”由n个像素组成的像素块“,像素块包含一个核心(通常在中央位置&…...

[C++] STL_list常用接口的模拟实现
文章目录 1、list的介绍与使用1.1 list的介绍1.2 list的使用 2、list迭代器3、list的构造4、list常用接口的实现4.1 list capacity4.2 插入删除、交换、清理4.2.1 insert任意位置插入4.2.2 push_front头插4.2.3 push_back尾插4.2.4 erase任意位置删除4.2.5 pop_front头删4.2.6 …...

js实现点击查看全部/收起功能
在上一篇文章实现用js截取文本后,我的另一个需求也迎刃而解了。需求就是一段长文本需要溢出隐藏,然后点击全部时显示全部文本,点击收起又回到溢出隐藏的状态。实现的效果如下图: 实现的思路时点击全部时使用这条数据的原文本&…...
安全区域边界技术测评要求项
1.边界防护-非授权设备接入、非授权连接外部网络、无线网络使用和设备可信接入 (网络边界就是采用不同安全策略的两个网络的连接处) 1-1/2-1/3-4/4-6 a)保证跨越边界的访问和数据流通过边界设备提供的受控接口进行通信 b)应能够对…...

基于YOLOV8模型的农作机器和行人目标检测系统(PyTorch+Pyside6+YOLOv8模型)
摘要:基于YOLOV8模型的农作机器和行人目标检测系统可用于日常生活中检测与定位农作机和行人目标,利用深度学习算法可实现图片、视频、摄像头等方式的目标检测,另外本系统还支持图片、视频等格式的结果可视化与结果导出。本系统采用YOLOv8目标…...
我的私人笔记(安装hbase)
在安装前需要安装好JDK、Hadoop以及Zookeeper,JDK版本为1.8、Hadoop版本为2.7.4以及Zookeeper的版本为3.4.10。 4.1.下载 下载地址:Index of /dist/hbase 本次学习版本为: hbase-1.2.1-bin.tar.gz 4.2.安装步骤 上传安装包至hadoop01节点…...

【MySQL】用户管理
之前我们一直都使用root身份来对mysql进行操作,但这样存在安全隐患。这时,就需要使用MySQL的用户管理 目录 一、用户 1.1 用户信息 1.2 添加用户 1.3 删除用户 1.4 修改用户密码 二、用户权限 2.1 赋予授权 2.2 回收权限 一、用户 1.1 用户信息…...
音视频 ffmpeg命令转封装
保持编码格式: ffmpeg -i test.mp4 -vcodec copy -acodec copy test_copy.ts ffmpeg -i test.mp4 -codec copy test_copy2.ts改变编码格式: ffmpeg -i test.mp4 -vcodec libx265 -acodec libmp3lame out_h265_mp3.mkv修改帧率: ffmpeg -i …...

恢复已删除的git分支
1.打开对应项目文件夹目录,在目录下执行git命令 2.执行命令 git reflog --dateiso , 找到最后一次commit 的id 3. 执行git checkout -b 新建分支名称 commitId 就会基于commitId这次提交时工作区新建一个分支,就能达到我们找到删除分支的代码效果。 4.直接看ide…...
ATF(TF-A)安全通告 TFV-3 (CVE-2017-7563)
安全之安全(security)博客目录导读 ATF(TF-A)安全通告汇总 目录 一、ATF(TF-A)安全通告 TFV-3 (CVE-2017-7563) 二、CVE-2017-7563 一、ATF(TF-A)安全通告 TFV-3 (CVE-2017-7563) Title RO内存始终在AArch64 Secure EL1下可执行CVE ID CVE-2017-7563 Date 06 Apr 2017 Vers…...
虚拟机Ubuntu18.04系统使用时所需要的便利配置选项
文章目录 一、屏幕分辨率调节二、解决虚拟机和宿主机之间无法进行复制粘贴和自由移动文件:三、允许使用Git指令四、可以使用Cmake进行编译五、vi编辑器查看代码文件,类型linux的记事本 每次配置虚拟机,都需要重新安装配置一些能提供便利功能的…...
python内置函数
Python 解释器内置了很多函数和类型,任何时候都能使用。以下按字母顺序给出列表。 内置函数 A abs() aiter() all() any() anext() ascii() B bin() bool() breakpoint() bytearray() bytes() C callable() chr() classmethod() compile() complex() D delattr(…...
线性思维和系统思维
1 线性思维介绍 线性思维是一种直线的、均匀的、不变的、单一的、单维的思维方式,一切都随着初始条件的给定而给定。 线性思维的5种具体表现: 简单复制过往经验去推断未来 (比如:银行工作者是铁饭碗)用已知结果得出…...

为什么要学习C++
操作系统历史 UINX操作系统诞生之初是用汇编语言编写的。随着UNIX的发展,汇编语言的开发效率成为一个瓶颈。寻找新的高效开发语言成为UNIX开发者需要解决的问题。当时BCPL语言成为了当时的选择之一。Ken Thomposn对BCPL进行简化得到了B语言。但是B语言不是直接生成…...

eureka服务注册和服务发现
文章目录 问题实现以orderservice为例orderservice服务注册orderservice服务拉取 总结 问题 我们要在orderservice中根据查询到的userId来查询user,将user信息封装到查询到的order中。 一个微服务,既可以是服务提供者,又可以是服务消费者&a…...

QT的介绍和优点,以及使用QT初步完成一个登录界面
QT介绍 QT主要用于图形化界面的开发,QT是基于C编写的一套界面相关的类库,进程线程库,网络编程的库,数据库操作的库,文件操作的库…QT是一个跨平台的GUI图形化界面开发工具 QT的优点 跨平台,具有较为完备…...
MySQL教程
MySQL教程 数据库简介数据库的基本概念MySQL简介windows下安装MySQLLinux下安装MySQL在MacOS下面安装MySQLMySQL配置文件分析MySQL数据库的基本操作MySQL创建表MySQL插入数据MySQL删除数据MySQL修改数据MySQL基本查询MySQL可视化客户端SQL语句的分类MySQL的DDLMySQL的数据类型…...

深入理解协同过滤算法及其实现
导语 个性化推荐系统在现代数字时代扮演着重要的角色,协助用户发现他们可能感兴趣的信息、产品或媒体内容。协同过滤是个性化推荐系统中最流行和有效的算法之一。 目录 协同过滤算法的原理 基于用户的协同过滤(User-Based Collaborative Filtering&am…...

力扣:随即指针138. 复制带随机指针的链表
复制带随机指针的链表 OJ链接 分析: 该题的大致题意就是有一个带随机指针的链表,复制这个链表但是不能指向原链表的节点,所以每一个节点都要复制一遍 大神思路: ps:我是学来的 上代码: struct Node* copyRandomList(s…...

【从0学习Solidity】合约入门 Hello Web3
【学习Solidity的基础】入门智能合约开发 Hello Web3 📱不写代码没饭吃上架主页 在强者的眼中,没有最好,只有更好。我们是全栈开发领域的优质创作者,同时也是阿里云专家博主。 ✨ 关注我们的主页,探索全栈开发的无限…...

Linux应用开发之网络套接字编程(实例篇)
服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …...
【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15
缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下: struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...

MFC内存泄露
1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...
3403. 从盒子中找出字典序最大的字符串 I
3403. 从盒子中找出字典序最大的字符串 I 题目链接:3403. 从盒子中找出字典序最大的字符串 I 代码如下: class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...

让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比
在机器学习的回归分析中,损失函数的选择对模型性能具有决定性影响。均方误差(MSE)作为经典的损失函数,在处理干净数据时表现优异,但在面对包含异常值的噪声数据时,其对大误差的二次惩罚机制往往导致模型参数…...

LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf
FTP 客服管理系统 实现kefu123登录,不允许匿名访问,kefu只能访问/data/kefu目录,不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...

基于单片机的宠物屋智能系统设计与实现(论文+源码)
本设计基于单片机的宠物屋智能系统核心是实现对宠物生活环境及状态的智能管理。系统以单片机为中枢,连接红外测温传感器,可实时精准捕捉宠物体温变化,以便及时发现健康异常;水位检测传感器时刻监测饮用水余量,防止宠物…...

链式法则中 复合函数的推导路径 多变量“信息传递路径”
非常好,我们将之前关于偏导数链式法则中不能“约掉”偏导符号的问题,统一使用 二重复合函数: z f ( u ( x , y ) , v ( x , y ) ) \boxed{z f(u(x,y),\ v(x,y))} zf(u(x,y), v(x,y)) 来全面说明。我们会展示其全微分形式(偏导…...
如何通过git命令查看项目连接的仓库地址?
要通过 Git 命令查看项目连接的仓库地址,您可以使用以下几种方法: 1. 查看所有远程仓库地址 使用 git remote -v 命令,它会显示项目中配置的所有远程仓库及其对应的 URL: git remote -v输出示例: origin https://…...

Springboot 高校报修与互助平台小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,高校报修与互助平台小程序被用户普遍使用,为…...