OpenCV_图像膨胀腐蚀与形态学操作及具体应用详解

news2024/9/22 16:59:51

在本教程中,您将学习如何:

  • 应用两个非常常见的形态运算符:腐蚀和膨胀:
    • cv::erode
    • cv::dilate
  • 使用OpenCV函数cv :: morphologyEx应用形态转换,如:
  1. 开运算
  2. 闭运算
  3. 形态学梯度
  4. 顶帽运算
  5. 黑帽运算

形态作业

  • 简而言之:一组基于形状处理图像的操作。形态操作将结构元素应用于输入图像并生成输出图像。
  • 最基本的形态作用是:腐蚀和膨胀。它们有广泛的用途,即:
  1. 消除噪音
  2. 隔离单个元素并连接图像中的不同元素。
  3. 查找图像中的强度凸点或孔

1.腐蚀操作(erode)


腐蚀操作可以将图像中的边缘“腐蚀”掉,使其变得更加平滑。它的原理是使用一个称为结构元素(Structuring Element)的小型矩阵,在图像上滑动并检查像素与结构元素的对应位置是否满足某种条件(通常是“与”操作)。如果像素值全部满足条件,则中心像素值保持不变,否则被腐蚀为0。这一过程可以用来消除小型噪声、分离接触对象、以及缩小物体等。
在 OpenCV 中,腐蚀操作的函数是 erode()。下面是它的语法格式和含义:

函数:

erode( src, dst, kernel);

src:表示输入图像,即待腐蚀的图像,应为灰度图像或者单通道二值图像。

dst:表示输出图像

kernel:表示结构元素,这是我们将用来执行操作的内核。如果我们不指定,
默认是一个简单的3x3矩阵。否则,我们可以指定它的形状。为此,我们需要使用
函数cv :: getStructuringElement:

腐蚀操作的基本思想是,对于给定的结构元素,在图像上滑动并检查像素与结构元素的对应位置是否满足某种条件。如果像素值全部满足条件,则中心像素值保持不变,否则被腐蚀为0。

  • 这个操作是扩张的姊妹。它计算给定内核区域的局部最小值。
  • 当内核在图像上扫描时,我们计算由重叠的最小像素值,并用该最小值替换锚点下的图像像素。BB
  • 对于扩张的例子,我们可以将侵蚀算子应用于原始图像(如上所示)。您可以在下面的结果中看到,图像的明亮区域(背景,显然)变得更薄,而黑暗区域(“写作”)变得更大。

OpenCV侵蚀

以相似的方式,通过对反转的原始图像(具有尺寸的矩形结构元素的两次侵蚀)施加腐蚀操作来产生相应的图像3x3:

OpenCV侵蚀

左图:原图反转,右图:造成腐蚀

代码如下:

void callback_Demo(int, void* userdata) {
	Mat dst;
	Mat image = *((Mat*)userdata);
	int s = element_size * 2 + 1;
	Mat structureElement = getStructuringElement(
        MORPH_RECT, 
        Size(s, s), 
        Point(-1, -1));
	erode(image, dst, structureElement, Point(-1, -1), 1);
	imshow(OUTPUT_WINDOW, dst);
	return;
}

2.膨胀操作(dilate)


膨胀操作是图像形态学处理中的一种基本操作,通常用于增加或扩展图像中的白色区域(前景对象)。它的原理是在图像上滑动一个结构元素(通常是一个小的矩形或圆形内核),将内核下方的像素值替换为内核下方区域内的最大像素值。因此,它会使图像中的白色区域变得更大。膨胀操作常用于填充图像中的空洞、连接相邻的对象以及消除图像中的噪声。

在OpenCV中,膨胀操作可以通过dilate()函数实现。该函数需要传入待处理的图像、结构元素(通常是一个矩形或圆形内核)以及迭代次数作为参数。迭代次数表示膨胀操作的次数,通常设置为1即可。

函数:

dilate( src, dst, kernel);

src:表示输入图像,即待膨胀的图像,应为灰度图像或者单通道二值图像。

dst:表示输出图像

