cv2.distanceTransform(src, distanceType, maskSize, dst=None, dstType=None)
cv2.connectedComponents(image, labels=None, connectivity=None, ltype=None)
cv2.watershed(image, markers)
import cv2 as cv
import numpy as np
def watershed_algorithm(image):
# 邊緣保留濾波EPF 去噪
blur = cv.pyrMeanShiftFiltering(image,sp=10,sr=100)
# 轉成灰度影象
gray = cv.cvtColor(blur, cv.COLOR_BGR2GRAY)
# 得到二值影象 自適應閾值
ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
cv.imshow('binary image', binary)
# 形態學操作 獲取結構元素 開操作
kernel = cv.getStructuringElement(cv.MORPH_RECT, (3, 3))
opening = cv.morphologyEx(binary, cv.MORPH_OPEN, kernel=kernel, iterations=2)
# 確定區域
sure_bg = cv.dilate(opening, kernel, iterations=3)
# cv.imshow('mor-opt', sure_bg)
# 距離變換
dist = cv.distanceTransform(opening, cv.DIST_L2, 3)
dist_out = cv.normalize(dist, 0, 1.0, cv.NORM_MINMAX)
# cv.imshow('distance-', dist_out * 50)
ret, surface = cv.threshold(dist_out, dist_out.max() * 0.6, 255, cv.THRESH_BINARY)
# cv.imshow('surface-markers', surface)
surface_fg = np.uint8(surface) # 轉成8位元整型
unkonown = cv.subtract(sure_bg, surface_fg) # 找到位置區域
# Marker labelling
ret, markers = cv.connectedComponents(surface_fg) # 連通區域
print(ret)
# 分水嶺變換
# 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[unkonown == 255] = 0
# 實施分水嶺演演算法了。標籤影象將會被修改,邊界區域的標記將變為 -1
markers = cv.watershed(image, markers=markers)
image[markers == -1] = [0, 0, 255] # 被標記的區域 設為紅色
cv.imshow('result', image)
src = cv.imread(r'./test/042.png')
src = cv.resize(src, None, fx=0.5, fy=0.5)
cv.imshow('input image', src)
watershed_algorithm(src)
cv.waitKey(0)
cv.destroyAllWindows()
執行效果如下: