OpenCV距离变换函数distanceTransform的使用

news2024/9/23 3:14:43
  • 操作系统:ubuntu22.04
  • OpenCV版本:OpenCV4.9
  • IDE:Visual Studio Code
  • 编程语言:C++11

功能描述

distanceTransform是OpenCV库中的一个非常有用的函数,主要用于计算图像中每个像素到最近的背景(通常是非零像素到零像素)的距离。它在计算机视觉和图像处理中有多种应用,以下是其中一些主要用途:

1.形态学分析:

  • 细化(Skeletonization):距离变换常用于细化图像,即获取图像的骨架,这对于字符识别、形状分析等很有帮助。
  • 膨胀和腐蚀:结合距离变换和阈值操作,可以实现精确的形态学膨胀和腐蚀。

2.物体分割:

  • 确定前景区域:距离变换可以帮助确定图像中的前景区域,特别是在二值图像中。
  • 种子点选择:在分水岭算法中,距离变换可以用于确定种子点,从而更好地分割物体。

3.特征提取:

  • 质心定位:对于连通组件,距离变换可以帮助找到其质心或重心。
  • 边缘检测:可以用于边缘增强,通过分析像素到边界点的距离来突出边缘。

4.路径规划和避障:

  • 在机器人导航和路径规划中,距离变换可以提供一个关于障碍物距离的信息图,帮助规划最优路径。

5.热力图生成:

  • 距离变换的结果可以被可视化为热力图,展示不同区域的“热度”或重要性。

6.形状描述符:

  • 在模式识别中,距离变换可以作为形状描述的一部分,帮助识别和分类不同的形状。

7.医学影像分析:

  • 在医疗图像处理中,距离变换可以用于测量结构的厚度或距离,例如血管壁的厚度。

cv::distanceTransform函数计算从二值图像中每个像素到最近零像素的近似或精确距离。对于零像素的图像,显然距离将为零。

当maskSize等于DIST_MASK_PRECISE且distanceType等于DIST_L2时,函数运行在文献[83]中描述的算法。此算法利用TBB库进行了并行化。

在其他情况下,使用文献[34]中的算法。这意味着对于每个像素,函数寻找到达最近零像素的最短路径,该路径由基本移动组成:水平、垂直、对角线或骑士移动(骑士移动适用于5×5的掩模)。总距离被计算为这些基本距离的总和。由于距离函数应当是对称的,所以所有的水平和垂直移动必须具有相同的代价(记作a),所有对角线移动必须具有相同的代价(记作b),所有骑士移动也必须具有相同的代价(记作c)。对于DIST_C和DIST_L1类型,距离被精确计算;而对于DIST_L2(欧几里得距离),距离只能计算出相对误差(5×5掩模给出更准确的结果)。对于a、b和c,OpenCV使用原论文中提出的值:

  • DIST_L1: a = 1, b = 2
  • DIST_L2:
    • 3 x 3: a=0.955, b=1.3693
    • 5 x 5: a=1, b=1.4, c=2.1969
  • DIST_C: a = 1, b = 1

通常,为了快速、粗略的距离估算DIST_L2,使用3×3掩模。为了更精确的距离估算DIST_L2,使用5×5掩模或精确算法。需要注意的是,无论是精确算法还是近似算法,它们的时间复杂度都是与像素数量线性的。

这种函数变体不仅计算每个像素(x,y)的最小距离,还标识出最近的由零像素组成的连通组件(当labelType等于DIST_LABEL_CCOMP)或最近的零像素(当labelType等于DIST_LABEL_PIXEL)。组件/像素的索引存储在labels(x, y)中。当labelType等于DIST_LABEL_CCOMP时,函数自动在输入图像中查找零像素的连通组件,并用不同的标签标记它们。当labelType等于DIST_LABEL_PIXEL时,函数遍历输入图像并对所有零像素标记不同的标签。

在这种模式下,复杂度仍然是线性的。也就是说,该函数提供了一种非常快速的方法来计算二值图像的Voronoi图。目前,第二种变体只能使用近似距离变换算法,即不支持maskSize= DIST_MASK_PRECISE。

