OPenCV高级编程——OPenCV形态学之腐蚀、膨胀、开运算、闭运算、形态学梯度等详解

news2024/11/13 10:00:39

目录

引言

形态学基础

结构元素(Structuring Element)

基本形态学操作

腐蚀(Erosion)

膨胀(Dilation)

开运算(Opening)

闭运算(Closing)

高级形态学操作

形态学梯度(Morphological Gradient)

顶帽(Top Hat)

黑帽(Black Hat)

​编辑

结论


引言

图像形态学是一种基于数学形态学的理论和技术,广泛应用于数字图像处理、计算机视觉和模式识别等领域。它主要通过对图像中的形状和结构元素(也称为内核或模板)进行操作,来实现图像的增强、去噪、特征提取等目的。本文将详细介绍OpenCV中C++语言支持的几种基本形态学操作,包括腐蚀、膨胀、开运算、闭运算、形态学梯度等。

形态学基础

结构元素(Structuring Element)

结构元素是一种小的图像模板,用于定义形态学操作的特征和行为。它通常是一个小的二值图像,用于描述待处理图像中的局部结构。常见的结构元素包括方形、圆形、十字形等。在OpenCV中,可以使用cv::getStructuringElement函数来生成这些结构元素。

函数原型

在 C++ 中,getStructuringElement 函数的原型如下:

Mat cv::getStructuringElement(int shape, Size ksize, Point anchor=Point(-1,-1))

参数说明

  • shape:结构元素的形状。OpenCV 提供了几种预定义的形状,如矩形(MORPH_RECT)、交叉形(MORPH_CROSS)、椭圆形(MORPH_ELLIPSE)等。
  • ksize:结构元素的大小,使用 Size 类型表示,即宽度和高度。
  • anchor:结构元素的锚点位置,即中心点。如果设置为 Point(-1,-1),则表示锚点位于结构元素的中心。

返回值

函数返回一个 Mat 对象,该对象是一个二值图像,表示了结构元素。

基本形态学操作

腐蚀(Erosion)

腐蚀是一种通过结构元素对图像进行局部最小值滤波的形态学操作,它会使图像中的边界部分逐渐缩小。腐蚀操作常用于去除图像中的噪声、细化边缘、分离紧密相连的物体等。

函数声明

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

参数说明

  • src:输入图像。
  • dst:输出图像。
  • kernel:腐蚀所使用的结构元素。
  • anchor:结构元素的锚点,默认为结构元素的中心。
  • iterations:腐蚀操作的迭代次数。
  • borderType:边界填充类型。
  • borderValue:当borderTypeBORDER_CONSTANT时,用于填充图像边缘的值。

代码示例:

#include <opencv2/opencv.hpp>  
#include <iostream>  

using namespace cv;
using namespace std;

int main() {
    // 加载图像  
    Mat src = imread("C:/Users/Administrator/Desktop/777.jpg"); 
    if (src.empty()) {
        cout << "Could not open or find the image!" << endl;
        return -1;
    }

    // 显示原始图像  
    namedWindow("Original Image", WINDOW_AUTOSIZE);
    imshow("Original Image", src);

    // 创建腐蚀操作所需的结构元素  
    Mat element = getStructuringElement(MORPH_RECT, Size(3, 3)); // 使用3x3的矩形结构元素  

    // 创建一个与原始图像相同大小和类型的Mat对象用于存储腐蚀后的图像  
    Mat eroded;

    // 应用腐蚀操作  
    erode(src, eroded, element);

    // 显示腐蚀后的图像  
    namedWindow("Eroded Image", WINDOW_AUTOSIZE);
    imshow("Eroded Image", eroded);

    // 等待任意键盘按键后退出  
    waitKey(0);

    return 0;
}

膨胀(Dilation)

膨胀是腐蚀的相反操作,它通过结构元素对图像进行局部最大值滤波,使图像中的边界部分逐渐扩张。膨胀操作常用于填充图像中的空洞、连接物体等。

函数声明(与腐蚀类似,但操作原理相反):

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

参数说明

  • src:输入图像。
  • dst:输出图像。
  • kernel:膨胀所使用的结构元素。
  • anchor:结构元素的锚点,默认为结构元素的中心。
  • iterations:膨胀操作的迭代次数。
  • borderType:边界填充类型。
  • borderValue:当borderTypeBORDER_CONSTANT时,用于填充图像边缘的值。

