当前位置: 首页 > news >正文

08- OpenCV:形态学操作(膨胀与腐蚀 、提取水平与垂直线)

目录

前言

一、膨胀(Dilation)与 腐蚀(Erosion)

二、形态学操作

1、开操作(Opening)

2、闭操作(Closing)

3、形态学梯度(Morphological Gradient)

4、顶帽 ( top hat)

5、黑帽 ( black hat)

6、相关的API

7、代码演示

三、形态学操作应用-提取水平与垂直线

1、原理方法

2、实现步骤


前言

1、了解图像形态学

图像形态学操作是一种基于图像形状的图像处理方法,常用于图像分割、边缘检测、图像增强等领域。

2、图像形态学主要包括腐蚀(Erosion)、膨胀(Dilation)、开运算(Opening)、闭运算(Closing)等操作。

除了以上基本操作,还有其他形态学操作,如击中击不中变换(Hit-or-Miss Transform)、顶帽运算(Top Hat Transform)和黑帽运算(Black Hat Transform)等。

这些图像形态学操作可以通过OpenCV库中的函数进行实现,例如cv::erodecv::dilatecv::morphologyEx等函数。

3、膨胀与腐蚀是图像处理中最常用得形态学手段。

一、膨胀(Dilation)与 腐蚀(Erosion)

通俗来讲:膨胀是用来处理缺陷问题,腐蚀用来处理毛刺问题。

所以膨胀过后的图像边界看起来更加清晰;腐蚀后的图像去除噪点,边界模糊了。

1、膨胀含义:

将图像中的前景物体进行扩张,通过在图像上滑动一个结构元素,当结构元素与前景物体有重叠时,将该像素置为1(白色)。膨胀操作可以填充物体内部的空洞,同时使物体边界变得更加清晰。

跟卷积操作类似,假设有图像A和结构元素B,结构元素B在A上面移动,其中B定义其中心为锚点,计算B覆盖下A的最大像素值用来替换锚点的像素,其中B作为结构体可以是任意形状。

 2、腐蚀含义:

将图像中的前景物体进行收缩,通过在图像上滑动一个结构元素,当结构元素完全覆盖住前景物体时,将该像素置为0(黑色)。腐蚀操作可以去除小的噪点,同时使物体边界变得模糊。

腐蚀跟膨胀操作的过程类似,唯一不同的是以最小值替换锚点重叠下图像的像素值。

3、相关的API:

(1)getStructuringElement(int shape, Size ksize, Point anchor)  

- 形状 (MORPH_RECT \MORPH_CROSS \MORPH_ELLIPSE)  

- 大小

 - 锚点 默认是Point(-1, -1)意思就是中心像素

(2)dilate(src, dst, kernel)

(3)erode(src, dst, kernel)

4、相关代码演示

#include<opencv2\opencv.hpp>
#include<iostream>int main()
{cv::Mat image = cv::imread("char.jpg", cv::IMREAD_GRAYSCALE);if (image.empty()){std::cout << "Failed to read image" << std::endl;return -1;}// 定义腐蚀和膨胀的核(结构元素)cv::Mat kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));// 腐蚀操作cv::Mat eroded_image;cv::erode(image, eroded_image, kernel);// 膨胀操作cv::Mat dilated_image;cv::dilate(image, dilated_image, kernel);cv::imshow("Original Image", image);cv::imshow("Eroded Image", eroded_image);cv::imshow("Dilated Image", dilated_image);cv::waitKey(0);cv::destroyAllWindows();return 0;
}

效果展示:

二、形态学操作

1、开操作(Opening)

先进行腐蚀操作,再进行膨胀操作。开运算可以消除小的噪点,并保持物体的整体形状不变。

(1)先腐蚀后膨胀

(2)可以去掉小的对象,假设对象是前景色,背景是黑色

2、闭操作(Closing)

先进行膨胀操作,再进行腐蚀操作。闭运算可以填充物体内部的空洞,并保持物体的整体形状不变。

(1)先膨胀后腐蚀(bin2)

(2)可以填充小的洞(fill hole),假设对象是前景色,背景是黑色

3、形态学梯度(Morphological Gradient)

(1)膨胀减去腐蚀

(2)又称为基本梯度(其它还包括-内部梯度、方向梯度)

4、顶帽 ( top hat)

