Opencv4 c++ 自用笔记 05 形态学操作

news2025/6/6 10:16:03

图像形态学主要获取物体的形状与位置信息。利用具有一定形态的结构元素度量和提取图像中的对应形状,达到对图像分析和识别的目的。操作主要包括腐蚀、膨胀、开运算和闭运算。

像素距离与连通域

图像形态学中,将不与其他区域链接的独立区域称为集合或者连通域,这个集合中的元素就是连通域中的每一个像素,像素之间的距离可以表示两个连通域之间的关系。

图像像素距离

两个像素之间的距离有多种定义。常见的有欧式距离、街区距离和棋盘距离。

欧式距离

指两个像素之间的直线距离,与坐标系中两点间的距离求取方式一致。
d = ( x 1 − x 2 ) 2 + ( y 1 − y 2 ) 2 d=\sqrt{(x_1-x_2)^2+(y_1-y_2)^2} d=(x1x2)2+(y1y2)2

街区距离

指两个像素X差与Y差的和。欧式距离表示的是两点间最近距离,但有时我们并不能沿着直线行走,而是沿着一定的路径行走,如同城市街区一般。
d = ∣ x 1 − x 2 ∣ + ∣ y 1 − y 2 ∣ d=|x_1-x_2|+|y_1-y_2| d=x1x2+y1y2

棋盘距离

又称切比雪夫距离(Chebyshev Distance),指两像素点在横坐标和纵坐标上差的绝对值中的较大者。这相当于棋盘上王从一个格子到另一个格子所需的最少步数。
d = m a x ( ∣ x 1 − x 2 ∣ , ∣ y 1 − y 2 ∣ ) d=max(|x_1-x_2|,|y_1-y_2|) d=max(x1x2,y1y2)
opencv中有计算不同距离的函数。

distanceTransform(src, dst, labels, distanceType, maskSize, labelType);

labels为二维标签数组,与输入图像有相同的尺寸,数据类型为CV_32S的单通道数据
distanceType为方法标志,-1 为自定义距离,1 为街区距离,2 为欧式距离,3 为棋盘距离
maskSize为距离变换掩码尺寸,可选 DIST_MASK_3( 3 × 3 3\times3 3×3) 和 DIST_MASK_5( 5 × 5 5\times5 5×5)
labelType为标签数组类型,0 表示同一连通区域的零像素及其最近的非零像素点赋予相同的标签,1 表示每个零像素及其最近的非零像素点都有其独特的标签

distanceTransform(src, dst, distanceType, maskSize, dstType);

这个原型不生成labels数组,占用资源小。
dstType决定了输出图像的类型,CV_8UCV_32F

图像连通域分析

图像的连通域指图像中具有相同像素值且位置相邻的像素组成的区域。为了避免像素值波动的影响,连通域分析处理的一般是二值化后的图像。

像素的邻域定义了其“相邻”关系,常见的有4-邻域(仅考虑上、下、左、右四个方向的像素)和8-邻域(额外包含对角线方向的四个像素)。

邻域分析主要有两遍扫描法和种子填充法。

函数如下:

connectedComponents(image, labels, connectivity, ltype, ccltype);

image为待标记图像,必须为CV_8U单通道二值图像
labels 输出的标记图像,其中每个连通域被赋予一个唯一的整数标签。
connectivity邻域种类,可选4(4-邻域)或8(8-邻域)
ltype为输出图像数据类型,可为CV_32SCV_16U
ccltype连通域标记算法类型,例如 cv::CCL_DEFAULTcv::CCL_WUcv::CCL_GRANA

简化原型:

connectedComponents(image, labels, connectivity=8, ltype=CV_32S);
connectedComponentsWithStats(image, labels, stats, centroids, connectivity, ltype, ccltype);
connectedComponentsWithStats(image, labels, stats, centroids, connectivity=8, ltype=CV_32S);