kernel:表示结构元素,这是我们将用来执行操作的内核。如果我们不指定,
默认是一个简单的3x3矩阵。否则,我们可以指定它的形状。为此,我们需要使用
函数cv :: getStructuringElement:
  • 该操作包括将图像与某些内核(B)进行卷积,其可以具有任何形状或尺寸,通常为正方形或圆形。AB
  • 内核具有定义的锚点,通常是内核的中心。B
  • 当内核在图像上扫描时,我们计算由B重叠的最大像素值,并用该最大值替换锚点位置中的图像像素。您可以推断,这种最大化的操作会使图像中的亮区“增长”(因此称为扩张)。以上图为例。应用扩张我们可以得到:BB

OpenCV扩张

背景(明亮)扩大了字母的黑色地区。

为了更好地把握想法并避免可能的混乱,在另一个例子中,我们已经将原始图像倒过来,如白色的对象现在是这个字母。我们已经执行了两个具有大小的矩形结构元素的扩张3x3。

OpenCV扩张

左图:原图反转,右图:产生扩张

代码如下:

void callback_Demo(int, void* userdata) {
	Mat dst;
	Mat image = *((Mat*)userdata);
	int s = element_size * 2 + 1;
	Mat structureElement = getStructuringElement(MORPH_RECT, Size(s, s), Point(-1, -1));	
	dilate(image,dst,structureElement,Point(-1,-1),1);	
	imshow(OUTPUT_WINDOW, dst);
	return;
}

全部代码如下:

char OUTPUT_WINDOW[] = "output image";
int element_size = 3;
int max_size = 21;
void callback_Demo(int, void* userdata);
void callback_Demo(int, void* userdata) {
	Mat dst;
	Mat image = *((Mat*)userdata);
	int s = element_size * 2 + 1;
	Mat structureElement = getStructuringElement(MORPH_RECT, Size(s, s), Point(-1, -1));	
	dilate(image,dst,structureElement,Point(-1,-1),1);
	//erode(image, dst, structureElement, Point(-1, -1), 1);	
	//threshold(image,dst, element_size, max_size, THRESH_OTSU);
	imshow(OUTPUT_WINDOW, dst);
	return;
}
void QuickDemo::eleven(Mat& image) {
	Mat gray;
	cvtColor(image, gray, COLOR_BGR2GRAY);
	namedWindow(OUTPUT_WINDOW, WINDOW_AUTOSIZE);
	createTrackbar("element size :", OUTPUT_WINDOW, &element_size, max_size, callback_Demo, &image);
	callback_Demo(10, &image);
}

在前面的教程中,我们介绍了两种基本的形态学操作:

  • 腐蚀
  • 膨胀

基于这两个,我们可以对我们的图像进行更复杂的转换。在这里,我们简要讨论OpenCV提供的5个操作:

3.开运算—先腐蚀后膨胀

开运算是先进行腐蚀操作,再进行膨胀操作。它主要用于去除小的噪点,并保持前景物体的整体形状。

函数:

morphologyEx(mask_image, opening_image, MORPH_OPEN, element);

示例代码:

void QuickDemo::twelve(Mat& image) {
	Mat dst;
	Mat kernel = getStructuringElement(MORPH_RECT, Size(5, 5), Point(-1, -1));
	morphologyEx(image, dst, MORPH_OPEN, kernel);
	namedWindow("形态学操作", WINDOW_AUTOSIZE);
	imshow("形态学操作", dst);
}

开运算效果:对比腐蚀过后的图像,进行稍微膨胀 补充连接细节

4.闭运算—先膨胀后腐蚀 

闭运算与开运算相反,先膨胀后腐蚀,它主要用于填补前景物体中的小孔和连接断开的物体。

void QuickDemo::twelve(Mat& image) {
	Mat dst;
	Mat kernel = getStructuringElement(MORPH_RECT, Size(10, 10), Point(-1, -1));
	morphologyEx(image, dst, MORPH_CLOSE, kernel);
	namedWindow("形态学操作", WINDOW_AUTOSIZE);
	imshow("形态学操作", dst);
}

闭运算效果:对比膨胀后的图像,边缘稍微细了些

5.形态学梯度(膨胀-腐蚀)

形态学梯度运算是用图像的膨胀图像减腐蚀图像的操作,该操作可以获取原始图像中前景图像的边缘。

  • 这是图像的扩张和侵蚀的区别。

OpenCV更多形态转化

  • 找到对象的轮廓是有用的,如下所示:

OpenCV更多形态转化

代码如下:

void QuickDemo::twelve(Mat& image) {
	Mat dst;
	Mat kernel = getStructuringElement(MORPH_RECT, Size(5, 5), Point(-1, -1));
	morphologyEx(image, dst, MORPH_GRADIENT, kernel);
	namedWindow("形态学操作", WINDOW_AUTOSIZE);
	imshow("形态学操作", dst);
}

 

6. 顶帽运算(src-开运算)

顶帽运算是用原始图像减去其开运算图像的操作。顶帽运算能够获取图像的噪声信息,或者得到比原始图像的边缘更亮的边缘信息。

代码如下:

void QuickDemo::twelve(Mat& image) {
	Mat dst;
	Mat kernel = getStructuringElement(MORPH_RECT, Size(5, 5), Point(-1, -1));
	morphologyEx(image, dst, MORPH_TOPHAT, kernel);
	namedWindow("形态学操作", WINDOW_AUTOSIZE);
	imshow("形态学操作", dst);
}

7.黑帽运算(闭运算-src)

黑帽运算是用闭运算图像减去原始图像的操作。黑帽运算能够获取图像内部的小孔,或前景色中的小黑点,或者得到比原始图像的边缘更暗的边缘部分。

void QuickDemo::twelve(Mat& image) {
	Mat dst;
	Mat kernel = getStructuringElement(MORPH_RECT, Size(5, 5), Point(-1, -1));
	morphologyEx(image, dst, MORPH_BLACKHAT, kernel);
	namedWindow("形态学操作", WINDOW_AUTOSIZE);
	imshow("形态学操作", dst);
}

原图像:

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

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

相关文章

算法-环形链表(141)

这道题其实是一个非常经典的快慢指针的问题 ,也成为Floyd的乌龟和兔子算法。 设置两个指针,一个快指针,一个满指针,都从头节点开始遍历,如果链表中存在环,那么快指针最终会在环内某个节点相遇,…

Linux网络工具:用于查询DNS(域名系统)域名解析信息的命令nslookup详解

目录 一、概述 二、基本功能 1、查询域名对应的IP地址 2、查询IP地址对应的主机名 3、查询特定类型的DNS记录 三、用法 1、命令格式 2、常用选项 五、nslookup的安装 1. 打开终端 2. 更新的系统包列表 3. 安装 bind-utils 软件包 (1)对于Ce…

树和二叉树的概念以及结构

