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

OpenCV距离变换函数distanceTransform的使用

  • 操作系统: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;
}

运行结果

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

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

相关文章:

OpenCV距离变换函数distanceTransform的使用

操作系统&#xff1a;ubuntu22.04OpenCV版本&#xff1a;OpenCV4.9IDE:Visual Studio Code编程语言&#xff1a;C11 功能描述 distanceTransform是OpenCV库中的一个非常有用的函数&#xff0c;主要用于计算图像中每个像素到最近的背景&#xff08;通常是非零像素到零像素&…...

Service Mesh 是一种用于处理服务间通信的基础设施层

Service Mesh 是一种用于处理服务间通信的基础设施层&#xff0c;它通常与微服务架构一起使用&#xff0c;以提供诸如服务发现、负载均衡、熔断、监控、追踪和安全性等功能。Service Mesh 的一个流行实现是 Istio&#xff0c;它基于 Envoy 代理和 Kubernetes。 然而&#xff0…...

QML界面控件加载与显示顺序

一、QML界面控件加载顺序 QML在界面加载时的顺序和我们认知的有很大的不同&#xff0c;有时候会对我们获取参数以及界面实现造成很大的困扰 1、加载顺序 import QtQuick 2.12 import QtQml 2.12 import QtQuick.Window 2.12 import QtQuick.VirtualKeyboard 2.4Window {id: …...

C++从入门到起飞之——缺省参数/函数重载/引用全方位剖析!

目录 1.缺省参数 2. 函数重载 3.引⽤ 3.1 引⽤的概念和定义 3.2 引⽤的特性 3.3 引⽤的使⽤ 3.4 const引⽤ 3.5 指针和引⽤的关系 4.完结散花 个人主页&#xff1a;秋风起&#xff0c;再归来~ C从入门到起飞 个人格言&#xff1a;悟已往之不谏…...

tkinter-TinUI-xml实战(12)pip可视化管理器

引言 pip命令行工具在平常使用方面确实足够简单&#xff0c;本项目只是作为TinUI多界面开发的示例。 当然&#xff0c;总有人想用GUI版pip&#xff0c;实际上也有。不过现在&#xff0c;我们就来手搓一个基于python和TinUI&#xff08;tkinter&#xff09;的pip可视化管理器。…...

Java中标识符和关键字

1.标识符 public class HelloWorld{public static void main(String[] args){System.out.println("Hello,world");} }上述代码中在public class 后面的HelloWorld称为类名&#xff0c;main称为方法名&#xff0c;也可以将其称为标识符&#xff0c;即&#xff1a;在程…...

电子版pdf格式标书怎么加盖公章?

电子版PDF格式标书加盖公章的方法有多种&#xff0c;以下是一些常用的步骤和技巧&#xff1a; 一、手动插入图片法 打开PDF文档&#xff1a;首先&#xff0c;确保你已经安装了支持PDF编辑的软件&#xff0c;如Adobe Acrobat Reader DC、Foxit PDF Editor等。选择插入图片&…...

【开放集目标检测】Grounding DINO

一、引言 论文&#xff1a; Grounding DINO: Grounding DINO: Marrying DINO with Grounded Pre-Training for Open-Set Object Detection 作者&#xff1a; IDEA 代码&#xff1a; Grounding DINO 注意&#xff1a; 该算法是在Swin Transformer、Deformable DETR、DINO基础上…...

东莞酷得 PMS134应广8位OTP单片机