顶帽 是原图像与开操作之间的差值图像

5、黑帽 ( black hat)

黑帽是闭操作图像与源图像的差值图像

6、相关的API

morphologyEx(src, dest, CV_MOP_BLACKHAT, kernel);

// 函数原型:

void morphologyEx (

InputArray src, // 输入图像,可以是单通道灰度图像或多通道彩色图像。

OutputArray dst, // 输出图像,与输入图像具有相同的尺寸和类型。

int op, // 形态学操作类型,可以是以下常量之一:

InputArray kernel, // 结构元素,用于定义形态学操作的形状和大小。可以使用cv::getStructuringElement函数创建不同形状的结构元素。

Point anchor = Point(-1,-1), // 锚点位置,默认为(-1,-1),表示结构元素的中心。

int iterations = 1, // 形态学操作的迭代次数,默认为1。

int borderType = BORDER_CONSTANT, // 边界类型,默认为BORDER_CONSTANT,表示使用常数值进行边界扩展。

const Scalar& borderValue = morphologyDefaultBorderValue() // 边界值,默认为morphologyDefaultBorderValue(),表示使用默认的边界值。

);
 

其中:

  • op:形态学操作类型,可以是以下常量之一:

    • cv::MORPH_ERODE:腐蚀操作

    • cv::MORPH_DILATE:膨胀操作

    • cv::MORPH_OPEN:开运算

    • cv::MORPH_CLOSE:闭运算

    • cv::MORPH_GRADIENT:形态学梯度

    • cv::MORPH_TOPHAT:顶帽运算

    • cv::MORPH_BLACKHAT:黑帽运算

7、代码演示
#include <opencv2/opencv.hpp>
#include <iostream>
#include <math.h>using namespace cv;
int main(int argc, char** argv) {Mat src, dst;src = imread("D:/vcprojects/images/bin2.png");if (!src.data) {printf("could not load image...\n");}namedWindow("input image", CV_WINDOW_AUTOSIZE);imshow("input image", src);char output_title[] = "morphology demo";namedWindow(output_title, CV_WINDOW_AUTOSIZE);Mat kernel = getStructuringElement(MORPH_RECT, Size(11, 11), Point(-1, -1));morphologyEx(src, dst, CV_MOP_BLACKHAT, kernel);imshow(output_title, dst);waitKey(0);return 0;
}

效果展示:(黑帽 CV_MOP_BLACKHAT)

三、形态学操作应用-提取水平与垂直线

1、原理方法

图像形态学操作时候,可以通过自定义的结构元素实现结构元素 对输入图像一些对象敏感、另外一些对象不敏感,这样就会让敏 感的对象改变而不敏感的对象保留输出。

通过使用两个最基本的 形态学操作 – 膨胀与腐蚀,使用不同的结构元素实现对输入图像 的操作、得到想要的结果。

(1)膨胀,输出的像素值是结构元素覆盖下输入图像的最大像素值

二值图像与灰度图像上的膨胀操作:

(2)腐蚀,输出的像素值是结构元素覆盖下输入图像的最小像素值

二值图像与灰度图像上的腐蚀操作

(3)结构元素

        1)上述膨胀与腐蚀过程可以使用任意的结构元素

        2)常见的形状:矩形、园、直线、磁盘形状、砖石形状等各种自定义形状。

2、实现步骤

(1)输入图像彩色图像 imread

(2)转换为灰度图像 – cvtColor

(3)转换为二值图像 – adaptiveThreshold

(4)定义结构元素

(5)开操作 (腐蚀+膨胀)提取 水平与垂直线

(1)输入图像彩色图像 imread

(2)转换为灰度图像 – cvtColor

(3)转换为二值图像 – adaptiveThreshold

adaptiveThreshold(

Mat src, // 输入的灰度图像

Mat dest, // 二值图像

double maxValue, // 二值图像最大值

int adaptiveMethod // 自适应方法,只能其中之一 –                 

                                // ADAPTIVE_THRESH_MEAN_C ,APTIVE_THRESH_GAUSSIAN_C

int thresholdType,// 阈值类型

int blockSize, // 块大小

double C // 常量C 可以是正数,0,负数

)

(4)定义结构元素

一个像素宽的水平线 -  水平长度 width/30