函数原型

void cv::distanceTransform	
(	
	InputArray 	src,
	OutputArray 	dst,
	OutputArray 	labels,
	int 	distanceType,
	int 	maskSize,
	int 	labelType = DIST_LABEL_CCOMP 
)		

参数

  • src:这是输入的8位单通道(通常是二值化的)源图像。每个像素值要么是0(背景),要么是255(前景),函数会计算每个前景像素到最近背景像素的距离。

  • dst:这是输出图像,包含计算出的距离信息。它是一个8位或32位浮点型的单通道图像,与src图像具有相同的尺寸。每个像素值表示该像素到最近的背景像素的距离。

  • labels:这是输出的二维标签数组(离散的Voronoi图)。它具有CV_32SC1(32位整数)类型,并且与src图像具有相同的尺寸。每个像素值代表了最近的背景像素或背景像素组成的连通组件的标签。

  • distanceType:这指定了距离类型,它定义了计算距离的方式,具体包括:

    • DIST_L1:城市街区距离,也称为曼哈顿距离。
    • DIST_L2:欧几里得距离。
    • DIST_C:棋盘距离,也称为无限范数距离。
  • maskSize:这是距离变换所使用的掩模大小。它定义了计算距离时考虑的邻域大小。DIST_MASK_PRECISE在此变体中不受支持。对于DIST_L1或DIST_C距离类型,参数被强制为3,因为3×3的掩模可以给出与5×5或任何更大窗口相同的距离结果。

  • labelType:这定义了要构建的标签数组的类型,具体包括:

    • DIST_LABEL_CCOMP:每个连通组件的背景像素都被赋予一个唯一的标签。
    • DIST_LABEL_PIXEL:每个背景像素都被赋予一个唯一的标签。

函数原型2


void cv::distanceTransform	
(	
	InputArray 	src,
	OutputArray 	dst,
	int 	distanceType,
	int 	maskSize,
	int 	dstType = CV_32F 
)		

参数2

  • src 这是输入的8位单通道(通常是二值化的)源图像.
  • dst 这是输出图像,包含计算出的距离信息,它是一个8位或32位浮点型的单通道图像,与src图像具有相同的尺寸。
  • distanceType 距离的类型,参见DistanceTypes
    maskSize 距离变换掩模的大小,参见DistanceTransformMasks。在DIST_L1或DIST_C距离类型的情况下,该参数被强制为3,因为3×3的掩模可以得到与5×5或任何更大孔径相同的结果.
  • dstType 输出图像的类型。它可以是CV_8U或CV_32F。CV_8U类型仅能用于函数的第一个变体,并且当distanceType等于DIST_L1时。

示例源码

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

int main()
{
    // 读取图像
    cv::Mat src = cv::imread( "/media/dingxin/data/study/OpenCV/sources/images/hawk.jpg", 0 );  // 以灰度模式读取图像

    if ( src.empty() )
    {
        std::cout << "Error : Image cannot be loaded..!!" << std::endl;
        return -1;
    }

    cv::Size sz2Sh( 300, 400 );

    resize( src, src, sz2Sh, 0, 0, cv::INTER_LINEAR_EXACT );

    // 将图像转换为二值图像
    cv::Mat binary;
    cv::threshold( src, binary, 127, 1, cv::THRESH_BINARY );

    // 计算距离变换
    cv::Mat dist;
    cv::distanceTransform( binary, dist, cv::DIST_L2, 3 );

    // 将距离变换结果归一化到[0,255]范围
    cv::normalize( dist, dist, 0, 1, cv::NORM_MINMAX );

    // 显示原始图像和距离变换结果

    cv::imshow( "Source Image", src );
    cv::imshow( "Distance Transform", dist );

    cv::waitKey( 0 );

    return 0;
}

运行结果

原图:
在这里插入图片描述

距离变换图:
在这里插入图片描述

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

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

相关文章

VMware_centos8安装