stats输出的统计信息矩阵。每一行对应一个连通域的统计数据(背景为第0行),列代表不同的统计属性
centroids为每个连通域质心的坐标,CV_64F
stats中包含的信息如下:

cv::CC_STAT_LEFT     // 0 连通域外包矩形最左侧像素的x坐标
cv::CC_STAT_TOP      // 1 连通域外包矩形最上方像素的y坐标
cv::CC_STAT_WIDTH    // 2 连通域外包矩形的水平长度
cv::CC_STAT_HEIGHT   // 3 连通域外包矩形的垂直长度
cv::CC_STAT_AREA     // 4 连通域的面积(以像素为单位)
// cv::CC_STAT_MAX      // 5 统计信息类型的总数,本身不代表具体统计值

腐蚀与膨胀

腐蚀与膨胀是形态学的基础操作,可用于去除图像噪声、分割独立的图像区域、连接邻近的区域等。

腐蚀

腐蚀与卷积相似,需要模板矩阵——结构元素。对于二值图像(通常前景为1或255,背景为0),腐蚀操作会检查结构元素是否能完全被图像中的前景像素区域所覆盖。若能,则结构元素中心(锚点)对应的像素在新图像中保持为前景;否则置为背景。其效果是“收缩”或“细化”图像中的前景区域,去除小的噪点和物体边界的一些像素。

getStructuringElement(shape, ksize, anchor = Point(-1, -1));

shape为生成的结构元素种类
ksize为结构元素大小
anchor为中心点的位置

这个函数可以生成矩形、十字、椭圆结构元素。只有十字结构元素的中心点位置会影响图像腐蚀后的轮廓形状,其他的只影响操作结果的平移量。

cv::MORPH_RECT     // 0 矩形结构元素
cv::MORPH_CROSS    // 1 十字结构元素
cv::MORPH_ELLIPSE  // 2 椭圆结构元素

图像腐蚀函数:

erode(src, dst, kernel, anchor=Point(-1, -1), iterations=1, borderType, borderValue);

kernel为结构元素
iterations为腐蚀次数,次数越多效果越明显
borderValue为使用边界不变外推法时的边界值

此函数执行图像腐蚀。对于多通道图像,每个通道将独立进行腐蚀。在二值图像中,腐蚀会使前景物体“收缩”或“变细”。

膨胀

图像膨胀通常被认为是腐蚀的对偶运算。对于二值图像,如果结构元素的锚点对应于输入图像的某个位置,且结构元素覆盖的区域内至少有一个前景像素与输入图像的前景像素重叠,则输出图像中该锚点对应的像素被置为前景。其效果是“扩张”或“加粗”图像中的前景区域,填充小的空洞或连接断裂部分。

dilate(src, dst, kernel, anchor, iterations, borderType, borderValue);

对于多通道图像,各通道独立膨胀。在二值图像中,膨胀会使前景物体“扩张”或“变粗”。

膨胀只针对非0像素。

运算组合

针对不同的图像处理需求,OpenCV 提供了腐蚀与膨胀运算的不同组合形式,封装在 morphologyEx 函数中。