一个像素宽的垂直线 – 垂直长度 height/30

(5)开操作 (腐蚀+膨胀)提取 水平与垂直线

后处理

1)bitwise_not(Mat bin, Mat dst)像素取反操作,255 – SrcPixel

2)模糊(blur)

3、代码演示

#include <opencv2/opencv.hpp>
#include <iostream>using namespace cv;
int main(int argc, char** argv) {Mat src, dst;src = imread("D:/vcprojects/images/chars.png");if (!src.data) {printf("could not load image...\n");return -1;}char INPUT_WIN[] = "input image";char OUTPUT_WIN[] = "result image";namedWindow(INPUT_WIN, CV_WINDOW_AUTOSIZE);imshow(INPUT_WIN, src);Mat gray_src;cvtColor(src, gray_src, CV_BGR2GRAY);imshow("gray image", gray_src);Mat binImg;adaptiveThreshold(~gray_src, binImg, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 15, -2);imshow("binary image", binImg);// 水平结构元素Mat hline = getStructuringElement(MORPH_RECT, Size(src.cols / 16, 1), Point(-1, -1));// 垂直结构元素Mat vline = getStructuringElement(MORPH_RECT, Size(1, src.rows / 16), Point(-1, -1));// 矩形结构Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3), Point(-1, -1));Mat temp;erode(binImg, temp, kernel);dilate(temp, dst, kernel);// morphologyEx(binImg, dst, CV_MOP_OPEN, vline);// 背景变色bitwise_not(dst, dst);// 结果更加圆滑些//blur(dst, dst, Size(3, 3), Point(-1, -1));imshow("Final Result", dst);waitKey(0);return 0;
}

效果展示:

(1)水平结构元素:

先腐蚀后膨胀,相当于一开始把垂直的元素擦掉,所以就保留了水平的线。

Mat hline = getStructuringElement(MORPH_RECT, Size(src.cols / 16, 1), Point(-1, -1));

erode(binImg, temp, hline)

dilate(temp, dst, hline);

等同于:

morphologyEx(binImg, dst, CV_MOP_OPEN, hline);

(2)垂直结构元素

先腐蚀后膨胀,相当于一开始把水平的元素擦掉,所以就保留了垂直的线。

Mat vline = getStructuringElement(MORPH_RECT, Size(1, src.rows / 16), Point(-1, -1));

morphologyEx(binImg, dst, CV_MOP_OPEN, vline);

(3)矩形结构

矩形大小的干扰项都去掉。

Mat kernel = getStructuringElement(MORPH_RECT, Size(4, 4), Point(-1, -1));

morphologyEx(binImg, dst, CV_MOP_OPEN, kernel);

相关文章:

08- OpenCV:形态学操作(膨胀与腐蚀 、提取水平与垂直线)

目录 前言 一、膨胀&#xff08;Dilation&#xff09;与 腐蚀&#xff08;Erosion&#xff09; 二、形态学操作 1、开操作&#xff08;Opening&#xff09; 2、闭操作&#xff08;Closing&#xff09; 3、形态学梯度&#xff08;Morphological Gradient&#xff09; 4、…...

基于JavaWeb+SSM+Vue停车场微信小程序系统的设计和实现

基于JavaWebSSMVue停车场微信小程序系统的设计和实现 滑到文末获取源码Lun文目录前言主要技术系统设计功能截图订阅经典源码专栏Java项目精品实战案例《500套》 源码获取 滑到文末获取源码 Lun文目录 目录 1系统概述 1 1.1 研究背景 1 1.2研究目的 1 1.3系统设计思想 1 2相关…...

VUE---自定义指令

自定义指令&#xff1a;自己定义的指令&#xff0c;可以封装一些dom操作&#xff0c;扩展额外功能。可分为全局注册与 局部注册。 全局注册&#xff08;main.js中注册&#xff09;&#xff1a; Vue.directive(指令名称,{ bind(ele,binding) {}, // 只执…...

开发安全之:Cross-Site Scripting (XSS) 漏洞

近期&#xff0c;我会结合研发云陆续发布开发安全相关的文章&#xff0c;欢迎大家关注&#xff01; Overview echo json_encode($arr)&#xff1a;向一个 Web 浏览器发送了未验证的数据&#xff0c;从而导致该浏览器执行恶意代码。 Details Cross-Site Scripting (XSS) 漏洞…...

