scipy.ndimage.distance_transform_edt 和 cv2.distanceTransform用法

article/2025/10/12 12:47:24

scipy.ndimage.distance_transform_edt cv2.distanceTransform 的作用都是计算一张图上每个前景像素点到背景的最近距离。

import cv2
import numpy as np
from scipy.ndimage import distance_transform_edta = np.array(([0, 1, 1, 1, 1],[0, 0, 1, 1, 1],[0, 1, 1, 1, 1],[0, 1, 1, 1, 0],[0, 1, 1, 0, 0]))
print(a.shape)  # (5, 5)
y1 = distance_transform_edt(a)
print(y1)
# [[0.         1.         1.41421356 2.23606798 3.        ]
#  [0.         0.         1.         2.         2.        ]
#  [0.         1.         1.41421356 1.41421356 1.        ]
#  [0.         1.         1.41421356 1.         0.        ]
#  [0.         1.         1.         0.         0.        ]]
y2 = cv2.distanceTransform(a.astype(np.uint8), cv2.DIST_L2, maskSize=cv2.DIST_MASK_PRECISE)
print(y2)
# [[0.        1.        1.4142135 2.236068  3.       ]
#  [0.        0.        1.        2.        2.       ]
#  [0.        1.        1.4142135 1.4142135 1.       ]
#  [0.        1.        1.4142135 1.        0.       ]
#  [0.        1.        1.        0.        0.       ]]

这里输入中前景为1,背景为0。

cv2.distanceTransform的参数需要注意一下

  • 输入的数据类型需要是8-bit的,这里输入a默认数据类型为int32,因此需要通过.astype(np.uint8)先转换一下,否则会报错。而在distance_transform_edt中没有这点要求。
  • 第二个参数cv2.DIST_L2表示欧式距离
  • 第三个参数maskSize表示掩码大小,决定了距离计算的精度

maskSize参数

这里网上找了半天没找到比较详细的解释,这里也不涉及实际计算距离时用到的算法,只结合实例介绍一下自己的理解

maskSize有三个可选值分别为DIST_MASK_3、DIST_MASK_5、cv2.DIST_MASK_PRECISE,分别表示3x3 mask、5x5 mask、精确计算。

下图中的L2表示我们这里例子中的欧式距离,其中a表示水平或者竖直方向移动一个像素的距离,cv2.DIST_MASK_PRECISE即精确距离a=1,当采用5x5 mask时,a也是1,但当采用3x3 mask时,水平或者竖直移动一个像素的距离a=0.955,至于背后采用的是什么加速算法以及这个值是怎么得来的这里就不多做讨论了。b表示对角线方向移动一个像素的距离,精确值 \(b=\sqrt{1^{2}+1^{2}}=\sqrt{2}\approx 1.4142135\),5x5 mask下b=1.4,3x3 mask下b=1.3693。当采用5x5 mask时还有一个c值,这里c的距离是象棋中日字对角线的距离,即水平和竖直方向一个方向移动一个像素,另一个方向移动两个像素,精确值为 \(b=\sqrt{1^{2}+2^{2}}=\sqrt{5}\approx 2.236068\),这里近似为c=2.1969。

有了a,b,c值,mask size内所有位置的距离都可以根据周围像素的距离递推得到,比如下面例子中3x3 mask输出结果中的右上角的2.8650055就可以通过最右列第二行的像素向上移动一个像素得到即2.8650055=1.9100037+0.95500183。

多通道

上面的输入都是单通道的情况,scipy.ndimage.distance_transform_edt是支持多通道的,但cv2.distanceTransform中专门提到输入只能是单通道的,因此如果是多通道只能通过for循环实现了。

在训练模型中,当有多类别或想要计算一整个batch时,scipy.ndimage.distance_transform_edt会更方便些。

