OpenCV 分水岭算法--距离变换distanceTransform
程序员文章站
2022-05-16 11:20:08
...
距离变换原理
距离变换的定义是:计算一个图像中非零像素点到最近的像素点的距离,也就是到零像素点的最短距离。
距离变换的处理图像通常是二值图像
什么是二值图像:就是把图像分为两个部分,即:背景和物体(前景目标)两部分
通常情况下,
我们把前景目标的灰度值设置为255,也就是白色
背景的灰度值我们设置为0,也就是黑色
所以回归到距离变换原理,
非零像素点就是前景目标
零像素点就是背景
如上图所示,手就是前景目标,黑色就是背景。
图像中前景目标的像素点距离背景的像素点越远,
用一个像素值来替换这个距离值,那么新生成的图像的这个点(前景目标的像素点)越亮。
手指相对于手掌来说,手指的距离比较近,所以替换得到的像素点比较小(暗)
而手掌的距离比较大,所替换的像素点比较大(亮)
通过合理的阈值对距离变换后的图像进行二值化处理,即可去除手指,手掌重心即为图像的几何中心。
distancetransform 函数
主要用于计算非零像素到最近零像素点的距离,一般用于求解图像的骨骼,得到的是距离图像数组。
def distanceTransform(src, distanceType, maskSize, dst=None, dstType=None)
- src:输入的图像,一般为二值图像
- distanceType:所用的求解距离的类型(CV_DIST_L1, CV_DIST_L2 , CV_DIST_C)
- maskSize:距离变换掩模的大小
骨骼显示如果想要骨骼显示,我们需要对distanceTransform返回的结果进行归一化处理,使用normalize
mask
用户自定义距离情况下的 mask。
- 3×3 mask 下它由两个数(水平/垂直位量,对角线位移量)组成
- 5×5 mask 下由三个数组成(水平/垂直位移量,对角位移和 国际象棋里的马步(马走日))
函数 cvDistTransform 二值图像每一个象素点到它最邻近零象素点的距离。
对零象素,函数设置 0 距离
对其它象素,它寻找由基本位移(水平、垂直、对角线或knight’s move,最后一项对 5×5 mask 有用)构成的最短路径。
- 由于距离函数是对称的,所有水平和垂直位移具有同样的代价 (表示为 a )
- 所有的对角位移具有同样的代价 (表示为 b)
- 所有的 knight’s 移动具有同样的代价 (表示为 c)
对类型 CV_DIST_C 和 CV_DIST_L1,距离的计算是精确的,而类型 CV_DIST_L2 (欧式距离) 距离的计算有某些相对误差 (5×5 mask 给出更精确的结果)
OpenCV 使用 [Borgefors86] 推荐的值:
- CV_DIST_C (3×3):a=1, b=1
- CV_DIST_L1 (3×3):a=1, b=2
- CV_DIST_L2 (3×3):a=0.955, b=1.3693
- CV_DIST_L2 (5×5):a=1, b=1.4, c=2.1969