代码随想录算法训练营第二十四天| 77. 组合

77.组合 public List<List<Integer>> combine(int n, int k) {if (n < k) {return null;}List<List<Integer>> list new ArrayList<>();List<Integer> path new ArrayList<>();backSource(n, path, list, k);return list;}pu…...

虚拟歌姬学习:DiffSinger,让GitHub下载快的方法!

《三分钟上手DiffSinger》系列 ——基础篇https://www.bilibili.com/video/BV1ug4y1S7Dk/?spm_id_from333.337.search-card.all.click&vd_source124076d7d88eee393a1d8bf6fc787efa 下载DiffSinger 建议用edge浏览器还有steam&#xff0c;有时只是慢&#xff0c;但是还是…...

What is `StringEscapeUtils.escapeHtml4` does?

StringEscapeUtils.escapeHtml4 作用是将特殊字符转换为它们对应的HTML实体形式&#xff0c;从而防止这些字符在网页中被解析为HTML标签或脚本&#xff0c;有助于防止跨站脚本攻击&#xff08;XSS, Cross-Site Scripting&#xff09; 依赖 <!--org.apache.commons.text.St…...

Dubbo 的心脏:理解和应用多种协议【十三】

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 Dubbo 的心脏&#xff1a;理解和应用多种协议【十三】 前言<dubbo:protocol> 基础<dubbo:protocol> 的定义和作用微服务中协议的重要性支持的协议类型配置示例 配置基本配置参数高级配置选…...

操作系统实验报告

目录 目录 实验一 一、实验结果 实验二 使用信号量实现进程互斥与同步 一、实验结果 1. 使用信号量实现有限缓冲区的生产者和消费者问题 2. 使用信号量实现读进程具有优先权的读者和写者问题 实验三 死锁和预防 一、实验要求 二、实验内容 三、实验结果 实验四 内…...

IPv6--ACL6(IPv6访问控制列表--基本ACL6配置)

ACL基本原理 ACL由一系列规则组成,通过将报文与ACL规则进行匹配,设备可以过滤出特定的报文。 ACL的组成 ACL编号: 在网络设备上配置ACL时,每个ACL都需要分配一个编号,称为ACL编号,用来标识ACL。不同分类的ACL编号范围不同,这个后面具体讲。 规则: 前面提到了,一个AC…...

C和指针课后答案

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 前言 第八章课后答案 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参…...

C语言——大头记单词

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd; 每一发奋努力的背后&#xff0c;必有加…...

根据自己修改后的容器制作镜像并上传docker hub

要将自己的镜像上传到Docker Hub&#xff0c;可以按照以下步骤进行操作&#xff1a; 首先&#xff0c;确保已经在本地构建好了需要上传的 Docker 镜像。如果还没有构建&#xff0c;可以使用 docker build 命令来创建镜像。 登录到 Docker Hub 账号。打开终端或命令提示符&…...

Maven 基础安装配置及使用

大家好我是苏麟 , 今天聊聊Maven . Maven Maven , 是Apache公司下基于Java开发的开源项目 . 我们构建一个项目需要用到很多第三方的类库&#xff0c;需要引入大量的jar包。一个项目Jar包的数量之多往往让我们瞠目结舌&#xff0c;并且Jar包之间的关系错综复杂&#xff0c;一…...

redis 持久化机制

client redis[内存] -----> 内存数据- 数据持久化-->磁盘 Redis官方提供了两种不同的持久化方法来将数据存储到硬盘里面分别是: RDB 快照(Snapshot) AOF (Append Only File) 只追加日志文件 1 快照(Snapshot) 1. 特点 这种方式可以将某一时刻的所有数据都写入硬盘中…...

MySQL(视图,存储函数,存储过程)

作业1&#xff1a; 作业实现&#xff1a; 首先创建学生表&#xff0c;课程表&#xff0c;以及学生选课表。 CREATE TABLE Student (Sno INT PRIMARY KEY,Sname VARCHAR(20) NOT NULL,Ssex CHAR(1) CHECK (Ssex IN (男, 女)),Sage INT,SDept VARCHAR(20) DEFAULT 计算机 );CRE…...

rockchip 平台 linux FIT 打包格式介绍

