距离变换的定义是计算一个图像中非零像素点到最近的零像素点的距离,也就是到零像素点的最短距离。即距离变换的定义是计算一个图像中非零像素点到最近的零像素点的距离,也就是到零像素点的最短距离。
通常处理的是一个二值化的图,所以求距离可以归一化,距离(像素距离)单位为1。
该函数有两个初始化API
C++: void distanceTransform(InputArray src, OutputArray dst, int distanceType, int maskSize)
C++: void distanceTransform(
InputArray src,
OutputArray dst,
OutputArray labels,
int distanceType,
int maskSize,
int labelType=DIST_LABEL_CCOMP )
src – 8-bit, 单通道(二值化)输入图片。
dst – 输出结果中包含计算的距离,这是一个32-bit float 单通道的Mat类型数组,大小与输入图片相同。
distanceType – 计算距离的类型那个,可以是 CV_DIST_L1、CV_DIST_L2 、CV_DIST_C。
maskSize – 距离变换掩码矩阵的大小,可以是
3(CV_DIST_L1、 CV_DIST_L2 、CV_DIST_C)
5(CV_DIST_L2 )
CV_DIST_MASK_PRECISE (这个只能在4参数的API中使用)
labels – 可选的2D标签输出(离散 Voronoi 图),类型为 CV_32SC1 大小同输入图片。
labelType – 输出标签的类型,这里有些两种。
labelType==DIST_LABEL_CCOMP 将周围较近的白色像素点作为一个整体计算其到黑色边缘的距离
labelType==DIST_LABEL_PIXEL 单独计算每个白色像素点到其黑色边缘的距离.
distanceType参数说明
CV_EXPORTS_W void distanceTransform( InputArray src, OutputArray dst,
int distanceType, int maskSize, int dstType=CV_32F);
enum DistanceTypes {
DIST_USER = -1, //!< User defined distance
DIST_L1 = 1, //!< distance = |x1-x2| + |y1-y2|
DIST_L2 = 2, //!< the simple euclidean distance
DIST_C = 3, //!< distance = max(|x1-x2|,|y1-y2|)
DIST_L12 = 4, //!< L1-L2 metric: distance = 2(sqrt(1+x*x/2) - 1))
DIST_FAIR = 5, //!< distance = c^2(|x|/c-log(1+|x|/c)), c = 1.3998
DIST_WELSCH = 6, //!< distance = c^2/2(1-exp(-(x/c)^2)), c = 2.9846
DIST_HUBER = 7 //!< distance = |x|
import numpy as np
import matplotlib.pyplot as plt
import cv2
# Generate test image
size = (100, 100)
mid_line = np.zeros(size, dtype='uint8')
mid_line[(np.linspace(20, 80, 61).astype(int),
np.linspace(50, 50, 61).astype(int))] = 1
outline = np.zeros(size, dtype='uint8')
outline[(np.linspace(20, 80, 61).astype(int),
np.linspace(20, 20, 61).astype(int))] = 1
outline[(np.linspace(20, 80, 61).astype(int),
np.linspace(80, 80, 61).astype(int))] = 1
src=255 - (255*mid_line)
dist = cv2.distanceTransform(src, cv2.DIST_L2, 5)
print('dist',dist,np.shape(dist))
# Visualize
plt.figure("Mid line plus edges over the distance transform")
plt.imshow(dist, cmap='gray')
overlay = mid_line + 2 * outline
plt.imshow(np.ma.masked_where(overlay == 0, overlay), cmap='jet', alpha=0.6)
# Get the maximum width
max_width = np.max(dist[outline > 0])
print("Maximum width:", max_width)