8.3 Python图像处理之图像典型分割-分水岭分割

8.3 Python图像处理之图像典型分割-分水岭分割

文章目录

  • 8.3 Python图像处理之图像典型分割-分水岭分割
    • 1 算法原理
    • 2 代码
    • 3 效果

1 算法原理

分水岭概念是以对图像进行三维可视化处理为基础的:其中两个是坐标,另一个是灰度级。基于“地形学”的这种解释,我们考虑三类点:

a.属于局部性最小值的点,也可能存在一个最小值面,该平面内的都是最小值点;

b.当一滴水放在某点的位置上的时候,水一定会下落到一个单一的最小值点; c.当水处在某个点的位置上时,水会等概率地流向不止一个这样的最小值点。

对一个特定的区域最小值,满足条件(b)的点的集合称为这个最小值的“汇水盆地”或“分水岭”。满足条件©的点的集合组成地形表面的峰线,称做“分割线”或

“分水线”。

8.3 Python图像处理之图像典型分割-分水岭分割_第1张图片

分水岭分割方法,是一种基于拓扑理论的数学形态学的分割方法,目前较著名且使用较多的有 2 种算法:自下而上的模拟泛洪的算法;自上而下的模拟降水的算法。

2 代码

运行代码说明

1.要改变代码中的图片地址(地址不能有中文)

更改put(path)函数中的路径put(r'../image/image1.jpg')

2.注意最后的plt.savefig('1.new.jpg')是保存plt图像,如果不使用可以注释掉

代码依赖包:

matplotlib  3.4.2
numpy  1.20.3
opencv-python  4.1.2.30
imageio  2.9.0
pillow  8.2.0
PyWavelets  1.1.1
scikit-image  0.18.1
# pip安装
pip install matplotlib numpy opencv-python imageio pillow PyWavelets scikit-image
import numpy as np
import cv2
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

def put(path):
    src = cv2.imread(path)
    img = src.copy()
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)  # Otsu's 二值化

    # 消除噪声
    kernel = np.ones((3, 3), np.uint8)
    opening = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=2)

    # 膨胀
    sure_bg = cv2.dilate(opening, kernel, iterations=3)

    # 距离变换
    dist_transform = cv2.distanceTransform(opening, 1, 5)
    ret, sure_fg = cv2.threshold(dist_transform, 0.7 * dist_transform.max(), 255, 0)

    # 获得未知区域获得边界区域
    sure_fg = np.uint8(sure_fg)
    unknown = cv2.subtract(sure_bg, sure_fg)

    # 标记
    ret, markers1 = cv2.connectedComponents(sure_fg)

    # 确保背景是1不是0
    markers = markers1 + 1

    # 未知区域标记为0
    markers[unknown == 255] = 0

    markers3 = cv2.watershed(img, markers)
    img[markers3 == -1] = [0, 0, 255]

    plt.subplot(241), plt.imshow(cv2.cvtColor(src, cv2.COLOR_BGR2RGB)),
    plt.title('原图'), plt.axis('off')
    plt.subplot(242), plt.imshow(thresh, cmap='gray'),
    plt.title('Otsu二值化'), plt.axis('off')
    plt.subplot(243), plt.imshow(sure_bg, cmap='gray'),
    plt.title('膨胀'), plt.axis('off')
    plt.subplot(244), plt.imshow(dist_transform, cmap='gray'),
    plt.title('距离变换'), plt.axis('off')
    plt.subplot(245), plt.imshow(sure_fg, cmap='gray'),
    plt.title('距离变换二值化'), plt.axis('off')
    plt.subplot(246), plt.imshow(unknown, cmap='gray'),
    plt.title('边界区域'), plt.axis('off')
    plt.subplot(247), plt.imshow(np.abs(markers), cmap='jet'),
    plt.title('标记区域'), plt.axis('off')
    plt.subplot(248), plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)),
    plt.title('分割图像'), plt.axis('off')

    # plt.savefig('3.new-img.jpg')
    plt.show()


# 图像处理函数,要传入路径
put(r'../image/img5.jpg')

3 效果

8.3 Python图像处理之图像典型分割-分水岭分割_第2张图片

你可能感兴趣的:(python图像处理,opencv,python)