前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >OpenCV 图像分析之 —— 距离变换

OpenCV 图像分析之 —— 距离变换

作者头像
为为为什么
发布2022-08-09 15:44:29
4.7K0
发布2022-08-09 15:44:29
举报
文章被收录于专栏:又见苍岚

函数 cv2.distanceTransform() 用于计算图像中每一个非零点像素与其最近的零点像素之间的距离(Distance Transform, DT算法),本文记录OpenCV 距离变换相关内容。

距离变换

OpenCV中,函数cv2.distanceTransform()用于计算图像中每一个非零点像素与其最近的零点像素之间的距离,输出的是保存每一个非零点与最近零点的距离信息;图像上越亮的点,代表了离零点的距离越远。

  • 图像的距离变换定义为一幅新图像,其中每个输出像素的值被设为输入图像中与最近的零像素的距离一当然得根据某个特定的距离度量。不难看出,距离变换生成的是某种边缘图像。在大多数应用中,距离变换的输入是边缘检测器的输出,就像把Canny边缘检测器反过来(使得边缘变成0,其他非边缘变成非0)。
  • 计算距离变换的方式有两种:
    • 第一种方法是使用通常为3×3或5×5阵列掩膜,数组中的每个点都定义了与掩膜中心相对的特定位置的点的“距离”。更大的距离是作为掩膜成员定义的“移动”序列被构建的(并且因此是近似的)。使用这个方法时,给定一个特定的距离度量,OpenCV就会自动从集合中选择一种近似掩膜。这是Borgefors在1986年提出的“原始”方法。 原始论文
    • 第二种方法计算精确的距离,由 Felzenszwalb 提出。 原始论文

两种方法运算复杂度与像素数都是线性关系,但精确的算法会稍慢一点。

原始 DT 算法

参考论文: 《Distance Transformations in Digital Images》

  • 计算二维图像中非特征点距离最近特征点的距离,例如:
  • 其中 * 为特征点,右图记录了非特征点到特征点的距离
  • 算法需要一个距离模板,可以按照 L1, L2 的定义来配置,也可以自定义,中心必须为0
    • 以最简单的模板示例 1 1 1 1 0 1 1 1 1
  • 该模板在特征点或定义过距离的像素上滑动,覆盖到未定义距离的点时,记录当前中心像素值和模板位置的值之和,放到该未定义点的候选距离列表中
  • 之后每个被覆盖到的未定义点从距离和中选择最小的作为自己的距离定义
  • 对定义过的像素遍历完成后即可开启下一轮遍历,表示为:

  • 其中v_{i,j}^m为第 m 轮迭代时图像中(i,j)的像素值,c(k,l) 为模板中对应的值
  • 直到某一轮迭代后没有值被修改,或所有值都被定义过距离
  • 引用原文的示例:

该方法计算出的不是精确的距离,胜在速度较快

OpenCV 实现

cv2.distanceTransform()

为源图像的每个像素计算到最近零像素的距离。 官方文档

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

参数

含义

cv2.DIST_USER

用户自定义距离

cv2.DIST_L1

L1 距离 $

cv2.DIST_L2

L2 距离,欧氏距离

cv2.DIST_C

$max(

cv2.DIST_L12

$2(sqrt(1+x*x/2) - 1))$

cv2.DIST_FAIR

$ c^2(

cv2.DIST_WELSCH

$ c2/2(1-exp(-(x/c)2)), c = 2.9846$

cv2.DIST_HUBER

$

参数

含义

cv2.DIST_MASK_3

mask=3

cv2.DIST_MASK_5

mask=5

cv2.DIST_MASK_PRECISE

该函数不支持该参数

  • 示例代码 图片来自 知乎
代码语言:javascript
复制
img_org = mt.cv_rgb_imread('dis_trans.jpg', gray=True)
img = (img_org > 100).astype('uint8')
res = cv2.distanceTransform(img, distanceType=cv2.DIST_L2, maskSize=0)
PIS(img>0, res)

cv2.distanceTransformWithLabels

距离变换的另一个重载,不仅计算最短零距离,也会报告最小距离对应的对象。 官方文档

  • 函数使用
代码语言:javascript
复制
cv2.distanceTransformWithLabels(
	src, 
	distanceType, 
	maskSize[, 
	dst[, 
	labels[, 
	labelType]]]) ->
	dst, labels

参数

含义

cv2.DIST_LABEL_CCOMP

Src 中的每个零点连接元件(图论)(以及所有最接近连接元件(图论)的非零像素)都会被分配相同的标签

cv2.DIST_LABEL_PIXEL

每个零像素(以及离它最近的所有非零像素)都有自己的标签。

  • 示例代码
代码语言:javascript
复制
img_org = mt.cv_rgb_imread('dis_trans.jpg', gray=True)
img = (img_org > 100).astype('uint8')
res_ccomp = cv2.distanceTransformWithLabels(img, distanceType=cv2.DIST_L2, maskSize=0, labelType=cv2.DIST_LABEL_CCOMP)
res_pixel = cv2.distanceTransformWithLabels(img, distanceType=cv2.DIST_L2, maskSize=0, labelType=cv2.DIST_LABEL_PIXEL)
PIS(img_org, res_ccomp[0], res_ccomp[1] % 17, res_pixel[1] % 17)

参考资料

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年4月1日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 距离变换
  • 原始 DT 算法
  • OpenCV 实现
    • cv2.distanceTransform()
      • cv2.distanceTransformWithLabels
      • 参考资料
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档