苦学Opencv的第十一天:图像的形态学操作

Python OpenCV从入门到精通学习日记:图像的形态学操作

前言

图像形态学是图像处理中的一个重要分支,主要关注图像中物体的形状和结构。通过形态学操作,我们可以对图像进行有效的分析和处理,例如图像的腐蚀与膨胀开运算与闭运算等。腐蚀和膨胀是图像形态学中的两种核心操作,通过这两种操作可以清除或强化图像中的细节。合理使用腐蚀和膨胀,还可以实现图像开运算、闭运算、梯度运算、顶帽运算和黑帽运算等极具特点的操作。接下来开始学习吧!!!

图像形态学操作
腐蚀
膨胀
开运算
闭运算
其他形态学运算
梯度运算
顶帽运算
黑帽运算

因为内容较多,我列举了目录,如下:

图像的形态学操作

  • Python OpenCV从入门到精通学习日记:图像的形态学操作
  • 前言
  • 1 腐蚀
  • 2 膨胀
  • 3 开运算
  • 4 闭运算
  • 5 形态学运算
    • 5.1 梯度运算
    • 5.2 顶帽运算
    • 5.3 黑帽运算
  • 小结

1 腐蚀

腐蚀操作可以让图像沿着自己的边界向内收缩。OpenCV通过“核”来实现收缩计算。“核”的英文名为kernel,在形态学中可以理解为“由n个像素组成的像素块”,像素块包含一个核心(核心通常在中央位置,也可以定义在其他位置)。像素块在图像的边缘移动,在移动过程中,核会将图像边缘那些与核重合但又没有越过核心的像素点都抹除,效果类似图12.1所示的过程,就像削土豆皮一样,将图像一层一层地“削薄”。(这里借用书上原图)

在这里插入图片描述
OpenCV将腐蚀操作封装成erode()方法。

dst = cv2.erode(src, kernel, anchor, iterations,borderType, borderValue)src: 输入图像。
kernel: 腐蚀使用的核,可以自定义或使用OpenCV提供的预设。
anchor:可选参数,核的锚点位置。
iterations: 腐蚀操作的迭代次数,默认为1。
borderType: 边界处理方式,默认为cv2.BORDER_CONSTANT。
borderValue: 边界值,默认为0。

图像经过腐蚀操作之后,可以抹除一些外部的细节,如图12.2所示是一个卡通小蜘蛛,如果用一个5×5的像素块作为核对小蜘蛛进行腐蚀操作,可以得到如图12.3所示的结果。小蜘蛛的腿被当成外部细节抹除了,同时小蜘蛛的眼睛变大了,因为核从内部也“削”了一圈。
在这里插入图片描述
在OpenCV做腐蚀或其他形态学操作时,通常使用numpy模块来创建核数组。
比如:

 import numpy as npk = np.ones((5, 5), np.uint8)

这两行代码什么意思可以去看我前面的文章:链接: 苦学Opencv的第三天:像素的操作

这个数组作为erode()方法的核参数。除了5×5的结构,还可以使用3×3、9×9、11×11等结构,行列数越大,计算出的效果就越粗糙,行列数越小,计算出的效果就越精细。

代码示例:

