{ "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 }