1 基础介绍 FIT&#xff08;flattened image tree&#xff09;是U-Boot⽀持的⼀种新固件类型的引导⽅案&#xff0c;⽀持任意多个image打包和校 验。FIT 使⽤ its (image source file) ⽂件描述image信息&#xff0c;最后通过mkimage⼯具⽣成 itb (flattened image tree blob) …...

虚拟机安装宝塔的坑

问题&#xff1a; 在虚拟机中centos7和centos8中安装宝塔之后&#xff0c;无法访问面板。 解决&#xff1a; 1.先关闭防火墙&#xff08;如果本机能够ping通相关端口&#xff0c;则不用关闭防火墙&#xff09; 2.最新的宝塔会自动开启ssl协议&#xff0c;需要手动关闭。…...

Ubuntu使用QtCreator + CMake 开发C/C++程序

平台 OS: Ubuntu 20.04 cmake: 3.16.3 IDE: Qt Creator 4.11.1 Based on Qt 5.14.1 (GCC 5.3.1 20160406 (Red Hat 5.3.1-6), 64 bit) Built on Feb 5 2020 12:48:30 From revision b2ddeacfb5 Copyright 2008-2019 The Qt Company Ltd. All rights reserved. The program …...

【分布式监控】zabbix与grafana连接

1.在zabbix- server服务端安装grafana&#xff0c;并启动服务 先在官网下载软件 https://grafana.com/grafana/download/9.4.7?editionenterprise&pggraf&plcmtdeploy-box-1#可以翻译成中文介绍&#xff0c;很详细的教程 yum install -y https://dl.grafana.com/ent…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中&#xff0c;我们已经大致实现了rpc服务端的各项功能代…...

Leetcode 3576. Transform Array to All Equal Elements

Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接&#xff1a;3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到&#xf…...

Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)

目录 1.TCP的连接管理机制&#xff08;1&#xff09;三次握手①握手过程②对握手过程的理解 &#xff08;2&#xff09;四次挥手&#xff08;3&#xff09;握手和挥手的触发&#xff08;4&#xff09;状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...

汽车生产虚拟实训中的技能提升与生产优化​

在制造业蓬勃发展的大背景下&#xff0c;虚拟教学实训宛如一颗璀璨的新星&#xff0c;正发挥着不可或缺且日益凸显的关键作用&#xff0c;源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例&#xff0c;汽车生产线上各类…...

华为OD机试-食堂供餐-二分法

import java.util.Arrays; import java.util.Scanner;public class DemoTest3 {public static void main(String[] args) {Scanner in new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别while (in.hasNextLine()) { // 注意 while 处理多个 caseint a in.nextIn…...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心

当仓库学会“思考”&#xff0c;物流的终极形态正在诞生 想象这样的场景&#xff1a; 凌晨3点&#xff0c;某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径&#xff1b;AI视觉系统在0.1秒内扫描包裹信息&#xff1b;数字孪生平台正模拟次日峰值流量压力…...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2

每日一言 今天的每一份坚持&#xff0c;都是在为未来积攒底气。 案例&#xff1a;OLED显示一个A 这边观察到一个点&#xff0c;怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 &#xff1a; 如果代码里信号切换太快&#xff08;比如 SDA 刚变&#xff0c;SCL 立刻变&#…...

【7色560页】职场可视化逻辑图高级数据分析PPT模版

7种色调职场工作汇报PPT&#xff0c;橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版&#xff1a;职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...

基于PHP的连锁酒店管理系统

有需要请加文章底部Q哦 可远程调试 基于PHP的连锁酒店管理系统 一 介绍 连锁酒店管理系统基于原生PHP开发&#xff0c;数据库mysql&#xff0c;前端bootstrap。系统角色分为用户和管理员。 技术栈 phpmysqlbootstrapphpstudyvscode 二 功能 用户 1 注册/登录/注销 2 个人中…...

【Post-process】【VBA】ETABS VBA FrameObj.GetNameList and write to EXCEL

ETABS API实战:导出框架元素数据到Excel 在结构工程师的日常工作中,经常需要从ETABS模型中提取框架元素信息进行后续分析。手动复制粘贴不仅耗时,还容易出错。今天我们来用简单的VBA代码实现自动化导出。 🎯 我们要实现什么? 一键点击,就能将ETABS中所有框架元素的基…...