目录 VMware Workstation Pro的安装 安装centos VMware Workstation Pro的安装 正版VMware 17百度网盘下载链接 (含秘钥) 链接&#xff1a;https://pan.baidu.com/s/16zB-7IAACM_1hwR1nsk12g?pwd1111 提取码&#xff1a;1111 第一次运行会要求输入秘钥 秘钥在上边的百度网盘…

【Leetcode】最小数字游戏

你有一个下标从 0 开始、长度为 偶数 的整数数组 nums &#xff0c;同时还有一个空数组 arr 。Alice 和 Bob 决定玩一个游戏&#xff0c;游戏中每一轮 Alice 和 Bob 都会各自执行一次操作。游戏规则如下&#xff1a; 每一轮&#xff0c;Alice 先从 nums 中移除一个 最小 元素&…

docker安装nginx并配置https

参考 docker安装nginx并配置https-腾讯云开发者社区-腾讯云 (tencent.com) 证书的生成 参见&#xff1a;SpringBoot项目配置HTTPS接口的安全访问&#xff08;openssl配置&#xff09;_配置接口访问-CSDN博客 步骤 1: 拉取Nginx镜像 docker pull nginx 好使的镜像如下&#x…

DockerCompose拉取DockerHub镜像,并部署OpenMetaData

参考博主&#xff1a;http://t.csdnimg.cn/i49ET 一、DockerCompose拉取DockerHub镜像 方法一&#xff08;不太行&#xff09;&#xff1a; 在daemon.json文件中添加一些国内还在服务的镜像站&#xff08;可能某些镜像会没有&#xff09; ([ -f /etc/docker/daemon.json ] ||…

RK3568笔记三十五:LED驱动开发测试

若该文为原创文章&#xff0c;转载请注明原文出处。 字符设备驱动程序的基本框架&#xff0c;主要是如何申请及释放设备号、添加以及注销设备&#xff0c;初始化、添加与删除 cdev 结构体&#xff0c;并通过 cdev_init 函数建立 cdev 和 file_operations 之间的关联&#xff0c…

每日一练:奇怪的TTL字段(python实现图片操作实战)

打开图片&#xff0c;只有四种数字&#xff1a;127&#xff0c;191&#xff0c;63&#xff0c;255 最大数字为255&#xff0c;想到进制转换 将其均转换为二进制&#xff1a; 发现只有前2位不一样 想着把每个数的前俩位提取出来&#xff0c;组成新的二进制&#xff0c;然后每…

Python中的数据容器及其在大数据开发中的应用

在Python编程中&#xff0c;数据容器是存储和组织数据的基本工具。作为大数据开发者&#xff0c;了解并灵活运用各种容器类型对于高效处理大规模数据至关重要。今天&#xff0c;我们将从Set出发&#xff0c;探讨Python中的各种数据容器&#xff0c;以及它们在大数据处理中的应用…

社交App iOS审核中的4.3问题:深入分析与解决策略

社交App审核中的4.3问题&#xff1a;深入分析与解决策略 在iOS应用开发和审核过程中&#xff0c;开发者经常会遇到苹果审核4.3问题。这一问题往往涉及应用的设计和内容重复性&#xff0c;导致应用被拒绝上架。为了帮助开发者更好地理解和解决这一问题&#xff0c;本文将对4.3问…

基于复旦微JFMQL100TAI的全国产化FPGA+AI人工智能异构计算平台,兼容XC7Z045-2FFG900I

基于上海复旦微电子FMQL45T900的全国产化ARM核心板。该核心板将复旦微的FMQL45T900&#xff08;与XILINX的XC7Z045-2FFG900I兼容&#xff09;的最小系统集成在了一个87*117mm的核心板上&#xff0c;可以作为一个核心模块&#xff0c;进行功能性扩展&#xff0c;能够快速的搭建起…

C语言操作符优先级

1 C语言操作符优先级 熟悉操作符的优先级&#xff0c;避免意外的求值顺序。 2. 运算符优先级记忆方法 利用优先级表或常见记忆口诀来记忆运算符的优先级。