代码示例:

#include <opencv2/opencv.hpp>  
#include <iostream>  

using namespace cv;
using namespace std;

int main() {
    // 加载图像  
    Mat src = imread("C:/Users/Administrator/Desktop/777.jpg");
    if (src.empty()) {
        cout << "Could not open or find the image!" << endl;
        return -1;
    }

    // 显示原始图像  
    namedWindow("Original Image", WINDOW_AUTOSIZE);
    imshow("Original Image", src);

    // 创建膨胀操作所需的结构元素  
    Mat element = getStructuringElement(MORPH_RECT, Size(3, 3)); // 使用3x3的矩形结构元素  

    // 创建一个与原始图像相同大小和类型的Mat对象用于存储膨胀后的图像  
    Mat dilated;

    // 应用膨胀操作  
    dilate(src, dilated, element);

    // 显示膨胀后的图像  
    namedWindow("Dilated Image", WINDOW_AUTOSIZE);
    imshow("Dilated Image", dilated);

    // 等待任意键盘按键后退出  
    waitKey(0);

    return 0;
}

开运算(Opening)

开运算是先进行腐蚀操作,再进行膨胀操作的组合操作。它常用于去除小的噪声,并保留图像中的主要结构。

示例代码

Mat structureElement = getStructuringElement(MORPH_RECT, Size(5,5), Point(-1,-1));  
morphologyEx(src, dst, MORPH_OPEN, structureElement);
#include <opencv2/opencv.hpp>  
using namespace cv;

int main() {
    // 读取图像  
    Mat src = imread("C:/Users/Administrator/Desktop/777.jpg", IMREAD_GRAYSCALE); // 假设我们处理的是灰度图像  
    if (src.empty()) {
        std::cerr << "Could not read the image." << std::endl;
        return 1;
    }

    // 创建输出图像  
    Mat dst;

    // 定义结构元素  
    // 这里我们使用一个3x3的矩形结构元素  
    Mat element = getStructuringElement(MORPH_RECT, Size(3, 3));

    // 应用开运算  
    morphologyEx(src, dst, MORPH_OPEN, element);

    // 显示原始图像和处理后的图像  
    imshow("Original Image", src);
    imshow("Opening Result", dst);

    // 等待按键操作  
    waitKey(0);

    return 0;
}

闭运算(Closing)

闭运算是先进行膨胀操作,再进行腐蚀操作的组合操作。它常用于填充小的空洞,并连接图像中的断裂结构。

示例代码

Mat structureElement = getStructuringElement(MORPH_RECT, Size(5,5), Point(-1,-1));  
morphologyEx(src, dst, MORPH_CLOSE, structureElement);
#include <opencv2/opencv.hpp>  
using namespace cv;

int main() {
    // 读取图像  
    Mat src = imread("C:/Users/Administrator/Desktop/777.jpg", IMREAD_GRAYSCALE); // 假设我们处理的是灰度图像  
    if (src.empty()) {
        std::cerr << "Could not read the image." << std::endl;
        return 1;
    }

    // 创建输出图像  
    Mat dst;

    // 定义结构元素  
    // 这里我们使用一个3x3的矩形结构元素  
    Mat element = getStructuringElement(MORPH_RECT, Size(3, 3));

    // 应用开运算  
    morphologyEx(src, dst, MORPH_CLOSE, element);

    // 显示原始图像和处理后的图像  
    imshow("Original Image", src);
    imshow("Closing Result", dst);

    // 等待按键操作  
    waitKey(0);

    return 0;
}

高级形态学操作

形态学梯度(Morphological Gradient)

形态学梯度是膨胀和腐蚀之间的差异,它常用于检测图像中的边缘和轮廓。

示例代码(使用morphologyEx函数):

Mat structureElement = getStructuringElement(MORPH_RECT, Size(3,3), Point(-1,-1));  
morphologyEx(src, gradient, MORPH_GRADIENT, structureElement);
顶帽(Top Hat)

顶帽是原图与开运算结果之间的差值,常用于从图像中提取更精细的细节。

示例代码

morphologyEx(src, tophat, MORPH_TOPHAT, structureElement);

黑帽(Black Hat)

黑帽是闭运算与原图之间的差值,同样用于从图像中提取更精细的细节,但通常用于分离比邻近点暗的斑块。

示例代码

morphologyEx(src, blackhat, MORPH_BLACKHAT, structureElement);

