使用分水岭算法进行图像分割时,基本的步骤为:
1.通过形态学开运算对原始图像 O 去噪。
2.通过腐蚀操作获取「确定背景 B」。需要注意,这里得到「原始图像-确定背景」即可。
3.利用距离变换函数 cv2.distanceTransform()对原始图像进行运算,并对其进行阈值处理,得到「确定前景 F」。
4.计算未知区域 UN(UN=O –B-F)。
5.利用函数 cv2.connectedComponents()对原始图像 O 进行标注。
6.对函数 cv2.connectedComponents()的标注结果进行修正。
7.使用分水岭函数完成对图像的分割。
引用自《OpenCV轻松入门》
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
img_raw = cv.imread('coin.jpg', cv.IMREAD_COLOR)
img_gray = cv.cvtColor(img_raw, cv.COLOR_BGR2GRAY)
_ret, img2 = cv.threshold(img_gray, 0, 255, cv.THRESH_BINARY_INV + cv.THRESH_OTSU)
kernel = np.ones((3, 3), np.uint8)
opening = cv.morphologyEx(img2, cv.MORPH_OPEN, kernel, iterations=2)
sure_bg = cv.dilate(opening, kernel, iterations=3)
distance = cv.distanceTransform(opening, cv.DIST_L2, 5)
_ret, sure_fg = cv.threshold(distance, 0.7 * distance.max(), 255, cv.THRESH_BINARY)
sure_fg = np.uint8(sure_fg)
unk = cv.subtract(sure_bg, sure_fg)
_ret, markers = cv.connectedComponents(sure_fg)
markers = markers + 1
markers[unk == 255] = 0
markers = cv.watershed(img_raw, markers)
imshow = img_raw.copy()
imshow[markers == -1] = [0, 255, 0]
plt.subplot(121), plt.imshow(cv.cvtColor(img_raw, cv.COLOR_BGR2RGB)), plt.title('org'), plt.axis('off')
plt.subplot(122), plt.imshow(cv.cvtColor(imshow, cv.COLOR_BGR2RGB)), plt.title('org'), plt.axis('off')