import cv2
import numpy as np# 读取图像
img = cv2.imread('image.png', 0)# 创建结构元素
kernel = np.ones((3,3), np.uint8)# 腐蚀操作
eroded_img = cv2.erode(img, kernel)# 显示结果
cv2.imshow('Eroded Image', eroded_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

运行结果如下:
在这里插入图片描述

🌟可以看出,仙人掌的刺并没有因此消失,但是刺明显变得模糊不清了。

2 膨胀

膨胀操作与腐蚀操作正好相反,它通过使用核来“扩展”图像的边界。

OpenCV将膨胀操作封装成dilate()方法。

dst = cv2.dilate(src, kernel, anchor, iterations,borderType, borderValue)参数说明:src:原始图像。kernel:膨胀使用的核。anchor:可选参数,核的锚点位置。iterations:可选参数,腐蚀操作的迭代次数,默认值为1。borderType:可选参数,边界样式,建议默认。borderValue:可选参数,边界值,建议默认。
返回值说明:dst:经过膨胀之后的图像。

膨胀的效果也正好是与腐蚀相反。这里不多加介绍了,直接放个图像,大家就知道什么意思了。
在这里插入图片描述

代码示例:

# 膨胀操作
import cv2
import numpy as np# 读取图像
img = cv2.imread('xianrenzhang.png')
cv2.imshow("img",img)
# 创建结构元素
kernel = np.ones((10,10), np.uint8)# 腐蚀操作
dilated_img = cv2.dilate(img, kernel)# 显示结果
cv2.imshow('Dilated Image', dilated_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

运行结果如下:
在这里插入图片描述

🌟这里可以看出,过度膨胀后的图像就好像近视眼的世界,图像变得非常模糊。

3 开运算

开运算是先进行腐蚀操作,再进行膨胀操作,开运算可以用来抹除图像外部的细节(或者噪声)。

我们举个例子,这是一个二叉树:
在这里插入图片描述
我们先对齐进行腐蚀操作,那么连接的细线会因为腐蚀而消失

在这里插入图片描述
随后我们进行膨胀操作

在这里插入图片描述
🌟从结果中可以明显地看出:经过开运算之后,二叉树中的连接线消失了,只剩下光秃秃的节点。因为连接线被核当成“细节”抹除了,所以利用检测轮廓的方法可以统计二叉树节点数量,也就是说在某些情况下,开运算的结果还可以用来做数量统计。

4 闭运算

闭运算是先进行膨胀操作,再进行腐蚀操作,闭运算可以抹除图像内部的细节(或者噪声)。

闭运算正好与开运算相反。我们在这举个例子:假设有只身上有斑点的小蜘蛛
在这里插入图片描述
我们先对其膨胀
在这里插入图片描述
在进行腐蚀
在这里插入图片描述
🌟从结果中可以明显地看出:经过闭运算后,小蜘蛛身上的花纹都被抹除了,就连眼睛也被当成“细节”抹除了。闭运算除了会抹除图像内部的细节,还会让一些离得较近的区域合并成一块区域。

5 形态学运算

除了基本的腐蚀和膨胀操作,OpenCV还提供了梯度运算、顶帽运算和黑帽运算等高级形态学操作。OpenCV 提 供 了 一 个morphologyEx()形态学方法,包含所有常用的运算,其语法如下:

dst = cv2.morphologyEx(src, op, kernel, anchor,iterations, borderType, borderValue)参数说明:src:原始图像。op:操作类型,具体值如表所示。kernel:操作过程中使用的核。anchor:可选参数,核的锚点位置。iterations:可选参数,迭代次数,默认值为1。borderType:可选参数,边界样式,建议默认。borderValue:可选参数,边界值,建议默认。
返回值说明:dst:操作之后得到的图像。
参数值含义
CV2.MORPH_ERODE腐蚀操作
CV2.MORPHDILATE膨胀操作
CV2.MORPH_OPEN开运算,先腐蚀后膨胀
CV2.MORPHCLOSE闭运算,先胀后腐蚀
CV2.MORPH_GRADIENT梯度运算,膨胀图减腐蚀图
CV2.MORPHTOPHAT顶幅运算,原始图减开运算图
CV2.MORPHBLACKHAT黑幅运算,闭运算图减原始图

morphologyEx()方法实现的腐蚀、膨胀、开运算和闭运算效果与前文中介绍的效果完全一致,这里不再赘述,下面我们学习3个特点鲜明的操作:梯度运算、顶帽运算和黑帽运算。

5.1 梯度运算

这里的梯度是指图像梯度,可以简单地理解为像素的变化程度。如果几个连续的像素,其像素值跨度越大,则梯度值越大

梯度运算是通过膨胀图像减去原始图像来突出显示图像的边缘。

通俗的讲,梯度运算的运算过程就是:让原图的膨胀图减去腐蚀图,因为膨胀图比原图大,腐蚀图比原图小,利用腐蚀图将膨胀图掏空,就得到了原图的轮廓图。当然,这只能等到一个大概的轮廓图,是不精准的。

具体的代码只是在前面的代码中修改函数为morphology(),在这里不再赘述。

5.2 顶帽运算

顶帽运算是原始图像减去开运算后的图像,用于提取图像的外部细节

5.3 黑帽运算

黑帽运算是闭运算后的图像减去原始图像,用于提取图像的内部细节

代码示例:

# 梯度运算
gradient_img = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)# 顶帽运算
tophat_img = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)# 黑帽运算
blackhat_img = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)# 显示结果
cv2.imshow('Gradient Image', gradient_img)
cv2.imshow('Top Hat Image', tophat_img)
cv2.imshow('Black Hat Image', blackhat_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

小结

通过今天的学习,我们掌握了图像形态学的基本操作,这些操作对于图像分析和特征提取非常有用。明天继续学习图形检测!!!

大家在实践中遇到任何问题,欢迎在评论区讨论交流。明天见!

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

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

相关文章

nginx的学习(一):nginx的基本概念和反向代理

简介 nginx的基本概念,以及反向代理的配置 nginx 是一个高性能的http和反向代理web服务器及电子邮件(IMAP/POP3/SMTP)代理服务器。 相关的基本概念 正向代理 客户端配置代理服务器,通过代理服务器访问互联网。 反向代理 客…

【8月EI会议推荐】第四届区块链技术与信息安全国际会议

一、会议信息 大会官网:http://www.bctis.nhttp://www.icbdsme.org/ 官方邮箱:icbctis126.com 组委会联系人:杨老师 19911536763 支持单位:中原工学院、西安工程大学、齐鲁工业大学(山东省科学院)、澳门…

Xinstall揭秘:一键拉起服务如何助力App提升用户体验和下载转化率

在移动互联网时代,App的运营和推广显得尤为重要。而在这个过程中,如何提升用户体验和下载转化率成为了每个App运营者关注的焦点。今天,我们就来揭秘一下Xinstall的一键拉起服务,看看它是如何助力App提升用户体验和下载转化率的。 …

Java之多线程-同步代码块

线程同步 Java中提供了线程同步的机制,来解决上述的线程安全问题。 Java中实现线程同步,主要借助synchronized关键字实现。 线程同步方式: 同步代码块 同步方法 锁机制 1)同步代码块 格式: //Object类及其子类…

