Еще одна вещь, которую вы могли бы сделать, если вы хотите, чтобы заливка контура была как можно ближе к контрастным элементам вашего изображения, - это выполнить квантование цветов Kmeans для сегментирования изображения на определенное количество кластеров. Поскольку небо и горы / деревья имеют видимую разницу в цвете, мы могли бы разделить изображение только на три цвета, которые лучше разделят объекты.
Например, с clusters=3
:
Входное изображение ->
Цветовая сегментация Kmeans
Результат заливки зеленым цветом
Обратите внимание, что после сегментирования только три цвета определяют изображение. Таким образом, пойма будет лучше очерчиваться вдоль гор / деревьев
Код
import cv2
import numpy as np
# Kmeans color segmentation
def kmeans_color_quantization(image, clusters=8, rounds=1):
h, w = image.shape[:2]
samples = np.zeros([h*w,3], dtype=np.float32)
count = 0
for x in range(h):
for y in range(w):
samples[count] = image[x][y]
count += 1
compactness, labels, centers = cv2.kmeans(samples,
clusters,
None,
(cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 10000, 0.0001),
rounds,
cv2.KMEANS_RANDOM_CENTERS)
centers = np.uint8(centers)
res = centers[labels.flatten()]
return res.reshape((image.shape))
# Load image and perform kmeans
image = cv2.imread('1.jpg')
kmeans = kmeans_color_quantization(image, clusters=3)
result = kmeans.copy()
# Floodfill
seed_point = (150, 50)
cv2.floodFill(result, None, seedPoint=seed_point, newVal=(36, 255, 12), loDiff=(0, 0, 0, 0), upDiff=(0, 0, 0, 0))
cv2.imshow('image', image)
cv2.imshow('kmeans', kmeans)
cv2.imshow('result', result)
cv2.waitKey()