1、特性 通用 OTP 系列 不建议使用于 AC 阻容降压供电或有高 EFT 要求的应用。应广不对使用于此类应用而不达安规要求负责 工作温度范围:-20C~70C 1.2.系统特性 一个硬件 16位计数器 两个8位硬件 PWM生成器 三个11 位硬件 PWM生成器(PWMG0&#xff0c;PWMG1…...

[终端安全]-7 后量子密码算法

本文参考资料来源&#xff1a;NSA Releases Future Quantum-Resistant (QR) Algorithm Requirements for National Security Systems > National Security Agency/Central Security Service > Article Commercial National Security Algorithm Suite 2.0” (CNSA 2.0) C…...

uniapp 支付宝小程序 芝麻免押 免押金

orderStr参数如下&#xff1a; my.tradePay({orderStr:res, // 完整的支付参数拼接成的字符串&#xff0c;从 alipay.fund.auth.order.app.freeze 接口获取success: (res) > {console.log(免押成功);console.log(JSON.stringify(res),不是JOSN);console.log(JSON.stringify…...

Python爬虫教程第一篇

一、爬虫基础概念 1. 什么是爬虫 爬虫&#xff08;Spider&#xff0c;又称网络爬虫&#xff09;&#xff0c;是指向网站/网络发起请求&#xff0c;获取资源后分析并提取有用数据的程序。从技术层面来说&#xff0c;爬虫通过程序模拟浏览器请求站点的行为&#xff0c;把站点返…...

AI时代:探索个人潜能的新视角

文章目录 Al时代的个人发展1 AI的高速发展意味着什么1.1 生产力大幅提升1.2 生产关系的改变1.3 产品范式1.4 产业革命1.5 Al的局限性1.5.1局限一:大模型的幻觉 1.5.2 局限二&#xff1a;Token 2 个体如何应对这种改变?2.1 职场人2.2 K12家长2.3 大学生2.4 创业者 3 人工智能发…...

【Python学习笔记】Optuna + Transformer B站视频实践

【Python学习笔记】Optuna Transformer 实践 背景前摇&#xff08;省流可不看&#xff09;&#xff1a; 之前以泰坦尼克号数据集为案例&#xff0c;学习了Optuna的基本操作&#xff0c;为了进一步巩固知识和便于包装简历&#xff0c;决定找个唬人一点的项目练练手。 ————…...

【自动驾驶/机器人面试C++八股精选】专栏介绍

目录 一、自动驾驶和机器人技术发展前景二、C在自动驾驶和机器人领域的地位三、专栏介绍四、订阅需知 一、自动驾驶和机器人技术发展前景 随着人工智能、机器学习、传感器技术和计算能力的进步&#xff0c;自动驾驶和机器人的技术水平不断提升&#xff0c;使得它们更加智能、可…...

Unity中一键生成具有身体感知的虚拟人物动作

在虚拟现实(VR)和增强现实(AR)的浪潮中&#xff0c;如何让虚拟人物的动作更加自然、真实&#xff0c;已经成为一个重要课题。AI4Animation项目&#xff0c;一个由 Sebastian Starke 主导的开源框架&#xff0c;为Unity开发者提供了强大的工具集&#xff0c;以实现这一目标。本文…...

谷粒商城实战-25-分布式组件-SpringCloud Alibaba-Nacos配置中心-加载多配置集

文章目录 一&#xff0c;拆分配置集二&#xff0c;配置文件中配置多配置集1&#xff0c;引用多配置集2&#xff0c;验证 三&#xff0c;多配置集总结1&#xff0c;使用场景2&#xff0c;优先级 这一节介绍如何加载多个配置集。 大多数情况下&#xff0c;我们把配置全部放在一个…...

UART编程

Q:为什么使用串口前要先在电脑上安装CH340驱动&#xff1f; 中断的作用&#xff1f; 环形buffer的作用&#xff1f; static和valitate的作用 三种编程方式简介 也可以通过DMA方式减小CPU资源的消耗 直接把数据在SRAM内存和UART模块进行传输 &#xff0c;流程&#xff1a; …...

C++:右值引用

右值与左值 在讲解右值引用之前&#xff0c;我们就需要先辨析一下左值与右值的区别。 左值 左值是一个表示数据的表达式&#xff0c;我们可以获取它的地址并且对其赋值&#xff0c;左值可以出现在赋值操作符的左边&#xff0c;但是右值不能。 int i 0; int* p &i; do…...

(算法)硬币问题

问题&#xff1a;有1元&#xff0c;5元&#xff0c;10元&#xff0c;50元&#xff0c;100元&#xff0c;500元的硬币各有C1,C5,C10.C50,C100,C500个。 现在要用这些硬币来支付A元&#xff0c;最小需要多少枚硬币&#xff1f; 该题使用递归算法&#xff0c;利用局部最优解来推导…...

java_网络服务相关_gateway_nacos_feign区别联系

1. spring-cloud-starter-gateway 作用&#xff1a;作为微服务架构的网关&#xff0c;统一入口&#xff0c;处理所有外部请求。 核心能力&#xff1a; 路由转发&#xff08;基于路径、服务名等&#xff09;过滤器&#xff08;鉴权、限流、日志、Header 处理&#xff09;支持负…...

FFmpeg 低延迟同屏方案

引言 在实时互动需求激增的当下&#xff0c;无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作&#xff0c;还是游戏直播的画面实时传输&#xff0c;低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架&#xff0c;凭借其灵活的编解码、数据…...

C# 类和继承(抽象类)

抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...

让AI看见世界:MCP协议与服务器的工作原理

让AI看见世界&#xff1a;MCP协议与服务器的工作原理 MCP&#xff08;Model Context Protocol&#xff09;是一种创新的通信协议&#xff0c;旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天&#xff0c;MCP正成为连接AI与现实世界的重要桥梁。…...

NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合

在汽车智能化的汹涌浪潮中&#xff0c;车辆不再仅仅是传统的交通工具&#xff0c;而是逐步演变为高度智能的移动终端。这一转变的核心支撑&#xff0c;来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒&#xff08;T-Box&#xff09;方案&#xff1a;NXP S32K146 与…...

JVM 内存结构 详解

内存结构 运行时数据区&#xff1a; Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器&#xff1a; ​ 线程私有&#xff0c;程序控制流的指示器&#xff0c;分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 ​ 每个线程都有一个程序计数…...

Visual Studio Code 扩展

Visual Studio Code 扩展 change-case 大小写转换EmmyLua for VSCode 调试插件Bookmarks 书签 change-case 大小写转换 https://marketplace.visualstudio.com/items?itemNamewmaurer.change-case 选中单词后&#xff0c;命令 changeCase.commands 可预览转换效果 EmmyLua…...

在golang中如何将已安装的依赖降级处理,比如:将 go-ansible/v2@v2.2.0 更换为 go-ansible/@v1.1.7

在 Go 项目中降级 go-ansible 从 v2.2.0 到 v1.1.7 具体步骤&#xff1a; 第一步&#xff1a; 修改 go.mod 文件 // 原 v2 版本声明 require github.com/apenella/go-ansible/v2 v2.2.0 替换为&#xff1a; // 改为 v…...

C++ 类基础:封装、继承、多态与多线程模板实现

前言 C 是一门强大的面向对象编程语言&#xff0c;而类&#xff08;Class&#xff09;作为其核心特性之一&#xff0c;是理解和使用 C 的关键。本文将深入探讨 C 类的基本特性&#xff0c;包括封装、继承和多态&#xff0c;同时讨论类中的权限控制&#xff0c;并展示如何使用类…...

二维数组 行列混淆区分 js

二维数组定义 行 row&#xff1a;是“横着的一整行” 列 column&#xff1a;是“竖着的一整列” 在 JavaScript 里访问二维数组 grid[i][j] 表示 第i行第j列的元素 let grid [[1, 2, 3], // 第0行[4, 5, 6], // 第1行[7, 8, 9] // 第2行 ];// grid[i][j] 表示 第i行第j列的…...