# 7.4. 基于分水岭算法的图像分割¶

## 7.4.1. 目标¶

-我们将学习使用分水岭算法使用基于标记的图像分割-我们将看到： cv2.分水岭（）

## 7.4.3. 代码¶

>>> %matplotlib inline
>>>
>>> import numpy as np
>>> import cv2
>>> from matplotlib import pyplot as plt
>>>
>>> gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
>>> ret, thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)

>>> plt.imshow(thresh)

<matplotlib.image.AxesImage at 0x7fe4b9f20dd8>


>>> # noise removal
>>> kernel = np.ones((3,3),np.uint8)
>>> opening = cv2.morphologyEx(thresh,cv2.MORPH_OPEN,kernel, iterations = 2)
>>>
>>> # sure background area
>>> sure_bg = cv2.dilate(opening,kernel,iterations=3)

>>> plt.imshow(sure_bg)

<matplotlib.image.AxesImage at 0x7fe4b9e3c7b8>

>>> # Finding sure foreground area
>>> dist_transform = cv2.distanceTransform(opening,cv2.DIST_L2,5)
>>> ret, sure_fg = cv2.threshold(dist_transform,0.7*dist_transform.max(),255,0)
>>>
>>> # Finding unknown region
>>> sure_fg = np.uint8(sure_fg)
>>> unknown = cv2.subtract(sure_bg,sure_fg)

>>> plt.imshow(sure_fg)

<matplotlib.image.AxesImage at 0x7fe4b9e13f98>


>>> # Marker labelling
>>> ret, markers = cv2.connectedComponents(sure_fg)
>>>
>>> # Add one to all labels so that sure background is not 0, but 1
>>> markers = markers+1
>>>
>>> # Now, mark the region of unknown with zero
>>> markers[unknown==255] = 0

>>> plt.imshow(markers)

<matplotlib.image.AxesImage at 0x7fe4b9d736a0>


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

>>> plt.imshow(markers)

<matplotlib.image.AxesImage at 0x7fe4b9d44a58>


## 7.4.4. 额外资源¶

1. CMM页面打开 Watershed Tranformation

## 7.4.5. 练习¶

1. OpenCV样本有一个关于分水岭分割的交互式样本， $$watershed.py$$ . 运行它，享受它，然后学习它。