180 lines
5.8 KiB
Plaintext
180 lines
5.8 KiB
Plaintext
{
|
||
"cells": [
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"Сегментация изображения методом спектральной кластеризации\n",
|
||
"Описание задачи\n",
|
||
"Цель: разделить изображение монет на несколько регионов, используя спектральную кластеризацию .\n",
|
||
"\n",
|
||
"Алгоритм:\n",
|
||
"\n",
|
||
"Изображение преобразуется в граф\n",
|
||
"Каждый пиксель — вершина графа\n",
|
||
"Рёбра между соседними пикселями строятся на основе разницы яркости\n",
|
||
"Применяется спектральная кластеризация для выделения регионов\n",
|
||
"Источник данных:\n",
|
||
"\n",
|
||
"Встроенное изображение coins() из библиотеки skimage"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"1. Импорт библиотек"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"import time\n",
|
||
"import numpy as np\n",
|
||
"import matplotlib.pyplot as plt\n",
|
||
"from scipy.ndimage import gaussian_filter\n",
|
||
"from skimage.data import coins\n",
|
||
"from skimage.transform import rescale\n",
|
||
"\n",
|
||
"from sklearn.cluster import spectral_clustering\n",
|
||
"from sklearn.feature_extraction import image"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"2. Загрузка и подготовка изображения"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Загружаем изображение монет\n",
|
||
"orig_coins = coins()\n",
|
||
"\n",
|
||
"# Уменьшаем размер изображения для ускорения обработки\n",
|
||
"# Перед уменьшением применяем фильтр Гаусса, чтобы уменьшить артефакты\n",
|
||
"smoothened_coins = gaussian_filter(orig_coins, sigma=2)\n",
|
||
"rescaled_coins = rescale(smoothened_coins, 0.2, mode=\"reflect\", anti_aliasing=False)\n",
|
||
"\n",
|
||
"print(\"Форма исходного изображения:\", orig_coins.shape)\n",
|
||
"print(\"Форма после масштабирования:\", rescaled_coins.shape)"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"3. Построение графа"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Преобразуем изображение в граф\n",
|
||
"graph = image.img_to_graph(rescaled_coins)\n",
|
||
"\n",
|
||
"# Уменьшаем веса рёбер экспоненциальной функцией\n",
|
||
"beta = 10\n",
|
||
"eps = 1e-6\n",
|
||
"graph.data = np.exp(-beta * graph.data / graph.data.std()) + eps\n",
|
||
"\n",
|
||
"print(\"Граф построен\")"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"4. Спектральная кластеризация"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "code",
|
||
"execution_count": null,
|
||
"metadata": {},
|
||
"outputs": [],
|
||
"source": [
|
||
"# Количество регионов\n",
|
||
"n_regions = 26\n",
|
||
"n_plus = 3 # дополнительные кластеры для лучшей сегментации\n",
|
||
"\n",
|
||
"# Выполняем кластеризацию тремя способами\n",
|
||
"for assign_labels in (\"kmeans\", \"discretize\", \"cluster_qr\"):\n",
|
||
" t0 = time.time()\n",
|
||
" \n",
|
||
" labels = spectral_clustering(\n",
|
||
" graph,\n",
|
||
" n_clusters=(n_regions + n_plus),\n",
|
||
" eigen_tol=1e-7,\n",
|
||
" assign_labels=assign_labels,\n",
|
||
" random_state=42,\n",
|
||
" )\n",
|
||
"\n",
|
||
" t1 = time.time()\n",
|
||
" labels = labels.reshape(rescaled_coins.shape)\n",
|
||
"\n",
|
||
" plt.figure(figsize=(5, 5))\n",
|
||
" plt.imshow(rescaled_coins, cmap=plt.cm.gray)\n",
|
||
" plt.xticks(())\n",
|
||
" plt.yticks(())\n",
|
||
"\n",
|
||
" title = f\"Спектральная кластеризация: {assign_labels}, {t1 - t0:.2f}с\"\n",
|
||
" print(title)\n",
|
||
" plt.title(title)\n",
|
||
"\n",
|
||
" for l in range(n_regions):\n",
|
||
" colors = [plt.cm.nipy_spectral((l + 4) / float(n_regions + 4))]\n",
|
||
" plt.contour(labels == l, colors=colors)\n",
|
||
"\n",
|
||
"plt.show()"
|
||
]
|
||
},
|
||
{
|
||
"cell_type": "markdown",
|
||
"metadata": {},
|
||
"source": [
|
||
"5. Интерпретация результатов\n",
|
||
"Каждое изображение показывает контуры найденных регионов. Цвета используются только для наглядности и не имеют семантической нагрузки.\n",
|
||
"\n",
|
||
"Методы:\n",
|
||
"\n",
|
||
"'kmeans' — стабильный, но может быть медленным\n",
|
||
"'discretize' — итеративный метод, работает быстрее\n",
|
||
"'cluster_qr' — новый экспериментальный метод, основанный на QR-разложении"
|
||
]
|
||
}
|
||
],
|
||
"metadata": {
|
||
"kernelspec": {
|
||
"display_name": "Python 3 (ipykernel)",
|
||
"language": "python",
|
||
"name": "python3"
|
||
},
|
||
"language_info": {
|
||
"codemirror_mode": {
|
||
"name": "ipython",
|
||
"version": 3
|
||
},
|
||
"file_extension": ".py",
|
||
"mimetype": "text/x-python",
|
||
"name": "python",
|
||
"nbconvert_exporter": "python",
|
||
"pygments_lexer": "ipython3",
|
||
"version": "3.12.9"
|
||
}
|
||
},
|
||
"nbformat": 4,
|
||
"nbformat_minor": 4
|
||
}
|