
Вот мой образец_изображения, если вы хотите попробовать.

Мой код водораздела прост, я использую ndimage вспомогательного scipy
import cv2
import numpy as np
from skimage.feature import peak_local_max
from skimage.segmentation import watershed
from scipy import ndimage
gray_for_mask = cv2.cvtColor(working, cv2.COLOR_BGR2GRAY)
mask_glare = cv2.threshold(gray_for_mask, 200, 255, cv2.THRESH_BINARY)[1]
if np.count_nonzero(mask_glare) > 0:
inpaint_mask = cv2.dilate(mask_glare, np.ones((3,3), np.uint8), iterations=1)
working = cv2.inpaint(working, inpaint_mask, inpaintRadius=3, flags=cv2.INPAINT_TELEA)
hsv = cv2.cvtColor(working, cv2.COLOR_BGR2HSV)
lower_gold = np.array([10, 40, 100]) # H,S,V
upper_gold = np.array([45, 255, 255])
mask_color = cv2.inRange(hsv, lower_gold, upper_gold)
gray = cv2.cvtColor(working, cv2.COLOR_BGR2GRAY)
gray_blur = cv2.medianBlur(gray, 5)
adaptive_thresh = cv2.adaptiveThreshold(gray_blur, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV , 31 , 3)
close_kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3))
adaptive_thresh = cv2.morphologyEx(adaptive_thresh, cv2.MORPH_CLOSE, close_kernel, iterations=1)
combined = cv2.bitwise_or(mask_color, adaptive_thresh)
k_open = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5,5))
k_close = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3,3))
mask = cv2.morphologyEx(combined, cv2.MORPH_CLOSE, k_close, iterations=1)
mask = remove_small_components(mask, min_area=150)
k_close = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (2,2))
mask = cv2.morphologyEx(mask, cv2.MORPH_DILATE, k_close, iterations=1)
contours, hierarchy = cv2.findContours(
mask, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE
)
mask_filled = mask.copy()
for i, cnt in enumerate(contours):
if hierarchy[0][3] == -1:
cv2.drawContours(mask_filled, [cnt], 0, 255, thickness=cv2.FILLED)
mask_filled = cv2.erode(mask_filled, kernel=np.ones((2,2), np.uint8), iterations=1)
dist = ndimage.distance_transform_edt(mask_filled.copy())
peaks = peak_local_max(dist, min_distance=40,
labels=mask_filled.copy())
dist_visual = cv2.normalize(dist, None, 0, 255, cv2.NORM_MINMAX).astype(np.uint8)
peak_map = cv2.cvtColor(dist_visual.copy() * 255, cv2.COLOR_GRAY2BGR)
for (py, px) in peaks:
cv2.circle(peak_map, (px, py), 3, (0, 0, 255), -1)
local_max = np.zeros_like(dist, dtype=bool)
local_max[tuple(peaks.T)] = True
markers = ndimage.label(local_max)[0]
labels = watershed(-dist, markers, mask=mask_filled.copy())
watershed_vis = np.zeros((mask_filled.copy().shape[0], mask_filled.copy().shape[1], 3), dtype=np.uint8)
for label in np.unique(labels):
if label == 0:
continue
color = np.random.randint(15, 255, size=(3,), dtype=np.uint8)
watershed_vis[labels == label] = color
Подробнее здесь: https://stackoverflow.com/questions/798 ... ed-objects
Мобильная версия