import cv2
import numpy as np
from scipy.ndimage import distance_transform_edta = np.array((([0, 1, 1, 1, 1],[0, 0, 1, 1, 1],[0, 1, 1, 1, 1],[0, 1, 1, 1, 0],[0, 1, 1, 0, 0]),([0, 1, 1, 1, 1],[0, 0, 1, 1, 1],[0, 1, 1, 1, 1],[0, 1, 1, 1, 0],[0, 1, 1, 0, 0])))y1 = distance_transform_edt(a)
print(y1.shape)  # (2, 5, 5)
print(y1)
# [[[0.         1.         1.41421356 2.23606798 3.        ]
#   [0.         0.         1.         2.         2.        ]
#   [0.         1.         1.41421356 1.41421356 1.        ]
#   [0.         1.         1.41421356 1.         0.        ]
#   [0.         1.         1.         0.         0.        ]]
#  [[0.         1.         1.41421356 2.23606798 3.        ]
#   [0.         0.         1.         2.         2.        ]
#   [0.         1.         1.41421356 1.41421356 1.        ]
#   [0.         1.         1.41421356 1.         0.        ]
#   [0.         1.         1.         0.         0.        ]]]
for single_c in a:y2 = cv2.distanceTransform(single_c.astype(np.uint8), cv2.DIST_L2, maskSize=cv2.DIST_MASK_PRECISE)print(y2.shape)  # (5, 5)print(y2)# [[0.        1.        1.4142135 2.236068  3.       ]#  [0.        0.        1.        2.        2.       ]#  [0.        1.        1.4142135 1.4142135 1.       ]#  [0.        1.        1.4142135 1.        0.       ]#  [0.        1.        1.        0.        0.       ]]

参考

cv.distanceTransform - mexopencv

OpenCV学习三十五:distanceTransform 距离变换函数_Thomas会写字的博客-CSDN博客_distancetransform


http://chatgpt.dhexx.cn/article/u6oKDKRB.shtml

相关文章

java edt,java并发之EDT测试

测试代码如下: 1、耗时计算没有单独起线程处理,耗时计算在EDT线程执行,导致界面没有响应,处于卡死状态 package thread; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.concurrent…

linux服务端修改EDT为东八区,EDT开发环境配置

1 安装条件 512MB内存或更高 Win XP/Win Vista/Win 7/RedHat Linux 32位或者64位操作系统(推荐32位) 安装IE7/8/9、FireFoxLatest Version、Chrome等浏览器中的一种 OracleJRE 1.6或更高版本 2 安装步骤 EDT 0.8.0已经发布发布。用户现在可以在http://www.eclipse.org/edt/#d…

修改linux系统的时间EDT为CST

问题: Centos 系统时间下午时间显示为12小时制 分析: 开始以为是要设置为24小时制 后来执行date命令发现是EDT,EDT 是北美东部夏令时间,比UTC落后4个小时 解决: # mv /etc/localtime /etc/localtime.bak # ln -s …

EDT技术 ug - 第四章节Creation of the EDT Logic (持续更新)

文章目录 Compression Analysisanalyze_compression Preparetion For EDT Logic CreationParameter Specification for the EDT LogicDual Compresson ConfigurationDefine Dual Compression ConfigurationsASYmmetric Input and Output ChannelsBypass Scan ChainsLatch-Based…

java edt,Java Swing 学问篇 - EDT

Java Swing 常识篇之EDT 从毕业到现在用SWING已经一年多,在这里想总结一下过去学到的东西和经验,和各位兄弟姐妹们一起分享。在以后的文章中也会和大家一起来分享一些好的框架。说起JAVA SWING,普遍给人的感觉是“丑、慢、难”,丑…

edt嵌入式确定性测试_CallSerially EDT和InvokeAndBlock(第1部分)

edt嵌入式确定性测试 我们上一次在2008年解释了EDT背后的一些概念,因此,我们很高兴再次撰写有关EDT的文章,在开发人员指南以及有关Udemy的课程中都有关于EDT的部分,但是由于这是最重要的了解在Codename One中,它几乎没…

EDT部署功能介绍

EDT部署功能介绍 当你在开发EDT Web前段程序的时候,你需要接触到EDT部署操作,从而将生成好的RUIHandler和Service的目标代码部署复制到目标Web程序中。和大家所熟知的部署到应用程序服务器上不同,EDT的部署操作是将生成好的Java/JavaScript/…

EDT技术 ug - 第一章节 Getting Start

文章目录 引言TestKompress Compression LogicEDT FlowEDT IP generationEDT synEDT IP pattern gennerationATPG 熟悉工具batch mode执行系统命令 本系列介绍的是Tessent的EDT( Embedded Deterministic Testing)技术。 参考为EDT tessent的 TestCompre…

DIY01_NE555叮咚门铃