结论

OpenCV提供的形态学操作功能强大且灵活,能够处理各种复杂的图像处理任务。通过合理使用腐蚀、膨胀、开运算、闭运算、形态学梯度、顶帽和黑帽等操作,我们可以有效地对图像进行去噪、增强、特征提取等处理。

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

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

相关文章

读零信任网络:在不可信网络中构建安全系统06授权

1. 授权 1.1. 授权决策不容忽视&#xff0c;所有访问请求都必须被授权 1.2. 数据存储系统和其他各支撑子系统是授权的基石 1.2.1. 子系统提供访问控制的权威数据源和评估依据&#xff0c;直接影响授权决策 1.2.2. 谨慎区分各子系统的职责和能力&#xff0c;需要将其严格隔离…

高数经典反例记录(持续更新)

这篇博客总结了一些易混淆的概念以及经典反例&#xff0c;全部看完会有收获的&#xff0c;后期可能会继续补充&#xff01; 1.概念模糊 2.极限存在/不存在问题

豹5全新价格引爆市场,技术平权开启SUV新篇章

关注汽车市场的小伙伴&#xff0c;想必都知道最近方程豹品牌的豹5车型&#xff0c;打出了23.98万元至30.28万元的全新价格区间&#xff0c;重新定义了SUV市场的竞争格局。 方程豹的这一举动&#xff0c;立刻引发了市场的热烈讨论&#xff1a;“豹5现在值得入手吗&#xff1f;”…

科普文: jdk 1.7和 jdk 1.8 中ConcurrentHashMap 原理浅析

1. 前言 为什么要使用 ConcurrentHashMap 主要基于两个原因&#xff1a; 在并发编程中使用 HashMap 可能造成死循环(jdk1.7,jdk1.8 中会造成数据丢失)HashTable 效率非常低下 2. ConcurrentHashMap 结构 jdk 1.7 和 jdk 1.8 中&#xff0c;ConcurrentHashMap 的结构有着很…

软件产品测试报告包括哪些内容?专业软件测试服务供应商推荐

在当今快速发展的软件行业中&#xff0c;软件产品测试报告的重要性愈加凸显。卓码软件测评作为专业的软件测试服务供应商&#xff0c;深知一份高质量的测试报告对于开发团队、管理层以及客户的重要性。 软件产品测试报告是对软件产品在测试过程中所表现出来的各项指标和特性的…

【架构师进阶必备】Spring - 运行时以四种方式动态注册 bean

Spring — 运行时以四种方式动态注册 bean 1. 概述 在本教程中&#xff0c;我们将学习“使用 spring 动态注册 bean”或“在运行时动态将 bean 添加到 spring-context”。在Spring 应用程序中加载和删除 bean 时&#xff0c;无需在运行时重新启动应用程序即可完成此操作。 如…

先用先发!小样本故障诊断新思路!Transformer-SVM组合模型多特征分类预测/故障诊断(Matlab)

先用先发&#xff01;小样本故障诊断新思路&#xff01;Transformer-SVM组合模型多特征分类预测/故障诊断&#xff08;Matlab&#xff09; 目录 先用先发&#xff01;小样本故障诊断新思路&#xff01;Transformer-SVM组合模型多特征分类预测/故障诊断&#xff08;Matlab&#…

【RabbitMQ】路由模式(Routing)

一、基本概念 生产者&#xff08;Producer&#xff09;&#xff1a;发送消息到交换机的程序。在发送消息时&#xff0c;需要指定一个路由键。交换机&#xff08;Exchange&#xff09;&#xff1a;接收生产者发送的消息&#xff0c;并根据路由键将消息路由到与之匹配的队列。在…

【C++BFS】1466. 重新规划路线

本文涉及知识点 CBFS算法 LeetCode1466. 重新规划路线 n 座城市&#xff0c;从 0 到 n-1 编号&#xff0c;其间共有 n-1 条路线。因此&#xff0c;要想在两座不同城市之间旅行只有唯一一条路线可供选择&#xff08;路线网形成一颗树&#xff09;。去年&#xff0c;交通运输部…

软件测试--易用性测试

人体工程学这是一门将日常使用的东西设计为易于使用何实用性强的科学。因此人体工程学的主要目标是达到易用性。 用户界面测试 用于与软件程序交互的方式称为用户界面或UI。大家都熟悉的计算机UI随着时间推移发生了变化。早期的计算机有触发开关和发光管。纸带、穿孔卡和电传打…

