分水岭算法的基本原理为:将任意的灰度图像视为地形图表面,其中灰度值高的部分表示山峰和丘陵,而灰度值低的部分表示山谷。用不同颜色的水(标签)填充每个独立的山谷(局部最小值);随着水平面的上升,来自不同山谷(具有不同颜色)的水将开始合并。为了避免出现这种情况,需要在水的汇合位置建造水坝;持续填充水和建造水坝,直到所有山峰和丘陵都在水下。整个过程中建造的水坝将作为图像分割的依据。
使用分水岭算法执行图像分割操作时通常包含下列步骤。
(1)将原图像转换为灰度图像。
(2)应用形态变换中的开运算和膨胀操作,去除图像噪声,获得图像边缘信息,确定图像背景。
(3)进行距离转换,再进行阈值处理,确定图像前景。
(4)确定图像的未知区域(用图像的背景减去前景的剩余部分)。
(5)标记背景图像。
(6)执行分水岭算法分割图像。
1.cv2.distanceTransform()函数
OpenCV中的cv2.distanceTransform()函数用于计算非0值像素点到0值(背景)像素点的距离,其基本格式如下。
dst=cv2.distanceTransform(src,distanceType,maskSize[,dstType])
参数说明如下。
dst为返回的距离转换结果图像。
src为原图像,必须是8位单通道二值图像。
distanceType为距离类型。
maskSize为掩模的大小,可设置为0、3或5。
dstType为返回的图像类型,默认为CV_32F(32位浮点数)。
import cv2
import numpy as np
img=cv2.imread('qizi.jpg')
cv2.imshow('original',img) #显示原图
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) #转换为灰度图
ret,imgthresh=cv2.threshold(gray,0,255,
cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU) #Otsu算法阈值处理
kernel=np.ones((3,3),np.uint8) #定义形态变换卷积核
imgopen=cv2.morphologyEx(imgthresh,cv2.MORPH_OPEN,kernel,iterations=2) #形态变换:开运算
imgdist=cv2.distanceTransform(imgopen,cv2.DIST_L2,5) #距离转换
cv2.imshow('distance',imgdist) #显示距离转换结果
cv2.waitKey(0)