Добавлены итоговые блокноты, внешнее изображение
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