# 4.14 基于分水岭算法的图像分割

## 目标

• 我们将学习使用基于标记的分水岭算法来进行图像分割
• 我们将看到：`cv2.watershed()`

## 代码

``````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)``````

``````# 噪音消除
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,cv2.DIST_L2,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, markers = cv2.connectedComponents(sure_fg)

# 为所有标签+1，以确保背景不是0，而是1
markers = markers+1

# 现在，用零标记未知区域
markers[unknown==255] = 0``````

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

## 练习

• OpenCV样本具有分水岭分割的交互式样本watershed.py。运行它，享受它，然后学会它。