Добавлены итоговые блокноты, внешнее изображение
This commit is contained in:
parent
a7003303f8
commit
a7a54edebc
16
.ipynb_checkpoints/README-checkpoint.md
Normal file
16
.ipynb_checkpoints/README-checkpoint.md
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
Описание задачи
|
||||||
|
Цель: сегментировать изображение на несколько однородных регионов с использованием спектральной кластеризации .
|
||||||
|
|
||||||
|
Алгоритм:
|
||||||
|
|
||||||
|
Изображение преобразуется в граф
|
||||||
|
Применяется спектральная кластеризация
|
||||||
|
Результат отображается в виде контуров вокруг найденных регионов
|
||||||
|
Поддерживаемые методы присвоения меток:
|
||||||
|
|
||||||
|
'kmeans'
|
||||||
|
'discretize'
|
||||||
|
'cluster_qr'
|
||||||
|
|
||||||
|
Для установки зависимостей:
|
||||||
|
pip install -r requirements.txt
|
179
.ipynb_checkpoints/plot_coin_segmentation-checkpoint.ipynb
Normal file
179
.ipynb_checkpoints/plot_coin_segmentation-checkpoint.ipynb
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
{
|
||||||
|
"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
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"cells": [],
|
||||||
|
"metadata": {},
|
||||||
|
"nbformat": 4,
|
||||||
|
"nbformat_minor": 5
|
||||||
|
}
|
17
README.md
17
README.md
@ -1 +1,16 @@
|
|||||||
https://www.kaggle.com/datasets/sachinpatel21/az-handwritten-alphabets-in-csv-format/data
|
##Описание задачи
|
||||||
|
Цель: сегментировать изображение на несколько однородных регионов с использованием спектральной кластеризации .
|
||||||
|
|
||||||
|
#Алгоритм:
|
||||||
|
|
||||||
|
Изображение преобразуется в граф
|
||||||
|
Применяется спектральная кластеризация
|
||||||
|
Результат отображается в виде контуров вокруг найденных регионов
|
||||||
|
Поддерживаемые методы присвоения меток:
|
||||||
|
|
||||||
|
'kmeans'
|
||||||
|
'discretize'
|
||||||
|
'cluster_qr'
|
||||||
|
|
||||||
|
Для установки зависимостей:
|
||||||
|
pip install -r requirements.txt
|
84
app.py
84
app.py
@ -1,84 +0,0 @@
|
|||||||
import pandas as pd
|
|
||||||
import numpy as np
|
|
||||||
import matplotlib.pyplot as plt
|
|
||||||
from sklearn.model_selection import train_test_split
|
|
||||||
from sklearn.svm import SVC
|
|
||||||
from sklearn.metrics import classification_report, ConfusionMatrixDisplay
|
|
||||||
|
|
||||||
# -----------------------------
|
|
||||||
# 1. Загрузка данных
|
|
||||||
# -----------------------------
|
|
||||||
# Попробуем определить, есть ли заголовки
|
|
||||||
try:
|
|
||||||
df = pd.read_csv('A_Z_HandwrittenLetters.csv')
|
|
||||||
if 'label' in df.columns:
|
|
||||||
print("Заголовки найдены, используется столбец 'label'")
|
|
||||||
else:
|
|
||||||
raise Exception("Столбец 'label' не найден")
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Ошибка: {e}, попытка чтения без заголовков")
|
|
||||||
df = pd.read_csv('A_Z_HandwrittenLetters.csv', header=None)
|
|
||||||
|
|
||||||
# Разделение на признаки и метки
|
|
||||||
if 'label' in df.columns:
|
|
||||||
y = df['label'].values
|
|
||||||
X = df.drop('label', axis=1).values
|
|
||||||
else:
|
|
||||||
y = df[0].values
|
|
||||||
X = df.drop(0, axis=1).values
|
|
||||||
|
|
||||||
# -----------------------------
|
|
||||||
# 2. Нормализация
|
|
||||||
# -----------------------------
|
|
||||||
X = X / 255.0
|
|
||||||
|
|
||||||
# -----------------------------
|
|
||||||
# 3. Визуализация первых изображений
|
|
||||||
# -----------------------------
|
|
||||||
_, axes = plt.subplots(1, 4, figsize=(10, 5))
|
|
||||||
for ax, image, label in zip(axes, X[:4], y[:4]):
|
|
||||||
ax.imshow(image.reshape(28, 28), cmap='gray')
|
|
||||||
ax.axis('off')
|
|
||||||
ax.set_title(f"Label: {label}\n({chr(label + ord('A'))})")
|
|
||||||
plt.suptitle("Sample Training Images")
|
|
||||||
plt.show()
|
|
||||||
|
|
||||||
# -----------------------------
|
|
||||||
# 4. Разделение выборки
|
|
||||||
# -----------------------------
|
|
||||||
X_train, X_test, y_train, y_test = train_test_split(
|
|
||||||
X, y, test_size=0.3, random_state=42, shuffle=True
|
|
||||||
)
|
|
||||||
|
|
||||||
# -----------------------------
|
|
||||||
# 5. Обучение модели
|
|
||||||
# -----------------------------
|
|
||||||
print("Обучение модели...")
|
|
||||||
clf = SVC(gamma=0.001)
|
|
||||||
clf.fit(X_train, y_train)
|
|
||||||
|
|
||||||
# -----------------------------
|
|
||||||
# 6. Предсказание
|
|
||||||
# -----------------------------
|
|
||||||
y_pred = clf.predict(X_test)
|
|
||||||
|
|
||||||
# -----------------------------
|
|
||||||
# 7. Визуализация предсказаний
|
|
||||||
# -----------------------------
|
|
||||||
_, axes = plt.subplots(1, 4, figsize=(10, 5))
|
|
||||||
for ax, image, prediction in zip(axes, X_test, y_pred):
|
|
||||||
ax.imshow(image.reshape(28, 28), cmap='gray')
|
|
||||||
ax.axis('off')
|
|
||||||
ax.set_title(f"Prediction: {prediction}\n({chr(prediction + ord('A'))})")
|
|
||||||
plt.suptitle("Predicted Letters")
|
|
||||||
plt.show()
|
|
||||||
|
|
||||||
# -----------------------------
|
|
||||||
# 8. Отчеты и матрица ошибок
|
|
||||||
# -----------------------------
|
|
||||||
print("\nClassification Report:")
|
|
||||||
print(classification_report(y_test, y_pred))
|
|
||||||
|
|
||||||
disp = ConfusionMatrixDisplay.from_predictions(y_test, y_pred)
|
|
||||||
disp.figure_.suptitle("Confusion Matrix")
|
|
||||||
plt.show()
|
|
237
plot_coin_segmentation.ipynb
Normal file
237
plot_coin_segmentation.ipynb
Normal file
File diff suppressed because one or more lines are too long
280
plot_coin_segmentation_upd.ipynb
Normal file
280
plot_coin_segmentation_upd.ipynb
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1,128 +0,0 @@
|
|||||||
"""
|
|
||||||
================================
|
|
||||||
Recognizing hand-written digits
|
|
||||||
================================
|
|
||||||
|
|
||||||
This example shows how scikit-learn can be used to recognize images of
|
|
||||||
hand-written digits, from 0-9.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Authors: The scikit-learn developers
|
|
||||||
# SPDX-License-Identifier: BSD-3-Clause
|
|
||||||
|
|
||||||
# Standard scientific Python imports
|
|
||||||
import matplotlib.pyplot as plt
|
|
||||||
|
|
||||||
# Import datasets, classifiers and performance metrics
|
|
||||||
from sklearn import datasets, metrics, svm
|
|
||||||
from sklearn.model_selection import train_test_split
|
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
# Digits dataset
|
|
||||||
# --------------
|
|
||||||
#
|
|
||||||
# The digits dataset consists of 8x8
|
|
||||||
# pixel images of digits. The ``images`` attribute of the dataset stores
|
|
||||||
# 8x8 arrays of grayscale values for each image. We will use these arrays to
|
|
||||||
# visualize the first 4 images. The ``target`` attribute of the dataset stores
|
|
||||||
# the digit each image represents and this is included in the title of the 4
|
|
||||||
# plots below.
|
|
||||||
#
|
|
||||||
# Note: if we were working from image files (e.g., 'png' files), we would load
|
|
||||||
# them using :func:`matplotlib.pyplot.imread`.
|
|
||||||
|
|
||||||
digits = datasets.load_digits()
|
|
||||||
|
|
||||||
_, axes = plt.subplots(nrows=1, ncols=4, figsize=(10, 3))
|
|
||||||
for ax, image, label in zip(axes, digits.images, digits.target):
|
|
||||||
ax.set_axis_off()
|
|
||||||
ax.imshow(image, cmap=plt.cm.gray_r, interpolation="nearest")
|
|
||||||
ax.set_title("Training: %i" % label)
|
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
# Classification
|
|
||||||
# --------------
|
|
||||||
#
|
|
||||||
# To apply a classifier on this data, we need to flatten the images, turning
|
|
||||||
# each 2-D array of grayscale values from shape ``(8, 8)`` into shape
|
|
||||||
# ``(64,)``. Subsequently, the entire dataset will be of shape
|
|
||||||
# ``(n_samples, n_features)``, where ``n_samples`` is the number of images and
|
|
||||||
# ``n_features`` is the total number of pixels in each image.
|
|
||||||
#
|
|
||||||
# We can then split the data into train and test subsets and fit a support
|
|
||||||
# vector classifier on the train samples. The fitted classifier can
|
|
||||||
# subsequently be used to predict the value of the digit for the samples
|
|
||||||
# in the test subset.
|
|
||||||
|
|
||||||
# flatten the images
|
|
||||||
n_samples = len(digits.images)
|
|
||||||
data = digits.images.reshape((n_samples, -1))
|
|
||||||
|
|
||||||
# Create a classifier: a support vector classifier
|
|
||||||
clf = svm.SVC(gamma=0.001)
|
|
||||||
|
|
||||||
# Split data into 50% train and 50% test subsets
|
|
||||||
X_train, X_test, y_train, y_test = train_test_split(
|
|
||||||
data, digits.target, test_size=0.5, shuffle=False
|
|
||||||
)
|
|
||||||
|
|
||||||
# Learn the digits on the train subset
|
|
||||||
clf.fit(X_train, y_train)
|
|
||||||
|
|
||||||
# Predict the value of the digit on the test subset
|
|
||||||
predicted = clf.predict(X_test)
|
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
# Below we visualize the first 4 test samples and show their predicted
|
|
||||||
# digit value in the title.
|
|
||||||
|
|
||||||
_, axes = plt.subplots(nrows=1, ncols=4, figsize=(10, 3))
|
|
||||||
for ax, image, prediction in zip(axes, X_test, predicted):
|
|
||||||
ax.set_axis_off()
|
|
||||||
image = image.reshape(8, 8)
|
|
||||||
ax.imshow(image, cmap=plt.cm.gray_r, interpolation="nearest")
|
|
||||||
ax.set_title(f"Prediction: {prediction}")
|
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
# :func:`~sklearn.metrics.classification_report` builds a text report showing
|
|
||||||
# the main classification metrics.
|
|
||||||
|
|
||||||
print(
|
|
||||||
f"Classification report for classifier {clf}:\n"
|
|
||||||
f"{metrics.classification_report(y_test, predicted)}\n"
|
|
||||||
)
|
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
# We can also plot a :ref:`confusion matrix <confusion_matrix>` of the
|
|
||||||
# true digit values and the predicted digit values.
|
|
||||||
|
|
||||||
disp = metrics.ConfusionMatrixDisplay.from_predictions(y_test, predicted)
|
|
||||||
disp.figure_.suptitle("Confusion Matrix")
|
|
||||||
print(f"Confusion matrix:\n{disp.confusion_matrix}")
|
|
||||||
|
|
||||||
plt.show()
|
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
# If the results from evaluating a classifier are stored in the form of a
|
|
||||||
# :ref:`confusion matrix <confusion_matrix>` and not in terms of `y_true` and
|
|
||||||
# `y_pred`, one can still build a :func:`~sklearn.metrics.classification_report`
|
|
||||||
# as follows:
|
|
||||||
|
|
||||||
|
|
||||||
# The ground truth and predicted lists
|
|
||||||
y_true = []
|
|
||||||
y_pred = []
|
|
||||||
cm = disp.confusion_matrix
|
|
||||||
|
|
||||||
# For each cell in the confusion matrix, add the corresponding ground truths
|
|
||||||
# and predictions to the lists
|
|
||||||
for gt in range(len(cm)):
|
|
||||||
for pred in range(len(cm)):
|
|
||||||
y_true += [gt] * cm[gt][pred]
|
|
||||||
y_pred += [pred] * cm[gt][pred]
|
|
||||||
|
|
||||||
print(
|
|
||||||
"Classification report rebuilt from confusion matrix:\n"
|
|
||||||
f"{metrics.classification_report(y_true, y_pred)}\n"
|
|
||||||
)
|
|
Loading…
Reference in New Issue
Block a user