文章目录 项目简介电路原理一、555定时器电路结构及工作原理二、叮咚门铃电路工作原理 原理图与PCB图一、原理图二、PCB图1. 初版2. 改进版 实物图立创打板流程经验总结 项目简介 第一次尝试自己DIY一个小电路设计,笔者选择了相对简单的NE555叮咚门铃。在本篇博客中…

NE555波形发生器手把手教程之NE555内部结构(一)

通过ne555搭建的波形发生器 可实现方波、三角波、正弦波输出 工程链接:https://pan.baidu.com/s/1T-9bdnO1IrWUsjmRTl12zQ 提取码:py66 一、芯片介绍 参数 供应电压:4.5-18V 供应电流:10-15mA 输出电流:225mA (m…

NE555基本原理及相关公式的推导

NE555基本原理及相关公式的推导 基本原理公式推导 基本原理 NE555主要由分压电路,电压比较器,RS触发器三部分组成; 分压电路电压比较器RS触发器提供电压比较器比较电压根据触发信号输出高低电平用于输出矩形波 当 V A > 2 3 V c c V_A&g…

模电学习12. NE555 方波信号发生器

模电学习12. NE555 方波信号发生器 一、NE555 基本功能1. 基本作用2. 基本组成 二、NE555方波生成电路1. 基本原理2. 原理图3. 仿真(1)RP1 设置为10%(2)RP1设置为90% 4. 实际电路 一、NE555 基本功能 1. 基本作用 NE555是一款广…

mysql profile 工具Neor Profile

一、下载Download - Neor Profile SQL http://www.profilesql.com/files/download/sqlprofiler-4.1.1.exe Neor Profile 这款免费的mysql 分析工具,这个工具类似于一个代理 本地启动一个mysql 代理服务,类似于MyCat 二、安装完成配置 三、代码连接代…

蓝桥杯NE555定时器与频率测量

使用的是蓝桥杯单片机CT107D实训平台: 555定时器内部,有3个5K的电阻分压。 NE555是一个纯硬件的设计,一旦电路确定了,其功能也就定了。 在蓝桥杯的板子上,555定时器是一个信号发生电路,通过定位器Rb3可改…

NE555的使用与理解

NE555 一款模拟与数字信号的集成芯片,通过一个电容充放电来输出方波,电容充放电的快慢决定了NE555输出的方波的频率,再通过控制两个电阻的比值来改变其输出方波的占空比。 外观图 内部图 因为NE555中有三个电阻R且都为5K所以称为555&#x…

蓝桥杯单片机设计与开发⑬ ---NE555模块

一、555定时器&频率测量 1. 电路原理 NE555是一种时钟芯片,输出一定频率的脉冲信号。就其模块特性,简单点来说,该模块会根据Rb3电位器的阻值,在SIG脚输出相应的频率的脉冲信号。 第十届竞赛中对该模块设置了考点,…

NE555 Motor LED Chaser

文章目录 1.前言2.资料下载 1.前言 这个是从YouTube上搬运来的,如图所示 2.资料下载 所需材料 #1# 10k resistor 1 #2# 10k variable resistor 1 #3# 10uf capacitor 1 #4# 3mm blue led 4 #5# 3mm yellow led 4 #6# 3mm red led 4 #7# 3mm green led 4 #8# 3mm…

单片机蓝桥杯——NE555频率测量

原理: 对蓝桥杯单片机板子上NE555电路进行频率测量时,不需要任何的配置,整个单片机测量频率的过程中,跟NE555芯片没什么关系,归根结底考察的还是定时/计数器。但需要注意: (1)当用到NE555时&am…

蓝桥杯单片机-NE555模块

一、简介 1、NE555在开发板中用于输出频率可变,占空比不变的方波。 2、NE555是纯硬件的设计,通过电位器RB3可改变其信号输出频率。不需要编程实现其功能。 考点:使用定时器的计数模式测量NE555输出的频率 3、开发板上电路 NET SIG即接P34&…

NE555产生方波

NE555详解 上图是芯片的引脚图 上图是芯片的内部结构图,脚号与第一张图的引脚相对应 从结构图可以得出下表: 接下来看应用图; 这是从CSDN上得到的一个方波发生器的原理图,对齐进行分析: 原理图将6和2脚连在一起, 所…