Примечание
Перейти к концу для скачивания полного примера кода. или для запуска этого примера в браузере через JupyterLite или Binder
Спектральное кластерирование для сегментации изображения
В этом примере генерируется изображение с соединенными кругами, и используется спектральное кластерирование для разделения кругов.
В этих настройках подход спектрального кластерирования решает проблему, известную как «нормализованные графовые разрезы»: изображение рассматривается как граф соединенных вокселей, и алгоритм спектрального кластерирования сводится к выбору разрезов графа, определяющих области, минимизируя отношение градиента вдоль разреза к объему области.
Поскольку алгоритм пытается сбалансировать объемы (то есть сбалансировать размеры областей), если мы возьмем круги разных размеров, сегментация не удается.
Кроме того, так как в интенсивности изображения или его градиенте нет полезной информации, мы выбираем выполнить спектральное кластерирование на графе, который слабо информирован градиентом. Это близко к выполнению разбиения Вороного графа.
Кроме того, мы используем маску объектов, чтобы ограничить граф контуром объектов. В этом примере нас интересует разделение объектов друг от друга, а не от фона.
# Authors: The scikit-learn developers # SPDX-License-Identifier: BSD-3-Clause
Генерация данных
import numpy as np l = 100 x, y = np.indices((l, l)) center1 = (28, 24) center2 = (40, 50) center3 = (67, 58) center4 = (24, 70) radius1, radius2, radius3, radius4 = 16, 14, 15, 14 circle1 = (x - center1[0]) ** 2 + (y - center1[1]) ** 2 < radius1**2 circle2 = (x - center2[0]) ** 2 + (y - center2[1]) ** 2 < radius2**2 circle3 = (x - center3[0]) ** 2 + (y - center3[1]) ** 2 < radius3**2 circle4 = (x - center4[0]) ** 2 + (y - center4[1]) ** 2 < radius4**2
Отображение четырех кругов
img = circle1 + circle2 + circle3 + circle4 # We use a mask that limits to the foreground: the problem that we are # interested in here is not separating the objects from the background, # but separating them one from the other. mask = img.astype(bool) img = img.astype(float) img += 1 + 0.2 * np.random.randn(*img.shape)
Преобразуйте изображение в граф со значением градиента на ребрах.
from sklearn.feature_extraction import image graph = image.img_to_graph(img, mask=mask)
Возьмите убывающую функцию градиента, что приведет к сегментации, близкой к разбиению Вороного.
graph.data = np.exp(-graph.data / graph.data.std())
Здесь мы выполняем спектральное кластерирование с использованием решателя arpack, так как amg численно неустойчив в этом примере. Затем мы отображаем результаты.
import matplotlib.pyplot as plt from sklearn.cluster import spectral_clustering labels = spectral_clustering(graph, n_clusters=4, eigen_solver="arpack") label_im = np.full(mask.shape, -1.0) label_im[mask] = labels fig, axs = plt.subplots(nrows=1, ncols=2, figsize=(10, 5)) axs[0].matshow(img) axs[1].matshow(label_im) plt.show()

Отображение двух кругов
Здесь мы повторяем вышеуказанный процесс, но рассматриваем только первые два сгенерированных круга. Обратите внимание, что это приводит к более чистому разделению между кругами, поскольку в этом случае размеры области легче сбалансировать.
img = circle1 + circle2 mask = img.astype(bool) img = img.astype(float) img += 1 + 0.2 * np.random.randn(*img.shape) graph = image.img_to_graph(img, mask=mask) graph.data = np.exp(-graph.data / graph.data.std()) labels = spectral_clustering(graph, n_clusters=2, eigen_solver="arpack") label_im = np.full(mask.shape, -1.0) label_im[mask] = labels fig, axs = plt.subplots(nrows=1, ncols=2, figsize=(10, 5)) axs[0].matshow(img) axs[1].matshow(label_im) plt.show()

Общее время выполнения скрипта: (0 минут 0,498 секунды)
Связанные примеры
© 2007–2025 The scikit-learn developers
Licensed under the 3-clause BSD License.
https://scikit-learn.org/1.6/auto_examples/cluster/plot_segmentation_toy.html