嵌入式人工智能应用-篇外-烧写说明

1 外部接线 1.1 前期准备 需要准备的工具 ⚫ 一根 Mini USB 线 ⚫ 嵌入式人工智能教学科研平台 ⚫ 12V DC 电源 ⚫ 一台电脑 1.2 接线 12V DC 电源接入 12V IN&#xff1b;Mini USB 线连接 USB OTG&#xff1b;如果有两条 Mini USB 线&#xff0c;可以接入 UART2 to USB 口…

python2

一、条件语句 具体有如下&#xff1a;if、if......elif、if......elif......else 注意格式&#xff1a; if后面的条件表达式没有&#xff08;&#xff09;&#xff0c;以&#xff1a;作为结尾对于多分支的条件&#xff0c;不是写成else if 而是elif注意条件下一行要有缩进 …

Stable Diffusion 使用

目录 背景 最简单用法 进阶用法 高手用法 safetensor 一、概述 二、主要特点 背景 Stable Diffusion 开源后&#xff0c;确实比较火&#xff0c;上次介绍了下 Stable Diffusion 最简单的concept。今天继续介绍下&#xff0c;以Liblib 为例&#xff0c;介绍下如何使用参…

排序——交换排序

在上篇文章我们详细介绍了排序的概念与插入排序&#xff0c;大家可以通过下面这个链接去看&#xff1a; 排序的概念及插入排序 这篇文章就介绍一下一种排序方式&#xff1a;交换排序。 一&#xff0c;交换排序 基本思想&#xff1a;两两比较&#xff0c;如果发生逆序则交换…

Java | Leetcode Java题解之第234题回文链表

题目&#xff1a; 题解&#xff1a; class Solution {public boolean isPalindrome(ListNode head) {if (head null) {return true;}// 找到前半部分链表的尾节点并反转后半部分链表ListNode firstHalfEnd endOfFirstHalf(head);ListNode secondHalfStart reverseList(firs…

《BASeg: Boundary aware semantic segmentation for autonomous driving》论文解读

期刊&#xff1a;Neural Networks | Journal | ScienceDirect.com by Elsevier 年份&#xff1a;2023 代码&#xff1a;https://github.com/Lature-Yang/BASeg 摘要 语义分割是自动驾驶领域街道理解任务的重要组成部分。现有的各种方法要么专注于通过聚合全局或多尺度上下文…

读人工智能全传12人工智能导致的问题1

1. 人工智能会导致什么问题 1.1. 人工智能是一门通用技术&#xff1a;它的应用仅仅受限于我们的想象 1.1.1. 所有的技术都可能产生意想不到的效果&#xff0c;未来几十年甚至几百年内都存在可能性 1.2. 所有的技术都可能被滥用 1.2.1. 我们的无名氏祖先率先用上了火&#x…

C#统一委托Func与Action

C#在System命名空间下提供两个委托Action和Func&#xff0c;这两个委托最多提供16个参数&#xff0c;基本上可以满足所有自定义事件所需的委托类型。几乎所有的 事件 都可以使用这两个内置的委托Action和Func进行处理。 Action委托&#xff1a; Action定义提供0~16个参数&…

【深度学习】PyTorch深度学习笔记01-Overview

参考学习&#xff1a;B站视频【《PyTorch深度学习实践》完结合集】-刘二大人 ------------------------------------------------------------------------------------------------------- 1. 基于规则的深度学习 2. 经典的机器学习——手动提取一些简单的特征 3. 表示学习…

【接口设计】为 APP、PC、H5 网页提供统一风格的 API(实战篇,附源码地址)

为 APP、PC、H5 网页提供统一风格的 API 1.实现文章实体2.实现数据持久层3.实现服务接口和服务接口的实现类3.1 创建服务接口3.2 编写服务接口的实现 4.处理返回结果4.1 实现响应的枚举类4.2 实现返回的对象实体4.3 封装返回结果 4.统一处理异常4.1 全局捕捉异常4.2 自定义异常…