# OpenCV 图像预处理—形态学:膨胀、腐蚀、开运算、闭运算 原理详解

文章目录

  • 形态学概念
  • 膨胀
    • 使用膨胀操作来修复裂痕
      • 示例代码
      • 关键解析:
  • 腐蚀
    • 使用腐蚀操作消除噪点
      • 示例代码:
  • 开运算—先腐蚀后膨胀
  • 闭运算—先膨胀后腐蚀

形态学概念

首先看这两张图片

在这里插入图片描述

一张图周围有大大小小的噪音和彩点,另一张图片中字母有间隙,这种效果影响了图片的质量,该如何处理图片,提高质量?

这就是形态学操作发挥作用的地方,形态学(Morphology)是图像处理中的一种技术,主要用于分析和处理图像中的结构和形状。形态学操作基于图像的形状和结构,而不是像素的具体值。它通常应用于二值图像(黑白图像),但也可以用于灰度图像。形态学操作在许多图像处理任务中发挥着重要作用,如去噪声、分割、边缘检测等。

膨胀

膨胀操作可以理解为将图像中的前景对象扩展。其基本原理是用一个结构元素扫描图像,如果结构元素至少有一个与前景(白色)部分重叠,则图像中的中心元素被设置为前景。

与卷积类似,也有一个矩阵来扫描整张图片,比如下方这个3*3矩阵,
$$
1 & 1 & 1
1 & 1 & 1
1 & 1 & 1

$$
当这个矩阵在图片扫描的时候,如果矩阵的任何元素遇到图像的像素值“1”。则与内核中心元素重叠的像素将转换为“1”。如下图所示

在这里插入图片描述

整个扫描的过程动态如下:会将橙色部分进行扩张,这就是膨胀的过程。

在这里插入图片描述

使用膨胀操作来修复裂痕

示例代码

//形态学操作 膨胀 腐蚀 ,开操作, 闭操作
void morphology_op_demo(Mat &image){Mat mask_image;threshold(image,mask_image,150,255,THRESH_BINARY_INV);  //图像进行二值化// 创建结构元素 扫描核int kernel_size =3;cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT,cv::Size(2 * kernel_size + 1, 2 * kernel_size + 1),cv::Point(-1, -1));// 执行膨胀操作cv::Mat eroded_image;cv::dilate(mask_image, eroded_image, element,Point(-1,-1),1);// 显示结果图像cv::imshow("Original Image", mask_image);cv::imshow("Eroded Image", eroded_image);waitKey();
}

关键解析:

threshold(image,mask_image,150,255,THRESH_BINARY);  //图像进行二值化

对图像进行二值化,让图像非黑即白,当然膨胀操作也可以用于彩色图像,但是会有一个问题,中心点像素会累加,会提高原来图片的亮度,扫描核越大,会导致图片越亮,直到白色看不见为止。

   cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT,cv::Size(2 * erosion_size + 1, 2 * erosion_size + 1),cv::Point(-1, -1));

创建扫描矩阵,矩阵可以任意大小,这里使用奇数n*n的矩阵 Point 取(-1,-1)代表使用中心点像素,扫描矩阵的size越大,膨胀效果越强。

  cv::dilate(mask_image, eroded_image, element,Point(-1,-1),1);

膨胀操作API ,函数原型

CV_EXPORTS_W void dilate( InputArray src, OutputArray dst, InputArray kernel,Point anchor = Point(-1,-1), int iterations = 1,int borderType = BORDER_CONSTANT,const Scalar& borderValue = morphologyDefaultBorderValue() );

一般只关心前三个参数即可,输入,输出,扫描核(扫描的矩阵),Point 取(-1,-1)代表使用中心点像素,这里迭代次数为1次,同理 迭代次数越多,膨胀效果越强

效果如图:

扫描核size为 3:有效果,但仍然有裂痕

在这里插入图片描述

扫描核 size 为 5:效果增强,边缘变粗,基本上添上空隙

在这里插入图片描述

腐蚀

与膨胀相反,删除元素,它腐蚀图像的方式就像水侵蚀河岸一样。在腐蚀操作中,它将结构元素从输入图像的左向右和从上到下滑动。如果结构元素内的所有像素都大于 0,则保留原始像素值。否则,像素设置为 0。腐蚀用于去除被视为噪声的小斑点。

