基于OpenCV [c++]——形态学操作(分析和应用)

news2024/11/24 1:19:58

摘要:

形态学一般指生物学中研究动物和植物结构的一个分支。用数学形态学(也称图像代数)表示以形态为基础对图像进行分析的数学工具。

基本思想是用具有一定形态的结构元素去度量和提取图像中的对应形状以达到对图像分析和识别的目的。

形态学图像处理的基本运算有:

  • 膨胀和腐蚀(膨胀区域填充,腐蚀分割区域)
  • 开运算和闭运算(开运算去除噪点,闭运算填充内部孔洞)
  • 击中与击不中
  • 顶帽变换,黑帽变换

形态学的应用:消除噪声、边界提取、区域填充、连通分量提取、凸壳、细化、粗化等;分割出独立的图像元素,或者图像中相邻的元素;求取图像中明显的极大值区域和极小值区域;求取图像梯度


🧡在讲各种形态学操作之前,先来看看结构元素:

膨胀和腐蚀操作的核心内容是结构元素。(后面的开闭运算等重要的也是结构元素的设计,一个合适的结构元素的设计可以带来很好的处理效果

OpenCV里面的API介绍:

Mat kernel = getStructuringElement(int shape,Size ksize,Point anchor);
shape   //结构元素的定义:形状 (MORPH_RECT \MORPH_CROSS(交叉形) \MORPH_ELLIPSE);
ksize   //结构元素大小;
anchor  //锚点 默认是Point(-1, -1)意思就是中心像素,也可以自己指定

一,腐蚀和膨胀

 腐蚀和膨胀是最基本的形态学操作,腐蚀和膨胀都是针对白色部分(高亮部分)而言的。

  • 膨胀就是使图像中高亮部分扩张,效果图拥有比原图更大的高亮区域(是求局部最大值的操作)
  • 腐蚀是原图中的高亮区域被蚕食,效果图拥有比原图更小的高亮区域(是求局部最小值的操作)

膨胀与腐蚀能实现多种多样的功能,主要如下:

1、消除噪声
2、腐蚀分割(isolate)出独立的图像元素,膨胀在图像中连接(join)相邻的元素。
3、寻找图像中的明显的极大值区域或极小值区域
4、求出图像的梯度

opencv中膨胀/腐蚀API:(两者相同)

void dilate/erode( const Mat& src,   //输入图像(任意通道的)
                         Mat& dst,   //输出图像
               const Mat& element,   //结构元素
        Point anchor=Point(-1,-1),   //中心位置锚点
                 int iterations=1,   //操作次数。省略时为默认值1。
   int borderType=BORDER_CONSTANT,   //边缘填充类型
        const Scalar& borderValue    //填充值(默认即可)
                 )

opencv实现:

    Mat src1 = imread("D:/opencv练习图片/腐蚀膨胀.png");
    Mat src_erode, src_dilate;
    imshow("原图", src1);
    Mat kernel = getStructuringElement(MORPH_RECT, Size(60, 60), Point(-1, -1));
    erode(src1, src_erode, kernel, Point(-1, -1),2);
    dilate(src1, src_dilate, kernel, Point(-1, -1),2);
    imshow("腐蚀", src_erode);
    imshow("膨胀", src_dilate);

膨胀:                                                                                腐蚀:                         

1️⃣腐蚀操作的原理就是求局部最小值的操作,并把这个最小值赋值给参考点指定的像素。这样就会使图像中的高亮区域逐渐减少。

2️⃣膨胀操作的原理就是求局部最大值的操作,并把这个最大值赋值给参考点指定的像素。这样就会使图像中的高亮区域逐渐增长。

二,高阶形态学变换

对于更加高级形态学变换就要用到morphologyEx()函数了,其函数原型如下:

void morphologyEx(
      InputArray src,            //输入图像
     OutputArray dst,            //输出图像
              int op,            //形态学运算类型
    InputArray kernel,           //结构元素
    Point anchor = Point(-1,-1), //锚点
    int iterations = 1,          //运算次数
    int borderType = BORDER_CONSTANT,
                  )

✨对于输入参数op(形态学运算类型)有以下几种参数可以设置:

  • MORPH_ERODE(腐蚀)
  • MORPH_DILATE(膨胀)
  • MORPH_OPEN(开运算)
  • MORPH_CLOSE(闭运算)
  • MORPH_GRADIENT(形态学梯度,即膨胀图减腐蚀图)
  • MORPH_TOPHAT(顶帽运算)
  • MORPH_BLACKHAT(底帽运算)
  • MORPH_HITMISS(击中与击不中)

🧡开运算和顶帽运算

开运算就是先腐蚀膨胀。作用:用来消除图像中细小对象,在纤细点处分离物体和平滑较大物体的边界而有不明显改变其面积和形状。

顶帽运算就是图与原图的开运算的差值图像。作用:

1️⃣:得到开运算消除的区域(检查开运算效果)

2️⃣:校正不均匀光照的影响(用于暗背景上的亮物体,去光差)

 opencv实现:

    Mat src1 = imread("D:/opencv练习图片/开运算.png");
    Mat src_open, src_tophat;
    imshow("原图", src1);
    Mat kernel = getStructuringElement(MORPH_RECT, Size(7, 7), Point(-1, -1));
    morphologyEx(src1, src_open, MORPH_OPEN, kernel,Point(-1, -1));//开运算
    morphologyEx(src1, src_tophat, MORPH_TOPHAT, kernel, Point(-1, -1));//顶帽运算
    imshow("开运算", src_open);
    imshow("顶帽运算", src_tophat);

开运算:                                                                      顶帽运算:(可以用来观察开运算的效果)

 

 💛闭运算和底帽运算

闭运算就是先膨胀后腐蚀。作用:用来填充目标内部的细小孔洞(fill hole),将断开的邻近目标连接,在不明显改变物体面积和形状的情况下平滑其边界。

底帽运算就是图与原图的闭运算的差值图像。作用:

1️⃣:闭运算是去噪点的过程,所以黑帽操作实质上保留的是噪点的部分。

2️⃣:校正不均匀光照的影响(用于亮(白)背景上的暗物体)

  opencv实现:

    Mat src1 = imread("D:/opencv练习图片/闭运算.png");
    Mat src_close, src_blackhat;
    imshow("原图", src1);
    Mat kernel = getStructuringElement(MORPH_RECT, Size(7, 7), Point(-1, -1));
    morphologyEx(src1, src_close, MORPH_CLOSE, kernel,Point(-1, -1));//闭运算
    morphologyEx(src1, src_blackhat, MORPH_BLACKHAT, kernel, Point(-1, -1));//底帽运算
    imshow("闭运算", src_close);
    imshow("底帽运算", src_blackhat);

 闭运算:                                                                    底帽运算:

 💚形态学梯度(求二值图边缘)

 图像形态学的梯度跟我们前面介绍的图像卷积计算出来的梯度有本质不同,形态学梯度可以帮助我们获得连通组件的边缘与轮廓,实现图像轮廓或者边缘提取。

根据使用的形态学操作不同,形态学梯度又分为:

  • 基本梯度(图像膨胀与腐蚀操作之间的差值)
  • 内梯度(输入图像与腐蚀之间的差值)
  • 外梯度(膨胀与输入图像之间的差值)

opencv实现:

Mat src1 = imread("D:/opencv练习图片/腐蚀膨胀.png");
    Mat src_giad1, src_exter,src_inter,src_dilate,src_erode;
    imshow("原图", src1);
    Mat kernel = getStructuringElement(MORPH_RECT, Size(7, 7), Point(-1, -1));
    //基本梯度
    morphologyEx(src1, src_giad1, MORPH_GRADIENT, kernel,Point(-1, -1));
    imshow("基本梯度", src_giad1);
    //外梯度
    morphologyEx(src1, src_dilate, MORPH_DILATE, kernel, Point(-1, -1));
    subtract(src_dilate, src1, src_exter);//求差值
    imshow("外梯度", src_exter);
    //内梯度
    morphologyEx(src1, src_erode, MORPH_ERODE, kernel, Point(-1, -1));
    subtract(src1, src_erode, src_inter);
    imshow("内梯度", src_inter);

 外梯度:                                                                      内梯度:

 内外梯度区别不是很大。。。

💙击中与击不中

形态学的击中击不中操作, 击中击不中也是基础形态学操作组合,它可以实现对象的细化跟剪枝操作,根据结构元素不同,可以提取二值图像中的一些特殊区域,得到我们想要的结果。并且击中击不中操作在二值图像的模式匹配跟发现上也非常有用

Hit-miss算法步骤(两次腐蚀,求交集):

击中击不中变换是形态学中用来检测特定形状所处位置的一个基本工具。它的原理就是使用腐蚀;如果要在一幅图像A上找到B形状的目标,我们要做的是:

  • 首先,建立一个比B大的结构元素B1;使用B1对图像A进行腐蚀,得到图像假设为A_B1;
  • 其次,用B减去B1,从而得到结构元素B2(B2-B);使用B2对图像A的补集进行腐蚀,得到图像假设为A_B2;
  • 然后,A_B1与A_B2取交集;得到的结果就是B的位置。

opencv实战(利用击中与击不中,提取网绳的结点位置):

Mat src = imread("D:/opencv练习图片/击中与击不中.png");
    imshow("原图", src);
    // 二值图像
    Mat gray, binary, hitImg;
    cvtColor(src, gray, COLOR_BGR2GRAY);
    //高斯滤波
    Mat gauss;
    GaussianBlur(gray, gauss, Size(5, 5), 0, 0);
    //二值化
    threshold(gauss, binary, 0, 255, THRESH_BINARY_INV | THRESH_OTSU);
    imshow("binary", binary);
    // 定义结构元素
    Mat se = getStructuringElement(MORPH_CROSS, Size(11, 11), Point(-1, -1));
    // 击中击不中
    morphologyEx(binary, hitImg, MORPH_HITMISS, se);
    imshow("击中击不中", hitImg);
    //膨胀一下
    Mat openImg;
    Mat kern2 = getStructuringElement(MORPH_RECT, Size(3, 3));
    morphologyEx(hitImg, openImg, MORPH_OPEN, kern2, Point(-1, -1), 2);
    imshow("dilate", openImg);
    //寻找轮廓
    vector<vector<Point>>contours;
    vector<Vec4i>hie;
    findContours(openImg, contours, hie, RETR_TREE, CHAIN_APPROX_SIMPLE, Point());
    for (size_t i = 0; i < contours.size(); i++)
    {
        double area = contourArea(contours[i]);
        if (area < 20.0)continue;
        Rect rect = boundingRect(contours[i]);
        rectangle(src, rect, Scalar(0, 0, 255), 1, 8);

    }
    // 显示
    imshow("结果", src);

 

 

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

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

相关文章

这篇文章把MOS管的基础知识讲透了

MOS管&#xff08;Metal-Oxide-Semiconductor field-effect transistor&#xff09;是一种常见的半导体器件&#xff0c;它在数字电路、模拟电路、功率电子等领域都有广泛的应用。本文将从MOS管的基本结构、工作原理、参数特性等方面讲解MOS管的基础知识。 一、MOS管的基本结构…

MediaPlayer error(-38, 0) 异常处理

文章目录 1、参考资料2、业务背景3、解决方案 1、参考资料 Media Player called in state 0, error (-38,0) MediaPlayer的使用 2、业务背景 对时长超过 5s 的音频提供裁剪、试听功能&#xff0c;裁剪、试听最大时长均为 5s。当视频长度在 5s ~ 6s 之间&#xff0c;试听暂停…

Flink on yarn任务日志怎么看

1、jobmanager日志 在yarn上可以直接看 2、taskmanager日志 在flink的webui中可以看&#xff0c;但是flink任务失败后&#xff0c;webui就不存在了&#xff0c;那怎么看&#xff1f; 这是jobmanager的地址 hadoop02:19888/jobhistory/logs/hadoop02:45454/container_e03_16844…

Apache应用和配置

目录 构建虚拟 Web 主机基于域名的虚拟主机基于IP地址的虚拟主机基于端口的虚拟主机 Apache 连接保持构建Web虚拟目录与用户授权限制Apache 日志分割 构建虚拟 Web 主机 虚拟Web主机指的是在同一台服务器中运行多个Web站点&#xff0c;其中每一个站点实际上并不独立占用整个服务…

【发电机、输变电JDL-5400A 电流继电器 报警信号切除故障JOSEF约瑟】

名称&#xff1a;电流继电器&#xff1b;品牌&#xff1a;JOSEF约瑟&#xff1b;型号&#xff1a;JDL-5400A&#xff1b;触点容量&#xff1a;250V2A&#xff1b;返回时间&#xff1a;≤35ms&#xff1b;整定范围&#xff1a;0.03-19.9A&#xff1b;特点&#xff1a;返回系数高…

应用案例 | 升级OPC Classic到OPC UA,实现安全高效的数据通信

一 背景 OPC&#xff08;OLE for Process Control&#xff0c;用于过程控制的OLE&#xff09;是工业自动化领域中常见的通信协议。它提供了一种标准化的方式&#xff0c;使得不同厂商的设备和软件可互相通信和交换数据。OPC Classic是旧版OPC规范&#xff0c;通过使用COM&…

LabVIEWCompactRIO 开发指南第六章42

LabVIEWCompactRIO 开发指南第六章42 要使用用户控制的I/O示例方法进行编程&#xff0c;请按照以下步骤操作&#xff0c;这些步骤引用了图6.9中的示例程序。 初始化进程 1.调用重置I/O函数。此调用完成后&#xff0c;模块已准备好使用用户控制的I/O采样函数执行采集。必须首…

财务共享五大价值助力央企构建世界一流财务管理体系

如果说小微企业是我国市场经济的毛细血管的话&#xff0c;那么央企就是承载着我国市场发展的主动脉。以规模为导向来看&#xff0c;央企完成了第一次长征&#xff0c;但央企在盈利能力、市场份额、行业地位、专利技术与优势、品牌影响力、市值管理、标准和规则制定话语权等软实…

从1万张模板中找的运营知识图谱,超级牛!

运营现在是时下大家都很熟悉的一个行业&#xff0c;我们熟知的有内容运营、用户运营、产品运营、新媒体运营、活动运营 社群运营、电商运营、品牌运营等多种运营方式。 想要做好运营&#xff0c;其实是需要很丰富的知识体系的&#xff0c;今天就给大家分享一些厉害的运营图谱。…

英伟达曝光超级芯片 黄仁勋:AI已重塑计算机产业

5月29日&#xff0c;英伟达再曝新品“NVIDIA DGX™超级计算机”&#xff0c;为生成式AI语言应用、推荐系统和数据分析工作负载的巨型模型提供硬件支持。 该计算机的核心组件是已经全面投产的英伟达Grace Hopper超级芯片——2000 亿个晶体管&#xff0c;在同一封装内集成了72核…

TC-PERM系列 单/双通道消光比测试仪

单/双通道消光比测试仪可独立进行偏振消光比测试、光功率测试、数字调零、数字校准、手动或自动选择量程&#xff0c;配备 USB(RS232) 接口&#xff0c;上位机软件可自动进行数据测试、 记录、分析&#xff0c;可方便地组成自动测试系统。 广泛应用于光通信设备、光纤、光无源器…

Deep Frequency Filtering for Domain Generalization论文阅读笔记

这是CVPR2023的一篇论文&#xff0c;讲的是在频域做domain generalization&#xff0c;找到频域中generalizable的分量enhance它&#xff0c;suppress那些影响generalization的分量 DG是一个研究模型泛化性的领域&#xff0c;尝试通过各自方法使得模型在未见过的测试集上有良好…

zabbix监控山石防火墙

一、导入监控模板 <Template Net Hillstone StoneOS SNMPv2> 导入前请确保zabbix内置的模板Template Net Network Generic Device SNMPv2存在。 支持山石E系列和X系列防火墙 兼容Zabbix 4.x和5.x。 二、监控内容 SNMP状态和接口速率由Template Net Network Generic De…

2023年互联网Java工程师高级面试八股文汇总(1260道题目附解析)

今年的行情&#xff0c;让招聘面试变得雪上加霜。已经有不少大厂&#xff0c;如腾讯、字节跳动的招聘名额明显减少&#xff0c;面试门槛却一再拔高&#xff0c;如果不用心准备&#xff0c;很可能就被面试官怼得哑口无言&#xff0c;甚至失去了难得的机会。 现如今&#xff0c;情…

基于imx8m plus开发板全体系开发教程5:Cortex-M7开发

前言&#xff1a; i.MX8M Plus 开发板是一款拥有 4 个 Cortex-A53 核心&#xff0c;运行频率 1.8GHz;1 个 Cortex-M7 核心&#xff0c;运行频率 800MHz;此外还集成了一个 2.3 TOPS 的 NPU&#xff0c;大大加速机器学习推理。 全文所使用的开发平台均为与NXP官方合作的FS-IMX8…

Linux Apache 网页优化【网页压缩 网页缓存 隐藏版本号 防盗链】

Apache 网页与安全优化 在企业中&#xff0c;部署Apache后只采用默认的配置参数&#xff0c;会引发网站很多问题&#xff0c;换言之默认配置是针对以前较低的服务器配置的&#xff0c;以前的配置已经不适用当今互联网时代。 为了适应企业需求&#xff0c;就需要考虑如何提升Apa…

网络安全合规-数据分类分级(三)

概念定义 数据分类分级应该将分类和分级分开进行理解。 分类指根据数据的用途和含义去定义数据。更偏向数据治理&#xff0c;而非数据安全治理。 分级指依据数据分类的结果以及数据价值对数据进行分级。是数据安全治理的范畴。 分级类别及依据目前大部分标准将分级定义为核心、…

代码自动生成:低代码与人工智能。

代码自动生成&#xff1a;低代码与人工智能TOC 在当前gpt大行其道的情况下&#xff0c;很多人都对自动生成代码感兴趣。这里将讨论一些与代码自动生成有关的话题&#xff1a; 严格的、闭包的、无歧义的范式系统是代码自动生成的前提与保障&#xff0c;没有这样的范式系统&…

微服务框架01--了解了解Spring Cloud

1.Spring Cloud简介 Spring Cloud是基于Spring Boot的一整套实现微服务的框架。他提供了微服 务开发所需的配置管理、服务注册与发现、断路器、智能路由、微代理、控制 总线、全局锁、决策竞选、分布式会话和集群状态管理等组件。最重要的是跟 Spring Boot框架一起使用的话&am…

有哪些代码编辑器可以推荐? - 易智编译EaseEditing

以下是一些常用的代码编辑器&#xff0c;并对它们进行简单介绍&#xff1a; Visual Studio Code&#xff1a; Visual Studio Code&#xff08;简称VS Code&#xff09;是由微软开发的免费、跨平台的代码编辑器。 它具有丰富的功能和插件生态系统&#xff0c;支持多种编程语言…