972 KiB
Лабораторная работа 9: Обработка изображений и анализ данных МРТ мозга¶
В этой лабораторной работе мы будем работать с датасетом МРТ изображений мозга для классификации опухолей. Используем Python и библиотеки для обработки изображений.
1. Подготовка среды и загрузка данных¶
# Импорт необходимых библиотек
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import cv2
import os
import mahotas
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report
from sklearn.ensemble import RandomForestClassifier
from sklearn.svm import SVC
from sklearn.cluster import KMeans
from skimage import filters, exposure, feature
from tensorflow.keras.preprocessing.image import ImageDataGenerator
2. Загрузка и исследование датасета¶
import kagglehub
# Download latest version
data_dir = kagglehub.dataset_download("orvile/brain-cancer-mri-dataset")
print("Path to dataset files:", data_dir)
data_dir = os.path.join(data_dir, "Brain_Cancer raw MRI data", "Brain_Cancer")
# Пути к данным
classes = ['brain_glioma', 'brain_menin', 'brain_tumor']
# Загрузка изображений
images = []
labels = []
for class_name in classes:
class_dir = os.path.join(data_dir, class_name)
for img_name in os.listdir(class_dir)[:100]: # Берем по 100 изображений из каждого класса для примера
img_path = os.path.join(class_dir, img_name)
img = cv2.imread(img_path)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # Конвертируем в RGB
img = cv2.resize(img, (128, 128)) # Уменьшаем размер для ускорения обработки
images.append(img)
labels.append(class_name)
# Преобразуем в numpy массивы
images = np.array(images)
labels = np.array(labels)
# Вывод информации о датасете
print(f"Всего изображений: {len(images)}")
print(f"Размерность изображений: {images[0].shape}")
print(f"Классы: {np.unique(labels)}")
print(f"Количество изображений по классам:")
for class_name in classes:
print(f"{class_name}: {np.sum(labels == class_name)}")
# Функция для отображения изображений
def plot_images(images, titles, cmap=None):
plt.figure(figsize=(15, 7))
for i in range(len(images)):
plt.subplot(1, len(images), i+1)
plt.imshow(images[i], cmap=cmap)
plt.title(titles[i])
plt.axis('off')
plt.show()
# Примеры изображений из каждого класса
for class_name in classes:
idx = np.where(labels == class_name)[0][0]
plot_images([images[idx]], [f"{class_name} - исходное"], cmap='gray')
3.2. Применение методов фильтрации¶
# Пример обработки одного изображения
sample_img = images[0]
# Гауссово размытие
gaussian_blur = cv2.GaussianBlur(sample_img, (5, 5), 0)
# Медианный фильтр
median_blur = cv2.medianBlur(sample_img, 5)
# Фильтр Собеля для выделения границ
sobel_x = cv2.Sobel(sample_img, cv2.CV_64F, 1, 0, ksize=5)
sobel_y = cv2.Sobel(sample_img, cv2.CV_64F, 0, 1, ksize=5)
sobel = np.sqrt(sobel_x**2 + sobel_y**2)
sobel = np.uint8(sobel / sobel.max() * 255)
# Фильтр Лапласа для повышения резкости
laplacian = cv2.Laplacian(sample_img, cv2.CV_64F)
# Отображение результатов
plot_images([sample_img, gaussian_blur, median_blur, sobel, laplacian],
['Исходное', 'Гауссово размытие', 'Медианный фильтр', 'Собель', 'Лапласиан'])
3.3. Преобразование в оттенки серого и выравнивание гистограммы¶
# Преобразование в оттенки серого
gray_img = cv2.cvtColor(sample_img, cv2.COLOR_RGB2GRAY)
# Выравнивание гистограммы
equalized_img = cv2.equalizeHist(gray_img)
# Адаптивное выравнивание гистограммы
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
clahe_img = clahe.apply(gray_img)
# Отображение результатов
plot_images([gray_img, equalized_img, clahe_img],
['Оттенки серого', 'Выравненная гистограмма', 'Адаптивное выравнивание'],
cmap='gray')
# Извлечение признаков Haralick
def extract_haralick_features(img):
gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
features = mahotas.features.haralick(gray).mean(axis=0)
return features
# Пример извлечения признаков
haralick_features = extract_haralick_features(sample_img)
print(f"Haralick features: {haralick_features}")
4.2. Гистограмма ориентированных градиентов (HOG)¶
# Извлечение признаков HOG
def extract_hog_features(img):
gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
hog_features = feature.hog(gray, orientations=8, pixels_per_cell=(16, 16),
cells_per_block=(1, 1), visualize=False)
return hog_features
# Пример извлечения признаков
hog_features = extract_hog_features(sample_img)
print(f"HOG features length: {len(hog_features)}")
4.3. Цветовые гистограммы¶
# Извлечение цветовых гистограмм
def extract_color_histogram(img, bins=(8, 8, 8)):
hsv = cv2.cvtColor(img, cv2.COLOR_RGB2HSV)
hist = cv2.calcHist([hsv], [0, 1, 2], None, bins, [0, 180, 0, 256, 0, 256])
cv2.normalize(hist, hist)
return hist.flatten()
# Пример извлечения признаков
color_hist = extract_color_histogram(sample_img)
print(f"Color histogram length: {len(color_hist)}")
# Извлечение признаков для всех изображений
X = []
for img in images:
haralick = extract_haralick_features(img)
hog = extract_hog_features(img)
color_hist = extract_color_histogram(img)
combined_features = np.hstack([haralick, hog, color_hist])
X.append(combined_features)
X = np.array(X)
# Кодирование меток
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
y = le.fit_transform(labels)
# Разделение на обучающую и тестовую выборки
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
5.2. Обучение Random Forest¶
# Обучение модели Random Forest
rf = RandomForestClassifier(n_estimators=100, random_state=42)
rf.fit(X_train, y_train)
# Оценка качества
y_pred = rf.predict(X_test)
print(classification_report(y_test, y_pred, target_names=classes))
5.3. Обучение SVM¶
# Обучение модели SVM
svm = SVC(kernel='rbf', C=10, gamma='scale', random_state=42)
svm.fit(X_train, y_train)
# Оценка качества
y_pred = svm.predict(X_test)
print(classification_report(y_test, y_pred, target_names=classes))
6. Аугментация данных¶
# Создание генератора аугментации
datagen = ImageDataGenerator(
rotation_range=20,
width_shift_range=0.1,
height_shift_range=0.1,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True,
fill_mode='nearest')
# Пример аугментации
plt.figure(figsize=(10, 5))
for i in range(10):
augmented = datagen.random_transform(images[0])
plt.subplot(2, 5, i+1)
plt.imshow(augmented)
plt.axis('off')
plt.suptitle('Примеры аугментации изображения')
plt.show()
7. Кластеризация с помощью K-means¶
# Кластеризация с использованием K-means
kmeans = KMeans(n_clusters=3, random_state=42)
cluster_labels = kmeans.fit_predict(X)
# Визуализация кластеров
plt.figure(figsize=(10, 6))
for i in range(4):
cluster_samples = np.where(cluster_labels == i)[0][:5]
for j, idx in enumerate(cluster_samples):
plt.subplot(4, 5, i*5 + j + 1)
plt.imshow(images[idx])
plt.title(f"Cluster {i}")
plt.axis('off')
plt.tight_layout()
plt.show()
Подсчет качества модели¶
Accuracy - общая точность классификации
Precision - точность (сколько из предсказанных положительных действительно положительные)
Recall - полнота (сколько реальных положительных нашли)
F1-score - гармоническое среднее precision и recall
Confusion Matrix - наглядно показывает ошибки между классами
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, confusion_matrix
# Для Random Forest (аналогично для SVM)
y_pred = rf.predict(X_test)
# Расчет основных метрик
accuracy = accuracy_score(y_test, y_pred)
precision = precision_score(y_test, y_pred, average='weighted')
recall = recall_score(y_test, y_pred, average='weighted')
f1 = f1_score(y_test, y_pred, average='weighted')
print(f"Accuracy: {accuracy:.4f}")
print(f"Precision: {precision:.4f}")
print(f"Recall: {recall:.4f}")
print(f"F1-score: {f1:.4f}")
# Матрица ошибок
conf_matrix = confusion_matrix(y_test, y_pred)
print("Confusion Matrix:")
print(conf_matrix)
# Визуализация матрицы ошибок
import seaborn as sns
plt.figure(figsize=(8, 6))
sns.heatmap(conf_matrix, annot=True, fmt='d', cmap='Blues',
xticklabels=classes, yticklabels=classes)
plt.xlabel('Predicted')
plt.ylabel('Actual')
plt.title('Confusion Matrix')
plt.show()
from sklearn.metrics import classification_report
print("\nDetailed Classification Report:")
print(classification_report(y_test, y_pred, target_names=classes))
Кросс-валидация для более надежной оценки
from sklearn.model_selection import cross_val_score
# Для RandomForest
scores = cross_val_score(rf, X, y, cv=5, scoring='accuracy')
print(f"Cross-Validation Accuracy: {scores.mean():.4f} (+/- {scores.std():.4f})")
Выводы по лабораторной работе¶
В ходе выполнения лабораторной работы была проведена обработка и классификация изображений МРТ мозга с использованием методов машинного обучения. На основе полученных метрик можно сделать следующие выводы:
1. Качество моделей¶
Общая точность (Accuracy):
- На тестовой выборке модель показала 68,3% правильных предсказаний.
- При кросс-валидации средняя точность составила 73,0% (±6,4%), что говорит о более устойчивой работе модели при разных разбиениях данных.
Precision (Точность):
- Средняя точность по классам 78,6%, что означает, что из всех предсказанных положительных случаев большинство действительно верные.
- Наивысшая точность у класса brain_tumor (93%), что говорит о хорошей различимости этого типа опухоли.
Recall (Полнота):
- Средний recall = 68,3%, что означает, что модель находит около 2/3 реальных случаев каждого класса.
- Класс brain_menin имеет recall = 88%, но низкую точность (47%), что говорит о большом количестве ложных срабатываний.
F1-score (Гармоническое среднее):
- Средний F1 = 69,7%, что подтверждает баланс между точностью и полнотой модели.
2. Анализ ошибок (Confusion Matrix)¶
- Класс brain_glioma:
- 14 верных предсказаний, но 8 ошибок (путает с brain_menin).
- Класс brain_menin:
- 14 верных, но 1 ошибка в brain_glioma и 1 в brain_tumor.
- Класс brain_tumor:
- 13 верных, но 8 ошибок (путает с brain_menin).
Основная проблема: модель чаще всего путает glioma и meningioma, что может быть связано с их визуальной схожестью на МРТ.
3. Итог¶
Модель показала умеренное качество (68-73% accuracy), но требует доработки, особенно в части различения классов glioma и meningioma. Для медицинской диагностики желательно достичь точности >85%, поэтому рекомендуется:
- Увеличить датасет.
- Использовать более сложные архитектуры (например, Transfer Learning).
- Применить ансамбли моделей.