同样的使用膨胀操作的扫描核 3*3 全为1 的矩阵
$$
1 & 1 & 1
1 & 1 & 1
1 & 1 & 1

$$
此内核遍历图像的每个像素。如果与内核重叠的所有像素恰好是“1”,则不会发生任何更改。但是,如果任何重叠的像素恰好为“0”,则与内核的 中心 元素重叠的像素将设置为“0”。

在这里插入图片描述

腐蚀操作可视化图:

在这里插入图片描述

随着迭代次数的增加,图像像素点慢慢被腐蚀。因此,如果您需要提取粗体且周围有很多噪点的时候,可以通过侵蚀图像来消除噪点。

使用腐蚀操作消除噪点

示例代码:

//形态学操作 膨胀 腐蚀 ,开操作, 闭操作
void morphology_op_demo(Mat &image){Mat mask_image;threshold(image,mask_image,150,255,THRESH_BINARY_INV);  //图像进行二值化// 创建结构元素 扫描核int kernel_size =1;cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT,cv::Size(2 * kernel_size + 1, 2 * kernel_size + 1),cv::Point(-1, -1));// 执行腐蚀操作cv::Mat eroded_image;cv::erode(mask_image, eroded_image, element,Point(-1,-1),1);// 显示结果图像cv::imshow("Original Image", mask_image);cv::imshow("Eroded Image", eroded_image);waitKey();
}
int main()
{string imagePath = "C:\\Users\\Marxist\\Pictures\\coco\\eroding_test.jpg";string mix_image_path = "C:\\Users\\Marxist\\Pictures\\coco\\Linux.jpg";Mat image = imread(imagePath,IMREAD_GRAYSCALE);//读取灰度图像morphology_op_demo(image);return 0;
}

关键解析:

cv::erode(mask_image, eroded_image, element,Point(-1,-1),1);

函数原型:

CV_EXPORTS_W void erode( InputArray src, OutputArray dst, InputArray kernel,Point anchor = Point(-1,-1), int iterations = 1,int borderType = BORDER_CONSTANT,const Scalar& borderValue = morphologyDefaultBorderValue() );

与膨胀API参数一致,但效果相反

腐蚀操作—内核大小3*3 迭代1次,噪点明显消除

在这里插入图片描述

腐蚀操作—内核大小5*5 迭代1次,噪点完全消除,但是图像细节也跟着丢失了

在这里插入图片描述

面对图像丢失的情况,可以进行开闭运算了

开运算—先腐蚀后膨胀

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

关键函数:

  morphologyEx(mask_image, opening_image, MORPH_OPEN, element);

本质上就是调用了腐蚀API和膨胀API,OpenCV为了代码简洁,将二个API 合成了一个

示例代码

//形态学操作 膨胀 腐蚀 ,开操作, 闭操作
void morphology_op_demo(Mat &image){Mat mask_image;threshold(image,mask_image,150,255,THRESH_BINARY_INV);  //图像进行二值化// 创建结构元素 扫描核int kernel_size =2;cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT,cv::Size(2 * kernel_size + 1, 2 * kernel_size + 1),cv::Point(-1, -1));// 执行腐蚀操作cv::Mat eroded_image;cv::erode(mask_image, eroded_image, element,Point(-1,-1),1);Mat final;// 先执行 腐蚀 然后执行膨胀morphologyEx(mask_image, final, MORPH_OPEN, element);cv::imshow("Original Image", mask_image);cv::imshow("Eroded Image", eroded_image);cv::imshow("final Image", final);waitKey();
}
int main()
{string imagePath = "C:\\Users\\Marxist\\Pictures\\coco\\eroding_test.jpg";string mix_image_path = "C:\\Users\\Marxist\\Pictures\\coco\\Linux.jpg";Mat image = imread(imagePath,IMREAD_GRAYSCALE);//读取灰度图像morphology_op_demo(image);return 0;
}

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

在这里插入图片描述

闭运算—先膨胀后腐蚀