一起加油学数据结构 目录 树的概念以及结构 树的概念 树的相关概念 树的表示 二叉树的概念以及结构 二叉树的概念 特殊的二叉树 二叉树的性质 二叉树的存储结构 树的概念以及结构 树的概念 树是一种非线性的数据结构,它是由n(n>0&#xff09…

【Elasticsearch系列十九】评分机制详解

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

Mapper核心配置文件

文章目录 environment 数据库环境typeAlias 起别名 environment 数据库环境 typeAlias 起别名

【QGIS入门实战精品教程】6.2:QGIS选择要素的多种方法

本文讲解QGIS中选择要素的多种方法。 文章目录 一、选择要素二、多边形选择三、自由手绘四、按半径选择五、按值选择要素六、按表达式选择在QGIS中,选择要素有多种方法,如下所示: 下面举例说明。 一、选择要素 可以直接点选、框选实现单个或者多个点线面要素的选择(按住C…

【计算机网络 - 基础问题】每日 3 题(十八)

✍个人博客:Pandaconda-CSDN博客 📣专栏地址:http://t.csdnimg.cn/fYaBd 📚专栏简介:在这个专栏中,我将会分享 C 面试中常见的面试题给大家~ ❤️如果有收获的话,欢迎点赞👍收藏&…

计算机毕业设计公交站点线路查询网站登录注册搜索站点线路车次/springboot/javaWEB/J2EE/MYSQL数据库/vue前后分离小程序

选题背景‌: 随着城市化进程的加快,公共交通成为城市居民出行的重要方式。然而,传统的公交站点线路查询方式往往依赖于纸质地图或简单的电子显示屏,查询效率低下且信息更新不及时。因此,开发一个功能全面、易于使用的…

某建筑市场爬虫数据采集逆向分析

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 目标网站 aHR0cHM6Ly9qenNjLm1vaHVyZC5nb3YuY24vZGF0YS9jb21wYW55P2NvbXBsZXhuYW1lPSVFNiVCMCVCNA 提示:以下是本篇文章正文内容,下面…

MySQL中的逻辑条件

逻辑条件组合两个比较条件的结果来产生一个基于这些条件的单个的结果,或者逆转一个单个条件的结果。当所有条件的结果为真时,返回行。 SQL的三个逻辑运算符是: AND、OR、NOT 可以在WHERE子句中用AND和OR运算符使用多个条件。 示例一&#…

【计组】数据的表示与运算

【计组】数据的表示与运算 一、数据的表示方法和转换 1、真值 二进制数和十进制数一样有正负之分,书写时加上“”或“-”来表示的,叫做真值。 例:十进制的3和-6,二进制的011和-110都是真值。 2、机器数 机器数采用二进制的0表…

最优化理论与自动驾驶(十一):基于iLQR的自动驾驶轨迹跟踪算法(c++和python版本)

最优化理论与自动驾驶(四):iLQR原理、公式及代码演示 之前的章节我们介绍过,iLQR(迭代线性二次调节器)是一种用于求解非线性系统最优控制最优控制最优控制和规划问题的算法。本章节介绍采用iLQR算法对设定…

Cpp类和对象(中)(4)

文章目录 前言一、类的六个默认成员函数二、构造函数构造函数的概念构造函数的特性构造函数的两种分类编译器默认生成构造函数意义及相关问题C11打的补丁 三、析构函数析构函数的概念析构函数的特性验证是否会自动调用析构函数验证析构函数对于内置与自定义类型处理验证先定义后…

【学习笔记】数据结构(六 ②)

树和二叉树(二) 文章目录 树和二叉树(二)6.3.2 线索二叉树 6.4 树和森林6.4.1 树的存储结构6.4.2 森林与二叉树的转换6.4.3 树和森林的遍历 6.5 树与等价问题6.5.1 等价定义6.5.2 划分等价类的方法6.5.3 划分等价类的具体操作 - 并…

【LeetCode热题100】位运算

这篇博客先介绍了常见位运算操作,然后记录了关于位运算的几道题,包括判定字符是否唯一、丢失的数字、两整数之和、只出现一次的数字2、消失的两个数字。 在这一部分,我们不妨先来总结一下常见位运算操作: 1.基础位运算 >>…

vite 使用飞行器仪表示例

这里写自定义目录标题 环境vue代码效果图 环境 jquery npm install -S jqueryjQuery-Flight-Indicators 将img、css、js拷贝到vite工程目录中 打开 jquery.flightindicators.js&#xff0c;在文件开头加上import jQuery from "jquery"; vue代码 <template>&…

C#(.NET FrameWork库)逆向基础流程(纯小白教程)

一&#xff0c;例题链接 限时题目&#xff0c;只能用网盘来分享了&#xff0c;侵权联系删->百度网盘 请输入提取码 二&#xff0c;文件特征 使用工具查看文件信息&#xff0c; 能看到分析出文件编写语言为C#&#xff0c;使用了.NET库 三&#xff0c;做题流程 &#xff08…

浙版传媒思迈特软件大数据分析管理平台建设项目正式启动

近日&#xff0c;思迈特软件与出版发行及电商书城领域的领军企业——浙江出版传媒股份有限公司&#xff0c;正式启动大近日&#xff0c;思迈特软件与出版发行及电商书城领域的领军企业——浙江出版传媒股份有限公司&#xff0c;正式启动大数据分析管理平台建设项目。浙版传媒相…

Java之继承1

1. 继承 1.1 为什么要继承 在Java中我们定义猫类和狗类&#xff0c;如下 public class Cat {public String name;public int age;public String color;public void eat(){System.out.println(name "正在吃饭");}public void sleep(){System.out.println(name &qu…

基于pytorch本地部署微调bert模型(yelp文本分类数据集)

项目介绍 本项目使用hugging face上提供的Bert模型API&#xff0c;基于yelp数据集&#xff0c;在本地部署微调Bert模型&#xff0c;官方的文档链接为https://huggingface.co/docs/transformers/quicktour&#xff0c;但是在官方介绍中出现了太多的API调用接口&#xff0c;无法…