AIGC技术的未来航向:深度解析与Java实践

摘要&#xff1a; 本文深入探讨了人工智能生成内容&#xff08;AIGC&#xff09;技术的未来发展方向&#xff0c;从技术创新、可持续可拓展性、用户体验、应用场景、政府赋能等多维度进行分析&#xff0c;并结合Java技术实践&#xff0c;提供具体的实现策略和代码示例。 引言…

PDF翻译神器:这四款可以实现一键搞定,留学党必备!

外文的阅读还是需要一定的语言功底&#xff0c;现在大家也对外文越来越重视起来了&#xff0c;但是借助一些翻译工具进行翻译可以很大程度地提升工作的效率&#xff0c;就算是遇到批量的文件处理也可以一键翻译出来&#xff0c;所以今天借此文章整理了四款好用的pdf翻译工具&am…

计算机基础(Windows 10+Office 2016)教程 —— 第3章 操作系统基础(下)

操作系统基础 Windows 10的系统管理3.5.1 设置日期和时间3.5.2 Windows 10 个性化设置3.5.3 安装和卸载应用程序3.5.4 分区管理3.5.5 格式化磁盘3.5.6 清理磁盘 3.6 Windows 10的网络功能3.6.1 网络软硬件的安装3.6.2 查看网络中其他计算机3.6.3 资源共享 3.7 Windows 10系统的…

数据灾备及时恢复应急预案

第一节总则 1&#xff0c;灾难备份的目的 为了规范本所重要数据备份清单的建立&#xff0c;备份的职责&#xff0c;备份的检查。以及系统受到破坏后的恢复工作&#xff0c;合理防范计算机及信息系统使用过程中的风险&#xff0c;特制定本预案。 2&#xff0c;灾难恢复的定义 灾…

1.kafka面试题之零拷贝

1. 写在前面 Kafka 是一个高性能的分布式消息系统&#xff0c;它使用了多种优化技术来提高数据传输效率&#xff0c;其中之一就是 “零拷贝”&#xff08;Zero Copy&#xff09;。零拷贝技术可以显著减少数据在内存中的复制次数&#xff0c;从而提高 I/O 操作的效率&#xff0…

模拟栈解决表达式求值-java

主要讲述了通过栈来解决后缀表达式&#xff0c;来计算出表达式的结果&#xff0c;可以好好熟悉一下思路。 目录 前言 一、表达式求值问题 二、栈模拟计算表达式 1.算法思路 2.代码解释 三、代码实现 1.代码如下&#xff1a; 2.测试样例如下&#xff1a; 3.运行结果如下…

【轨物推荐】经济长波:创新周期的历史

原创 丑丑姐姐 专利分析可视化 2021年08月01日 21:18 图片来源&#xff1a;Visual Capitalist 在开始本文之前&#xff0c;我们先来学习两个概念&#xff1a; 经济长波&#xff08;Long Waves&#xff09;&#xff0c;亦称“大循环理论”、“康德拉季耶夫周期”。经济长波理论…

redis持久化存储,rdb快照文件,aof文件

redis作为内存数据库&#xff0c;在内存中进行读写操作&#xff0c;将读写操作从毫秒级别降为纳秒级别&#xff0c;得到极大的性能提升&#xff0c;与此同时&#xff0c;作为内存数据库其也有致命缺陷&#xff0c;一旦redis发生意外宕机&#xff0c;那么内存中的数据将全部消失…

智慧医院临床检验管理系统源码(LIS),全套LIS系统源码交付,商业源码,自主版权,支持二次开发

实验室信息系统是集申请、采样、核收、计费、检验、审核、发布、质控、查询、耗材控制等检验科工作为一体的网络管理系统。它的开发和应用将加快检验科管理的统一化、网络化、标准化的进程。一体化设计&#xff0c;与其他系统无缝连接&#xff0c;全程化条码管理。支持危机值管…

如何手动修复DLL丢失?2种手动修复dll文件方法

DLL&#xff08;动态链接库&#xff09;文件是Windows操作系统中非常重要的组成部分&#xff0c;它们包含了程序运行所需的代码和数据。然而&#xff0c;由于各种原因&#xff0c;如系统更新、软件卸载不当或病毒感染&#xff0c;DLL文件有时会丢失或损坏&#xff0c;导致程序无…