//形态学操作 膨胀 腐蚀 ,开操作, 闭操作
void morphology_op_demo(Mat &image){Mat mask_image;threshold(image,mask_image,150,255,THRESH_BINARY_INV);  //图像进行二值化// 创建结构元素 扫描核int kernel_size =2;cv::Mat element = cv::getStructuringElement(cv::MORPH_RECT,cv::Size(2 * kernel_size + 1, 2 * kernel_size + 1),cv::Point(-1, -1));// 执行膨胀操作cv::Mat eroded_image;cv::dilate(mask_image, eroded_image, element,Point(-1,-1),1);Mat final;// 先执行 腐蚀 然后执行膨胀morphologyEx(mask_image, final, MORPH_CLOSE, element);cv::imshow("Original Image", mask_image);cv::imshow("Eroded Image", eroded_image);cv::imshow("final Image", final);waitKey();
}
int main()
{string imagePath = "C:\\Users\\Marxist\\Pictures\\coco\\dilation_test.jpg";string mix_image_path = "C:\\Users\\Marxist\\Pictures\\coco\\Linux.jpg";Mat image = imread(imagePath,IMREAD_GRAYSCALE);//读取灰度图像morphology_op_demo(image);return 0;
}

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

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

在这里插入图片描述

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

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

相关文章

go语言Gin框架的学习路线(十一)

