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')

效果类似于下图

相关推荐
生而为虫9 分钟前
28.Python处理图像
人工智能·python·计算机视觉·pillow·pygame
Dev7z9 分钟前
基于OpenCV和MATLAB的椭圆检测系统的设计与实现
人工智能·opencv·matlab
Dev7z2 小时前
基于深度学习和图像处理的药丸计数与分类系统研究
图像处理·人工智能·深度学习
饭饭大王6665 小时前
深度学习在计算机视觉中的最新进展
人工智能·深度学习·计算机视觉
雍凉明月夜8 小时前
视觉opencv学习笔记Ⅲ
笔记·opencv·学习
徽4409 小时前
农田植被目标检测数据标注与模型训练总结1
人工智能·目标检测·计算机视觉
余蓝9 小时前
本地部署!文生图LCM超简单教程
图像处理·人工智能·深度学习·ai作画·stable diffusion·dall·e 2
stormsha12 小时前
裸眼3D原理浅析AI如何生成平面裸眼3D图像以科幻战士破框而出为例
人工智能·计算机视觉·平面·3d·ai
顾道长生'17 小时前
(Arxiv-2025)ID-COMPOSER:具有分层身份保持的多主体视频合成
计算机视觉·音视频·composer
一只侯子18 小时前
Face AE Tuning
图像处理·笔记·学习·算法·计算机视觉