opencv:距离变换 cv2.distanceTransform

函数 cv2.distanceTransform() 用于计算图像中每一个非零点像素与其最近的零点像素之间的距离(Distance Transform, DT算法),输出的是保存每一个非零点与最近零点的距离信息;图像上越亮的点,代表了离零点的距离越远。
distanceTransformWithLabels 可以返回距离图和标签图。

distance, labels = cv.distanceTransformWithLabels(opn, cv.DIST_L1, 3, labelType=cv.DIST_LABEL_CCOMP)

python 复制代码
cv2.distanceTransform(
	src, 					# 二通道二值图,uint8 格式
	distanceType, 			# 距离类型
	maskSize[, 				# 距离变换掩码的大小
	dst[, 
	dstType]]				# 要生成的标签数组的类型
	) -> dst

参数

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:每个背景像素都被赋予一个唯一的标签。

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


distanceTransformWithLabels

复制代码
import cv2 as cv

# 假设 opn 是经过预处理(如形态学开运算)的二值图像
distance, labels = cv.distanceTransformWithLabels(
    opn, 
    distanceType=cv.DIST_L1,
    maskSize=3,
    labelType=cv.DIST_LABEL_CCOMP
)

经典应用

提取硬币前景

python 复制代码
path = "..." # 补充图片路径
img = cv.imread(path, cv.IMREAD_GRAYSCALE)
_ret, img2 = cv.threshold(img, 0, 255, cv.THRESH_BINARY + cv.THRESH_OTSU)
kernel = np.ones((3, 3), np.uint8)
opn = cv.morphologyEx(img2, cv.MORPH_OPEN, kernel)
distance = cv.distanceTransform(opn, cv.DIST_L2, 3)
_ret, result = cv.threshold(distance, 0.05 * distance.max(), 255, cv.THRESH_BINARY)


plt.subplot(221), plt.imshow(img, cmap='gray'), plt.title('org'), plt.axis('off')
plt.subplot(222), plt.imshow(opn, cmap='gray'), plt.title('opn'), plt.axis('off')
plt.subplot(223), plt.imshow(distance, cmap='gray'), plt.title('distance'), plt.axis('off')
plt.subplot(224), plt.imshow(result, cmap='gray'), plt.title('result'), plt.axis('off')

效果类似于下图:

相关推荐
拜小白11 小时前
【论文解读】ZInD:带标注平面图、360° 全景与 3D 房间布局的 Zillow 室内数据集
深度学习·计算机视觉·全景图
楚山之石11 小时前
【Lancet Neurology 】多发性硬化认知障碍的 SDMT 筛查、灰质萎缩标志与认知康复循证路径
图像处理·人工智能·学习·mri
美狐美颜sdk15 小时前
视频美颜SDK中的YUV与RGBA格式有什么区别?直播APP开发解析
人工智能·计算机视觉·音视频·美颜sdk·直播美颜sdk·视频美颜sdk
沃达德软件17 小时前
智慧无人机图像识别分析技术
人工智能·目标检测·计算机视觉·目标跟踪·视觉检测·无人机
AI的探索之旅19 小时前
97 个 OpenCV 实例(三十七):二维码识别,一张图四个码的陷阱
c++·opencv·计算机视觉
晓天衡宇•评测社区21 小时前
当需求具体到图片尺寸,Nano Banana 2.1 交出了什么答案?
人工智能·计算机视觉
TMedical1 天前
MedPlanning 截骨模拟矫形功能
c++·图像处理·人工智能·qt·健康医疗
Angeldream1232 天前
第 10 章 医学影像伦理与安全
图像处理·人工智能·python·安全·机器学习·医学影像
陈嘿萌2 天前
ACM MM 2026|告别密集交互!ProtoHGF-Net:基于原型超图的RGBT目标检测新范式
图像处理·人工智能·深度学习·目标检测·计算机视觉·学术研究与理论基础
指针向南2 天前
PDF 转 HTML 免费5种方法,体积0.5%到368%
图像处理·人工智能·计算机视觉·pdf