目录 GORM的CRUD教程 更新操作 更新所有字段 更新指定字段 使用 Select 和 Omit 更新 无 Hooks 更新 批量更新 删除操作 删除记录 批量删除 软删除 物理删除 示例代码 GORM的CRUD教程 CRUD 是 "Create, Read, Update, Delete"(创建、查询、…

Google Cloud Platform数据工程简介

Google Cloud Platform数据工程简介 前言 云计算的出现为数据驱动型组织提供了采用成本效益高且可扩展的数据工程解决方案的机会。在云服务提供商中,Google Cloud Platform (GCP) 是近年来表现优异的领导者之一。GCP的增长被归因于其在企业和初创公司中的日益普及…

【TypeScript 一点点教程】

文章目录 一、开发环境搭建二、基本类型2.1 类型声明2.2 基本类型 三、编译3.1 tsc命令3.2 tsconfig.json3.2.1 基本配置项includeexcludeextendsfiles 3.2.2 compilerOptions编译器的配置项 四、面向对象4.1 类4.2 继承4.3 抽象类4.4 接口 一、开发环境搭建 下载Node.js《Nod…

【全国大学生电子设计竞赛】2023年B题

🥰🥰全国大学生电子设计大赛学习资料专栏已开启,限时免费,速速收藏~

IP数据报结构详解:从基础到进阶

目录 IP数据报的格式 IP数据报首部的固定部分 IP数据报首部的可变部分 实例分析:数据报的分片 生存时间(TTL)与协议 首部检验和 总结 在网络通信中,IP数据报是至关重要的基本单元。本文将带您深入了解IP数据报的格式及其各个…

Python酷库之旅-第三方库Pandas(041)

目录 一、用法精讲 136、pandas.Series.ne方法 136-1、语法 136-2、参数 136-3、功能 136-4、返回值 136-5、说明 136-6、用法 136-6-1、数据准备 136-6-2、代码示例 136-6-3、结果输出 137、pandas.Series.eq方法 137-1、语法 137-2、参数 137-3、功能 137-4、…

数据结构-C语言-排序(4)

代码位置: test-c-2024: 对C语言习题代码的练习 (gitee.com) 一、前言: 1.1-排序定义: 排序就是将一组杂乱无章的数据按照一定的规律(升序或降序)组织起来。(注:我们这里的排序采用的都为升序) 1.2-排…

如何借助生成式人工智能引领未来的科技狂潮

如何借助生成式人工智能引领未来的科技狂潮 1. 生成式AI的现状1.1 技术基础1.1.1 深度学习1.1.2 生成对抗网络(GANs)1.1.3 变分自编码器(VAEs) 1.2 主要应用1.2.1 语言模型1.2.2 图像生成1.2.3 音频与视频生成 2. 未来的发展趋势2…

Windows下帆软BI(finebi)单机部署移植(Tomcat)攻略

一、基础环境 操作系统:Windows 10 64bit 帆软BI 版本:V9.0/V10.0 HTTP工具:Tomcat 外置数据库:Oracle 11g 实验内容:将已经部署好的帆软BI从一台电脑移植到另一台电脑 二、前期准备 1、做好外置数据库移植&…

<数据集>苹果腐烂识别数据集<目标检测>

数据集格式:VOCYOLO格式 图片数量:978张 标注数量(xml文件个数):978 标注数量(txt文件个数):978 标注类别数:2 标注类别名称:[fresh_apple, rotten_apple] 序号类别名称图片数框数1fresh_apple520922…

2022 年中高职组“网络安全”赛项-海南省省竞赛任务书-1-B模块-B-4Web渗透测试

前言 本章节我将尝试操作B-4模块的渗透测试,搭建环境很难,还望大家点点赞多多支持! 任务概览 最后4、5、6有一定的难度。 环境要求 kali Linux192.168.41.2Web服务器(假设为PYsystem 2020 模拟平台)192.168.41.7交换…

日常开发记录分享——C#控件ToolTip实现分栏显示内容

文章目录 需求来源实现思路实施请看VCR等等别走,有优化 需求来源 需要在鼠标浮动到指定位置后提示出详细的信息,一开始使用的tooltip实现,但是里面的内容效果并不理想,需要有条理性,于是就想到能不能将展示的东西分列…

代理协议解析:如何根据需求选择HTTP、HTTPS或SOCKS5?

代理IP协议是一种网络代理技术,可以实现隐藏客户端IP地址、加速网站访问、过滤网络内容、访问内网资源等功能。常用的IP代理协议主要有Socks5代理、HTTP代理、HTTPS代理这三种。代理IP协议主要用于分组交换计算机通信网络的互联系统中使用,只负责数据的路…

Linux(CentOS)的“应用商城” —— yum

Linux(CentOS)的“应用商城” —— yum 关于 yum 和软件包Linux 系统(CentOS)的生态yum 相关操作yum 本地配置yum 安装 lrzsz.x86_64 关于 yum 和软件包 首先 yum 是软件下载安装管理的客户端,类似各种手机里的“应用…

面试场景题系列--(1)如果系统的 QPS 突然提升 10 倍该怎么设计?--xunznux

1. 如果系统的 QPS 突然提升 10 倍该怎么设计? 1.1 硬件的扩展微服务的拆分 如果所有的业务包括交易系统、会员信息、库存、商品等等都夹杂在一起,当流量一旦起来之后,单体架构的问题就暴露出来了,机器挂了所有的业务就全部无法…

【机器学习】Jupyter Notebook如何使用之基本步骤和进阶操作

引言 Jupyter Notebook 是一个交互式计算环境,它允许创建包含代码、文本和可视化内容的文档 文章目录 引言一、基本步骤1.1 启动 Jupyter Notebook1.2 使用 Jupyter Notebook 仪表板1.3 在笔记本中工作1.4 常用快捷键1.5 导出和分享笔记本 二、进阶用法2.1 组织笔…

“微软蓝屏”事件,给IT行业带来的宝贵经验和教训

“微软蓝屏”事件是指2024年7月19日发生的一次全球性技术故障,主要涉及微软视窗(Windows)操作系统及其相关应用和服务。 以下是对该事件的详细解析: 一、事件概述 发生时间:2024年7月19日事件影响:全球多个…

暑期c++ 命名空间

今天是暑期第一天开始写c笔记&#xff0c;新起点&#xff0c;新开始加油 我们先来看两串代码 这串代码编译没有问题 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> int rand 14; int main(void) {int rand 14;printf("%d\n", rand);return 0; }但是…

鸽哒IM即时通讯安卓+苹果双系统源码20240723(反编译+二次开发版)

功能特点&#xff1a; 1、该软件支持加好友、消息私聊、消息群聊、朋友圈、红包、语音、视频、表情包&#xff0c;定位等。 2、此外&#xff0c;该软件还支持阅后即焚、消息过期自动销毁、支持3DES加密传输、支持端到端传输&#xff0c;保护消息隐私。 3、后台使用的是酷信的…

Java面试八股之详细阐述Spring的DI和IOC

详细阐述Spring的DI和IOC Spring框架的两大核心特性之一就是控制反转&#xff08;Inversion of Control, IoC&#xff09;&#xff0c;另一个密切相关的是依赖注入&#xff08;Dependency Injection, DI&#xff09;。这两个概念是Spring实现松耦合、可测试和可管理软件组件的…