morphologyEx(src, dst, op, kernel, anshor, iterations, bord

op为形态学操作类型标志。

cv::MORPH_ERODE      // 0 腐蚀
cv::MORPH_DILATE     // 1 膨胀
cv::MORPH_OPEN       // 2 开运算
cv::MORPH_CLOSE      // 3 闭运算
cv::MORPH_GRADIENT   // 4 形态学梯度
cv::MORPH_TOPHAT     // 5 顶帽运算
cv::MORPH_BLACKHAT   // 6 黑帽运算
cv::MORPH_HITMISS    // 7 击中击不中变换
开运算

开运算可以去除图像噪声,消除较小连通域,保留较大连通域,同时在两个物体纤细连接处分离,且能在不明显改变较大连通域面积的同时平滑连通域的边界。

开运算先对图像进行腐蚀,随后膨胀,使用相同的结构元素。

O p e n i n g ( A , B ) = ( A ⊖ B ) ⊕ B Opening(A,B)=(A\ominus B)\oplus B Opening(A,B)=(AB)B
其中 A A A是图像, B B B是结构元素, ⊖ \ominus 代表腐蚀, ⊕ \oplus 代表膨胀。

闭运算

闭运算常用于填充前景对象内部的小空洞,连接邻近的对象,以及平滑对象的轮廓(特别是填充轮廓的凹陷部分)。

闭运算先进行膨胀,再进行腐蚀。
C l o s i n g ( A , B ) = ( A ⊕ B ) ⊖ B Closing(A,B)=(A\oplus B)\ominus B Closing(A,B)=(AB)B
其中 A A A是图像, B B B是结构元素, ⊖ \ominus 代表腐蚀, ⊕ \oplus 代表膨胀。

形态学梯度

形态学梯度(cv::MORPH_GRADIENT)用于突出对象的边缘。标准的形态学梯度是图像膨胀的结果与图像腐蚀的结果之差。梯度分为基本梯度、内部梯度、外部梯度。

基本梯度指图像膨胀后和腐蚀后的差值图像
G r a d i e n t ( A , B ) = ( A ⊕ B ) − ( A ⊖ B ) Gradient(A,B)=(A\oplus B)-(A\ominus B) Gradient(A,B)=(AB)(AB)

内部梯度指原图像与腐蚀后图像间的差值
G r a d i e n t ( A , B ) = A − ( A ⊖ B ) Gradient(A,B)=A-(A\ominus B) Gradient(A,B)=A(AB)

外部梯度指膨胀后图像与原图像间的差值。
G r a d i e n t ( A , B ) = ( A ⊕ B ) − A Gradient(A,B)=(A\oplus B)-A Gradient(A,B)=(AB)A

内部梯度与外部梯度需自己实现。

顶帽运算

顶帽运算(cv::MORPH_TOPHAT)是原图像与其开运算结果之间的差值。它常用于提取图像中相对于其周围环境更亮的细小区域或斑点,这些区域通常在开运算中被移除。
T o p H a t ( A , B ) = A − O p e n i n g ( A , B ) TopHat(A,B)=A−Opening(A,B) TopHat(A,B)=AOpening(A,B)

黑帽运算

黑帽运算(cv::MORPH_BLACKHAT)是图像的闭运算结果与原图像之间的差值。它用于提取图像中相对于其周围环境更暗的细小区域或斑点。
B l a c k H a t ( A , B ) = C l o s i n g ( A , B ) − A BlackHat(A,B)=Closing(A,B)−A BlackHat(A,B)=Closing(A,B)A

击中击不中变换

击中击不中变换(cv::MORPH_HITMISS)是一种用于查找特定像素模式的运算。

它使用一个特殊的结构元素,该结构元素不仅定义了需要匹配的前景(“击中”部分,通常标记为1),也定义了必须为背景的区域(“击不中”部分,通常标记为-1),其他部分为“不关心”(标记为0)。

只有当图像中的某个区域与结构元素的前景部分完全匹配,并且与背景部分也完全匹配时,输出图像中对应锚点位置的像素才会被标记。这是一种比简单腐蚀更精确的模式匹配方法,常用于查找角点、孤立点等特定配置。

在使用矩形结构元素时,结果与腐蚀相同。

图像细化

细化指从多像素宽度减少到单位像素宽度的过程,又称“骨架化”或“中轴变换”。图像细化常用于文字识别。图像细化一般要求保证细化后骨架的连通性、对原图像的细节特征有较好保留、线条的端点保留完好、线条交叉点不能发生畸变。主要应用于由线条形状构成的物体。

细化算法分为迭代细化和非迭代细化。迭代细化中,又可分为串行细化和并行细化。

opencv中提供了如下函数:

thinning(src, dst, thinningType=THINNING_ZHANGSUEN);

src必须为CV_8UC1
thinningType为细化算法选择标志

0	THINNING_ZHANGSUEN	
1	THINNING_GUOHALL	复杂场景效果更好

需确保已链接 opencv_ximgproc 模块,并通过 cv::ximgproc:: 命名空间调用

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

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

相关文章

R语言基础| 创建数据集

在R语言中,有多种数据类型,用以存储和处理数据。每种数据类型都有其特定的用途和操作函数,使得R语言在处理各种数据分析任务时非常灵活和强大: 向量(Vector): 向量是R语言中最基本的数据类型,它…

Centos7搭建zabbix6.0

此方法适用于zabbix6以上版本zabbix6.0前期环境准备:Lamp(linux httpd mysql8.0 php)mysql官网下载位置:https://dev.mysql.com/downloads/mysql/Zabbix源码包地址:https://www.zabbix.com/cn/download_sourcesZabbix6…

Docker 部署前后端分离项目

1.Docker 1.1 什么是 Docker ? Docker 是一种开源的 容器化平台,用于开发、部署和运行应用程序。它通过 容器(Container) 技术,将应用程序及其依赖项打包在一个轻量级、可移植的环境中,确保应用在不同计算…

云游戏混合架构

云游戏混合架构通过整合本地计算资源与云端能力,形成了灵活且高性能的技术体系,其核心架构及技术特征可概括如下: 一、混合架构的典型模式 分层混合模式‌ 前端应用部署于公有云(如渲染流化服务),后端逻辑…

【小红书】API接口,获取笔记核心数据

小红书笔记核心数据API接口详解 - 深圳小于科技提供专业数据服务 深圳小于科技(官网:https://www.szlessthan.com)推出的小红书笔记核心数据API接口,为开发者提供精准的笔记互动数据分析能力,助力内容运营与商业决策。…

会议室钥匙总丢失?换预约功能的智能门锁更安全

在企业日常运营中,会议室作为重要的沟通与协作场所,其管理效率与安全性直接影响着企业的运作顺畅度。然而,传统会议室管理方式中钥匙丢失、管理不便等问题频发,给企业带来了不少困扰。近期,某企业引入了启辰智慧预约系…

Redis底层数据结构之跳表(SkipList)

SkipList是Redis有序结合ZSet底层的数据结构,也是ZSet的灵魂所在。与之相应的,Redis还有一个无序集合Set,这两个在底层的实现是不一样的。 标准的SkipList: 跳表的本质是一个链表。链表这种结构虽然简单清晰,但是在查…

Ubuntu安装Docker命令清单(以20.04为例)

在你虚拟机上完成Ubuntu的下载后打开终端!!! Ubuntu安装Docker终极命令清单(以20.04为例) # 1. 卸载旧版本(全新系统可跳过) sudo apt-get remove docker docker-engine docker.io containerd …

HarmonyOS Next 弹窗系列教程(2)

HarmonyOS Next 弹窗系列教程(2) 上一章节我们讲了自定义弹出框 (openCustomDialog),那对于一些简单的业务场景,不一定需要都是自定义,也可以使用 HarmonyOS Next 内置的一些弹窗效果。比如: 名称描述不依…

中小企业搭建网站选择虚拟主机还是云服务器?华为云有话说

这是一个很常见的问题,许多小企业在搭建网站时都会面临这个选择。虚拟主机和云服务器都有各自的优缺点,需要根据自己的需求和预算来决定。 虚拟主机是指将一台物理服务器分割成多个虚拟空间,每个空间都可以运行一个网站。虚拟主机的优点是价格…

使用 HTML + JavaScript 在高德地图上实现物流轨迹跟踪系统

在电商行业蓬勃发展的今天,物流信息查询已成为人们日常生活中的重要需求。本文将详细介绍如何基于高德地图 API 利用 HTML JavaScript 实现物流轨迹跟踪系统的开发。 效果演示 项目概述 本项目主要包含以下核心功能: 地图初始化与展示运单号查询功能…

19-项目部署(Linux)

Linux是一套免费使用和自由传播的操作系统。说到操作系统,大家比较熟知的应该就是Windows和MacOS操作系统,我们今天所学习的Linux也是一款操作系统。 我们作为javaEE开发工程师,将来在企业中开发时会涉及到很多的数据库、中间件等技术&#…

html基础01:前端基础知识学习

html基础01&#xff1a;前端基础知识学习 1.个人建立打造 -- 之前知识的小总结1.1个人简历展示1.2简历信息填写页面 1.个人建立打造 – 之前知识的小总结 1.1个人简历展示 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8&qu…

【RoadRunner】自动驾驶模拟3D场景构建 | 软件简介与视角控制

&#x1f4af; 欢迎光临清流君的博客小天地&#xff0c;这里是我分享技术与心得的温馨角落 &#x1f4af; &#x1f525; 个人主页:【清流君】&#x1f525; &#x1f4da; 系列专栏: 运动控制 | 决策规划 | 机器人数值优化 &#x1f4da; &#x1f31f;始终保持好奇心&…

基于RK3576+FPGA芯片构建的CODESYS软PLC Linux实时系统方案,支持6T AI算力

基于RK3576芯片构建的CODESYS软PLC Linux实时系统方案&#xff0c;结合了异构计算架构与工业实时控制技术&#xff0c;主要特点如下&#xff1a; 一、硬件架构设计 ‌异构多核协同‌ ‌Cortex-A72四核‌&#xff08;2.3GHz&#xff09;&#xff1a;处理运动轨迹规划、AI视觉等…

适配器模式:让不兼容接口协同工作

文章目录 1. 适配器模式概述2. 适配器模式的分类2.1 类适配器2.2 对象适配器 3. 适配器模式的结构4. C#实现适配器模式4.1 对象适配器实现4.2 类适配器实现 5. 适配器模式的实际应用场景5.1 第三方库集成5.2 遗留系统集成5.3 系统重构与升级5.4 跨平台开发 6. 类适配器与对象适…

DDP与FSDP:分布式训练技术全解析

DDP与FSDP:分布式训练技术全解析 DDP(Distributed Data Parallel)和 FSDP(Fully Sharded Data Parallel)均为用于深度学习模型训练的分布式训练技术,二者借助多 GPU 或多节点来提升训练速度。 1. DDP(Distributed Data Parallel) 实现原理 数据并行:把相同的模型复…

【Spring AI 1.0.0】Spring AI 1.0.0框架快速入门(1)——Chat Client API

Spring AI框架快速入门 一、前言二、前期准备2.1 运行环境2.2 maven配置2.3 api-key申请 三、Chat Client API3.1 导入pom依赖3.2 配置application.properties文件3.3 创建 ChatClient3.3.1 使用自动配置的 ChatClient.Builder3.3.2 使用多个聊天模型 3.4 ChatClient请求3.5 Ch…

【笔记】在 MSYS2(MINGW64)中正确安装 Rust

#工作记录 1. 环境信息 Windows系统: MSYS2 MINGW64当前时间: 2025年6月1日Rust 版本: rustc 1.87.0 (17067e9ac 2025-05-09) (Rev2, Built by MSYS2 project) 2. 安装步骤 步骤 1: 更新系统包数据库并升级已安装的包 首先&#xff0c;确保我们的 MSYS2 系统是最新状态。打…

从汇编的角度揭秘C++引用,豁然开朗

C中的引用是指已有对象的别名&#xff0c;可以通过该别名访问并修改被引用的对象。那么其背后的原理是什么呢&#xff1f;引用是否会带来额外的开销呢&#xff1f;我们从一段代码入手&#xff0c;来分析一下引用的本质。 #include <stdio.h> int main() {int a 10;int …