Flink笔记整理(五)

Flink笔记整理(五) 文章目录 Flink笔记整理(五)七、处理函数(最底层最常用最灵活)7.1基本处理函数(ProcessFunction)处理函数的功能和使用ProcessFunction解析 7.2按键分区处理函数&…

数据结构 Day2 链式存储

线性表的链式存储 解决顺序存储的缺点,插入和删除,动态存储问题。特点:线性表链式存储结构的特点是一组任意的存储单位存储线性表的数据元素,存储单元可以是连续的,也可以不连续。可以被存储在任意内存未被占用的位置上…

JavaScript Let

ECMAScript 2015 ES2015 引入了两个重要的 JavaScript 新关键词:let 和 const。 这两个关键字在 JavaScript 中提供了块作用域(Block Scope)变量(和常量)。 在 ES2015 之前,JavaScript 只有两种类型的作…

【数据库】联合索引在b+树如何存储

什么是联合索引? 联合索引是一种数据库索引类型,它允许你基于表中两个或多个列的组合来创建索引。这种索引可以提高数据库查询的性能,特别是当查询条件涉及到这些列时。 如: create index id_name_age out users(name,age) 索引…

算法刷题day20|回溯:39. 组合总和、40. 组合总和 II、131. 分割回文串

39. 组合总和 回溯 class Solution { private:vector<vector<int>> result;vector<int> path;void backtracking(vector<int>& candidates, int target, int sum, int startIndex) {if (sum > target) {return;}if (sum target) {result.push…

C#、Net6、WebApi报表方案

目录 1 Pdf表单方案 1.1出现如下错误提示: 1.2 字体路径使用 2 Docx报表模板方案 2.1 pdf方案缺陷 2.2 解决方案 3 Spire.Doc报表方案 3.1 Docx方案缺陷 3.2 解决方案 4 插入复选框 5 WebApi文件流下载接口 6 软件获取方式 1 Pdf表单方案 使用【Adobe Acrobat P…

Python 爬虫入门(一):从零开始学爬虫 「详细介绍」

Python 爬虫入门&#xff08;一&#xff09;&#xff1a;从零开始学爬虫 「详细介绍」 前言1.爬虫概念1.1 什么是爬虫&#xff1f;1.2 爬虫的工作原理 2. HTTP 简述2.1 什么是 HTTP&#xff1f;2.2 HTTP 请求2.3 HTTP 响应2.4 常见的 HTTP 方法 3. 网页的组成3.1 HTML3.1.1 HTM…

掀桌子了!原来是咱们的大屏设计太酷,吓着前端开发老铁了

掀桌子了&#xff01;原来是咱们的大屏设计太酷&#xff0c;吓着前端开发老铁了 艾斯视觉观点认为&#xff1a;在软件开发的世界里&#xff0c;有时候创意和设计的火花会擦得特别亮&#xff0c;以至于让技术实现的伙伴们感到既兴奋又紧张。这不&#xff0c;我们的设计团队刚刚…

SpringBoot入门实战:SpringBoot整合Shiro

1.背景介绍 SpringBoot是一个用于快速开发Spring应用程序的框架。它的核心是对Spring框架的一层封装&#xff0c;使其更加简单易用。SpringBoot整合Shiro是一种将SpringBoot与Shiro整合的方法&#xff0c;以实现身份验证和授权功能。 Shiro是一个强大的Java安全框架&#xff0c…

matlab笔记 - 最小二乘法拟合直线的原理与实现

最小二乘法拟合直线原理与实现 一、引言二、原理概述1. 建模思路2.误差函数3.求解最优参数 三、matlab实现最小二乘法拟合直线1.直接代码实现2.MATLAB内置函数实现 四、扩展统计学与回归分析经济学工程学图像处理机器学习 一、引言 最小二乘法&#xff08;Least Squares Metho…

鸿蒙APP架构及开发入门

1.鸿蒙系统 1.1 什么是鸿蒙 鸿蒙是一款面向万物互联时代的、全新的分布式操作系统。 在传统的单设备系统能力基础上&#xff0c;鸿蒙提出了基于同一套系统能力、适配多种终端形态的分布式理念&#xff0c;能够支持手机、平板、智能穿戴、智慧屏、车机、PC、智能音箱、耳机、…

超燃!纯AI生成《泰坦尼克号》大片!浙大阿里发布MovieDreamer:超长电影生成“梦工厂“

论文链接&#xff1a;https://arxiv.org/pdf/2407.16655 项目主页&#xff1a;https://aim-uofa.github.io/MovieDreamer/ github链接&#xff1a;https://github.com/aim-uofa/MovieDreamer 亮点直击 MovieDreamer&#xff0c;一个新颖的分层框架&#xff0c;将自回归模型与扩…

正则表达式与文本处理

目录 一、正则表达式 1、正则表达式定义 1.1正则表达式的概念及作用 1.2、正则表达式的工具 1.3、正则表达式的组成 2、基础正则表达式 3、扩展正则表达式 4、元字符操作 4.1、查找特定字符 4.2、利用中括号“[]”来查找集合字符 4.3、查找行首“^”与行尾字符“$”…

前端江湖:从菜鸟到大侠的修炼手册

在这个数字编织的梦幻世界里&#xff0c;前端&#xff0c;这个听起来就带着几分仙气与神秘感的词汇&#xff0c;实则是每一位互联网探险家手中的魔法杖。它不仅连接着代码的冰冷逻辑与用户的炽热情感&#xff0c;更在无数次的点击与滑动间&#xff0c;绘制出一幅幅绚丽多彩的交…

通过IP获取对应的经纬度地区

背景 项目现在要通过IP获取对应的地区和经纬度。后面会根据经纬度在地图上展示 直接用大佬给出的ip-info 这是大佬给的项目地址 https://gitee.com/jthinking/ip-info这是运行实例 感谢大佬打赏 ![在这里插入图片描述]