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

news2024/9/20 1:04:24

文章目录

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

形态学概念

首先看这两张图片

在这里插入图片描述

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

这就是形态学操作发挥作用的地方,形态学(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.coloradmin.cn/o/1944142.html

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

相关文章

安宝特方案|解放双手,解决死角,AR带来质量监督新体验

AR质量监督 解放双手,解决死角 在当今制造业快速发展的背景下,质量监督成为确保产品高质量和完善的管理制度的关键环节。然而,传统的质量监督方式存在诸多挑战,如人工操作带来的效率低下、查岗不及时、摄像头死角等问题。 为了解…

el-upload照片墙自定义上传多张图片(手动一次性上传多张图片)包含图片回显,删除

需求:el-upload照片墙自定义上传多张图片(手动一次性上传多张图片)包含图片回显,删除,预览,在网上看了很多,都没有说怎么把数据转为file格式的,找了很久最终实现, 难点&a…

Java之数组应用-选择排序-插入排序

已经完全掌握了冒泡排序和二分查找的同学,可以自己尝试学习选择、插入排序。不要求今天全部掌握,最近2-3天掌握即可! 1 选择排序 选择排序(Selection Sort)的原理有点类似插入排序,也分已排序区间和未排序区间。但是选择排序每次…

《峡谷小狐仙-多模态角色扮演游戏助手》复现流程

YongXie66/Honor-of-Kings_RolePlay: The Role Playing Project of Honor-of-Kings Based on LnternLM2。峡谷小狐仙--王者荣耀领域的角色扮演聊天机器人,结合多模态技术将英雄妲己的形象带入大模型中。 (github.com) https://github.com/chg0901/Honor_of_Kings…

盘点2024年大家都在使用的AI智能写作工具

在科技发达的现在社会,AI已经悄悄的渗入我们生活的各种角落。不知道你有没有尝试过用ai智能写作来完成一些文章创作呢?这次我介绍几个可以提升效率的ai智能写作工具给你试试吧。 1.笔|灵AI写作 CSDN 传送门:https://ibiling.cn…

Interesting bug caused by getattr

题意:由 getattr 引起的有趣的 bug 问题背景: I try to train 8 CNN models with the same structures simultaneously. After training a model on a batch, I need to synchronize the weights of the feature extraction layers in other 7 models. …

Vue3+Element Plus 实现table表格中input的验证

实现效果 html部分 <template><div class"table"><el-form ref"tableFormRef" :model"form"><el-table :data"form.detailList"><el-table-column type"selection" width"55" align&…

初识c++(string和模拟实现string)

一、标准库中的string类 string类的文档介绍&#xff1a;cplusplus.com/reference/string/string/?kwstring 1、auto和范围for auto&#xff1a; 在早期C/C中auto的含义是&#xff1a;使用auto修饰的变量&#xff0c;是具有自动存储器的局部变量&#xff0c;后来这个 不重…

【北航主办丨本届SPIE独立出版丨已确认ISSN号】第三届智能机械与人机交互技术学术会议(IHCIT 2024,7月27)

由北京航空航天大学指导&#xff0c;北京航空航天大学自动化科学与电气工程学院主办&#xff0c;AEIC学术交流中心承办的第三届智能机械与人机交互技术学术会议&#xff08;IHCIT 2024&#xff09;将定于2024年7月27日于中国杭州召开。 大会面向基础与前沿、学科与产业&#xf…

初识c++:string类 (1)

目录 # 初识c&#xff1a;string类 1.为什么学习string类 2.标准库中的string类 2.1 string类的了解 2.2 auto和范围for 2.3 string类的常用接口说明 2.3.1string类对象的常见构造 2.3.2string类对象的容量操作 2.3.3string类对象的访问及遍历操作 2.3.4string类对象…

DNS概述及DNS服务器的搭建(twelve day)

回顾 关闭防火墙 systemctl stop firewalld 永久停止防火墙 systemctl disable firewalld 关闭selinux setenforce 0 永久关闭selinux安全架构 vim /etc/selinux/config 修改静态IP地址 vim /etc/sysconfig/network-scripts/ifcfg-ens160 #修改uuid的目的是为了保证网络的唯一…

计算机的错误计算(四十)

摘要 计算机的错误计算&#xff08;三十九&#xff09;阐明有时计算机将0算成非0&#xff0c;非0算成0&#xff1b;并且前面介绍的这些错误计算相对来说均是由软件完成。本节讨论手持式计算器对这些算式的计算效果。 例1. 用手持式计算器计算 与 . 我们用同一个计算器计算…

机械学习—零基础学习日志(高数10——函数图形)

零基础为了学人工智能&#xff0c;真的开始复习高数 函数图像&#xff0c;开始新的学习&#xff01;本次就多做一做题目&#xff01; 第一题&#xff1a; 这个解法是有点不太懂的了。以后再多研究一下。再出一道题目。 张宇老师&#xff0c;比较多提示了大家&#xff0c;一定…

哪些工作可以年入几十万到2亿?

关注卢松松&#xff0c;会经常给你分享一些我的经验和观点。 从今年起&#xff0c; 每个月都会有年入几十万到2亿的新闻案例出来&#xff0c;而且很多都是官方媒体发的&#xff0c;你们看看&#xff1a; 7月19日35岁小伙扛楼一年多存了40万 7月4日老板娘一天卖出200斤知了日入…

Leetcode3217. 从链表中移除在数组中存在的节点

Every day a Leetcode 题目来源&#xff1a;3217. 从链表中移除在数组中存在的节点 解法1&#xff1a;集合 链表遍历 代码&#xff1a; /** lc appleetcode.cn id3217 langcpp** [3217] 从链表中移除在数组中存在的节点*/// lc codestart /*** Definition for singly-link…

docker--容器数据进行持久化存储的三种方式

文章目录 为什么Docker容器需要使用持久化存储1.什么是Docker容器&#xff1f;2.什么是持久化存储&#xff1f;3.为什么Docker容器需要持久化存储&#xff1f;4.Docker如何实现持久化存储&#xff1f;(1)、Docker卷(Volumes)简介适用环境:使用场景:使用案例: (2)、绑定挂载&…

Python 实现PDF和TIFF图像之间的相互转换

PDF是数据文档管理领域常用格式之一&#xff0c;主要用于存储和共享包含文本、图像、表格、链接等的复杂文档。而TIFF&#xff08;Tagged Image File Format&#xff09;常见于图像处理领域&#xff0c;主要用于高质量的图像文件存储。 在实际应用中&#xff0c;我们可能有时需…

哪个邮箱最安全最好用啊

企业邮箱安全至关重要&#xff0c;需保护隐私、防财务损失、维护通信安全、避免纠纷&#xff0c;并维持业务连续性。哪个企业邮箱最安全好用呢&#xff1f;Zoho企业邮箱&#xff0c;采用加密技术、反垃圾邮件和病毒保护&#xff0c;支持多因素认证&#xff0c;确保数据安全合规…

php的文件上传

&#x1f3bc;个人主页&#xff1a;金灰 &#x1f60e;作者简介:一名简单的大一学生;易编橙终身成长社群的嘉宾.✨ 专注网络空间安全服务,期待与您的交流分享~ 感谢您的点赞、关注、评论、收藏、是对我最大的认可和支持&#xff01;❤️ &#x1f34a;易编橙终身成长社群&#…

【每日刷题Day85】

【每日刷题Day85】 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;每日刷题&#x1f34d; &#x1f33c;文章目录&#x1f33c; 1. 125. 验证回文串 - 力扣&#xff08;LeetCode&#xff09; 2. 43. 字符串相乘 - 力扣&#xff08;L…