181.基于 Sobel 梯度的分水岭算法

10. 轮廓与图像分割索引

  • 图像分割之分水岭算法

一、图像分割之分水岭算法

  • 分水岭算法是一种图像区域分割法,以临近像素间的相似性作为重要特征,从而将空间位置相近且灰度值相近的像素点互相连接起来,构成一个封闭的轮廓。

  • 分水岭算法是基于形态学的图像分割方法,体现了边缘检测、阈值处理和区域提取的概念和思想,往往会产生更稳定的分割结果。算法的实现过程可以理解为洪水淹没的过程:最低点首先被淹没,然后水逐渐淹没整个山谷;水位升高到一定高度就会溢出,于是在溢出位置修建堤坝;不断提高水位,重复上述过程,直到所有的点全部被淹没;所建立的一系列堤坝就成为分隔各个盆地的分水岭。

  • 分水岭的计算过程是一个迭代标注过程,通过寻找集水盆和分水岭对图像进行分割。经典的分水岭算法分为排序过程和淹没过程两个步骤,首先对每个像素的灰度级从低到高排序,然后在从低到高的淹没过程中,对每一个局部极小值在 h 阶高度的影响域进行判断及标注。

二、基于 Sobel 梯度的分水岭算法

  • 在分水岭算法之前通常要对图像进行滤波以消除噪点,但也使弱边缘被平滑,分水岭的峰值弱化。梯度处理可以强化边缘,把梯度图像作为输入图像,可以避免弱边缘在分水岭填充过程中被淹没。可以使用 Sobel、Canny 梯度算子,也可以用形态学梯度操作获得梯度图像。

  • 基于梯度的分水岭算法通过梯度函数使得集水盆只响应想要探测的目标,对微弱边缘也有良好的响应,但图像中的噪声容易导致过分割。对此,在对梯度图像进行阈值分割转换为二值图像后,运用开运算消除噪点非常重要,可以有效地抑制梯度图像的过分割。

  • 基于梯度的分水岭算法的步骤为:
    (1)首先对图像进行梯度处理获得梯度图像,阈值分割将梯度图像转换为二值图像,运用开运算消除噪点;
    (2)通过形态学的膨胀操作,生成 “确定背景” 区域 sureBG;
    (3)通过距离变换,并由阈值分割得到高亮区域,生成 “确定前景” 区域 sureFG;
    (4)对 “确定前景” 区域 sureFG 进行连通性分析,标记为不同的连通域编号,即对多个分割目标进行编号;
    (5)“确定前景” 区域 sureFG 与 “确定背景” 区域重合的部分,作为 “待定区域” unknown;
    (6)从连通域标记图像中去除 “确定背景” 区域,作为分水岭算法的标注图像;
    (7)基于标记图像使用分水岭算法进行分割,得到各个分割目标的轮廓;
    (8)把目标的轮廓添加到原始图像上。

三、例程

  • 11.38 基于 Sobel 梯度的分水岭算法
    # 11.38 基于 Sobel 梯度的分水岭算法
    img = cv2.imread("../images/Fig1039a.tif", flags=1)  # 读取彩色图像(BGR)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # 转为灰度图像

    # 高斯模糊
    Gauss = cv2.GaussianBlur(gray, (5,5), sigmaX=10.0)
    # 计算 Sobel 梯度算子
    SobelX = cv2.Sobel(Gauss, cv2.CV_32F, 1, 0)  # 计算 x 轴方向
    SobelY = cv2.Sobel(Gauss, cv2.CV_32F, 0, 1)  # 计算 y 轴方向
    grad = np.uint8(cv2.normalize(np.sqrt(SobelX**2+SobelY**2), None, 0, 255, cv2.NORM_MINMAX))

    # 阈值分割,将灰度图像分为黑白二值图像
    _, thresh = cv2.threshold(np.uint8(grad), 0.2*grad.max(), 255, cv2.THRESH_BINARY)
    # 形态学操作,生成 "确定背景" 区域
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))  # 生成 3*3 结构元
    opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=2)  # 开运算,消除噪点
    sure_bg = cv2.dilate(opening, kernel, iterations=3)  # 膨胀操作,生成 "确定背景" 区域
    # 距离变换,生成 "确定前景" 区域
    distance = cv2.distanceTransform(opening, cv2.DIST_L2, 5)  # DIST_L2: 3/5
    _, sure_fg = cv2.threshold(distance, 0.1 * distance.max(), 255, 0)  # 阈值选择 0.1*max 效果较好
    sure_fg = np.uint8(sure_fg)
    # 连通域处理
    ret, component = cv2.connectedComponents(sure_fg, connectivity=8)  # 对连通区域进行标号,序号为 0-N-1
    markers = component + 1  # OpenCV 分水岭算法设置标注从 1 开始,而连通域编从 0 开始
    kinds = markers.max()  # 标注连通域的数量
    maxKind = np.argmax(np.bincount(markers.flatten()))  # 出现最多的序号,所占面积最大,选为底色
    markersBGR = np.ones_like(img) * 255
    for i in range(kinds):
        if (i!=maxKind):
            colorKind = [np.random.randint(0, 255), np.random.randint(0, 255), np.random.randint(0, 255)]
            markersBGR[markers==i] = colorKind
    # 去除连通域中的背景区域部分
    unknown = cv2.subtract(sure_bg, sure_fg)  # 待定区域,前景与背景的重合区域
    markers[unknown == 255] = 0  # 去掉属于背景的区域 (置零)
    # 分水岭算法标注目标的轮廓
    markers = cv2.watershed(img, markers)  # 分水岭算法,将所有轮廓的像素点标注为 -1
    kinds = markers.max()  # 标注连通域的数量

    # 把轮廓添加到原始图像上
    imgWatershed = img.copy()
    imgWatershed[markers == -1] = [0, 0, 255]  # 将分水岭算法标注的轮廓点设为红色
    print(img.shape, markers.shape, markers.max(), markers.min(), ret)

    plt.figure(figsize=(10, 6))
    plt.subplot(231), plt.axis('off'), plt.title("Origin image")
    plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))  # 显示 img(RGB)
    plt.subplot(232), plt.axis('off'), plt.title("Gradient")
    plt.imshow(grad, 'gray')  # 钝化掩蔽
    plt.subplot(233), plt.axis('off'), plt.title("Sure_bg")
    plt.imshow(sure_bg, 'gray')  # 确定背景
    plt.subplot(234), plt.axis('off'), plt.title("Sure_fg")
    plt.imshow(sure_fg, 'gray')  # 确定前景
    plt.subplot(235), plt.axis('off'), plt.title("Markers")
    # plt.imshow(markers, 'gray')  # 图像标注
    plt.imshow(cv2.cvtColor(markersBGR, cv2.COLOR_BGR2RGB))
    plt.subplot(236), plt.axis('off'), plt.title("Watershed")
    plt.imshow(cv2.cvtColor(imgWatershed, cv2.COLOR_BGR2RGB))
    plt.tight_layout()
    plt.show()    

四、资料

youcans_的博客:
https://blog.csdn.net/youcans/article/details/124766231
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容