# AI Medical Education & Imaging (ai-med-edu) Образовательный проект по AI-обработке медицинских изображений: детекция и сегментация анатомических структур (почки, их сегменты, опухоли, кисты, абсцессы) на основе DICOM и 3D NRRD данных с использованием архитектур YOLO. ## 🎯 Цели проекта - Конвертация медицинских 3D-данных (NRRD, DICOM) в 2D-срезы формата YOLO - Обучение моделей детекции (yolov8s, yolo26n) и сегментации (yolov8s-seg) - Автоматическая подготовка и стратифицированное разделение датасета на train/val/test - Поддержка индивидуальных схем классов для каждого препарата - Проверка доступности GPU (PyTorch + CUDA) - Образовательные материалы: лекции, семинары, лабораторные работы ## 📂 Структура репозитория ``` ai-med-edu/ │ ├── README.md # Этот файл ├── ai-use-program.doc # Учебная программа ├── references.txt # Список литературы ├── labels.cache # Кэш лейблов YOLO │ ├── data/ # Эксперименты (каждый препарат - отдельная папка) │ ├── 1_2236040_zno_cyst_AF/ # Эксперимент 1: ZNO Cyst AF │ │ ├── predefined_classes.txt # Схема классов (12 классов) │ │ ├── data.yaml # Конфиг YOLO │ │ ├── 501 arterial ax 1mm iDose (5).nrrd # Исходные 3D данные │ │ ├── Segmentation.seg.nrrd # Сегментационная маска │ │ ├── dcm/ # DICOM-срезы (1042 файла) │ │ ├── images/ # PNG-срезы (300 файлов) │ │ ├── images_labels/ # Bbox-разметка │ │ │ └── polygons/ # Полигоны для сегментации │ │ └── images_result/ # Визуализация результатов │ │ └── masks_sam/ # Маски SAM │ │ │ ├── example/ # Пример структуры │ │ ├── README.md │ │ ├── images/ │ │ ├── images_labels/ │ │ │ └── polygons/ │ │ └── images_results/ │ │ │ └── prep/ # Подготовительные данные │ ├── predefined_classes.txt │ ├── csv/ # CSV-файлы с разметкой │ ├── images/ # DCM и JPG файлы │ ├── images_labels/ # TXT-лейблы │ │ └── polygons/ │ └── images_results/ # Результаты │ └── masks_sam/ │ ├── scripts/ # Универсальные скрипты │ ├── ttv_freq2.py # Сплиттер (стратифицированный) │ ├── train_yolo.py # Обучение детекции │ ├── train_yolo_seg.py # Обучение сегментации │ ├── check_PyTorch_gpu.py # Проверка GPU │ ├── check_tf_gpu.py # Проверка TensorFlow GPU │ ├── config/ # Конфигурационные файлы │ │ └── data.yaml │ ├── Тема 2.1/ # Скрипты по теме 2.1 │ │ ├── analysis.py │ │ ├── config_3d.py │ │ ├── feature_3d.py │ │ └── segmentation.py │ └── Тема 2.2/ # Скрипты по теме 2.2 │ └── nrrd_to_yolo.py # Конвертация NRRD → YOLO │ ├── env/ # Виртуальное окружение Python │ ├── Include/ │ ├── Lib/ │ │ └── site-packages/ # Установленные пакеты │ ├── Scripts/ # Исполняемые файлы │ ├── etc/ │ ├── share/ │ └── pyvenv.cfg │ ├── lectures/ # Лекционные материалы │ ├── К26_1_1.pdf │ ├── К26_2_1.pdf │ └── К26_2_2.pdf │ ├── seminars/ # Семинарские занятия │ ├── FeatureExtractionClient.ipynb │ ├── Тема 1.1/ # Jupyter ноутбуки │ │ ├── Dataset.ipynb │ │ ├── Noise.ipynb │ │ ├── Resource1.ipynb │ │ ├── resource2.ipynb │ │ └── segm2.ipynb │ ├── Тема 1.2/ │ │ ├── Практикум1.ipynb │ │ ├── Т1.ipynb │ │ ├── Т2.ipynb │ │ └── best_spleen_model.pth # Предобученная модель │ ├── Тема 2.1/ │ │ ├── radiomics_report.html │ │ ├── segmentation_full_report.html │ │ ├── requirements_3d.txt │ │ └── Лабораторная работа.docx │ └── Тема 2.2/ │ └── labs/ # Лабораторные работы ├── Тема 1.1/ ├── Тема 1.2/ ├── Тема 2.1/ │ └── Лабораторная работа.docx └── Тема 2.2/ ``` ## 🏷️ Схема классов (predefined_classes.txt) Каждый эксперимент имеет СВОЙ СОБСТВЕННЫЙ файл `predefined_classes.txt`, расположенный в папке эксперимента. Это позволяет использовать разные наборы классов для разных препаратов. Формат: один класс на строку, позиция в файле = YOLO index (0-based). ### Пример: data/1_2236040_zno_cyst_AF/predefined_classes.txt (12 классов) ```txt right_kidney # ID 1 → YOLO idx 0 right_kidney_upper_segment # ID 2 → YOLO idx 1 right_kidney_middle_segment # ID 3 → YOLO idx 2 right_kidney_lower_segment # ID 4 → YOLO idx 3 left_kidney # ID 5 → YOLO idx 4 left_kidney_upper_segment # ID 6 → YOLO idx 5 left_kidney_middle_segment # ID 7 → YOLO idx 6 left_kidney_lower_segment # ID 8 → YOLO idx 7 malignant_tumor # ID 9 → YOLO idx 8 benign_tumor # ID 10 → YOLO idx 9 cyst # ID 11 → YOLO idx 10 abscess # ID 12 → YOLO idx 11 ``` > **Важно:** Исходные лейблы (Label Studio / CVAT) используют 1-based ID (1–N). Скрипт `ttv_freq2.py` автоматически перенумеровывает их в 0-based формат при копировании в папку `labels/`. Это необходимо, так как YOLOv8 требует, чтобы все ID в `.txt`-файлах были в диапазоне [0, nc-1] без пропусков. ## 🚀 Быстрый старт ### 1. Активация окружения **Windows:** ```bash cd D:\ai-med-edu env\Scripts\activate ``` **Linux / macOS:** ```bash cd /path/to/ai-med-edu source env/bin/activate ``` ### 2. Проверка GPU ```bash python scripts/check_PyTorch_gpu.py ``` Ожидаемый результат: ``` CUDA доступна! Количество доступных GPU: 1 GPU 0: NVIDIA GeForce RTX 3060 ``` ### 3. Установка зависимостей (при необходимости) ```bash pip install ultralytics torch torchvision pyyaml pydicom nrrd scipy pandas opencv-python ``` ## 📋 Полный пайплайн обучения ### Вариант A: Детекция (bounding boxes) ```bash # Шаг 1: Создать сплит с перенумерацией классов python scripts/ttv_freq2.py --task detect ^ --images-dir data/1_2236040_zno_cyst_AF/images ^ --labels-dir data/1_2236040_zno_cyst_AF/images_labels ^ --output-dir data/1_2236040_zno_cyst_AF # Шаг 2: Запустить обучение python scripts/train_yolo.py ^ --data data/1_2236040_zno_cyst_AF/data.yaml ^ --model yolov8s.pt ^ --epochs 100 ^ --batch 16 ^ --name kidney_det_exp1 ``` ### Вариант B: Сегментация (полигоны) ```bash # Шаг 1: Создать сплит для сегментации python scripts/ttv_freq2.py --task segment ^ --images-dir data/1_2236040_zno_cyst_AF/images ^ --labels-dir data/1_2236040_zno_cyst_AF/images_labels/polygons ^ --output-dir data/1_2236040_zno_cyst_AF # Шаг 2: Запустить обучение python scripts/train_yolo_seg.py ^ --data data/1_2236040_zno_cyst_AF/data.yaml ^ --model yolov8s-seg.pt ^ --epochs 100 ^ --batch 16 ^ --name kidney_seg_exp1 ``` ### Вариант C: Обе задачи сразу (общий сплит) ```bash python scripts/ttv_freq2.py --task both ^ --images-dir data/1_2236040_zno_cyst_AF/images ^ --labels-dir data/1_2236040_zno_cyst_AF/images_labels ^ --polygons-dir data/1_2236040_zno_cyst_AF/images_labels/polygons ^ --output-dir data/1_2236040_zno_cyst_AF ``` ## 📜 Описание скриптов ### scripts/ttv_freq2.py — Стратифицированный сплиттер **Ключевая особенность:** разбивает датасет, начиная с самых редких классов. Это гарантирует присутствие каждого класса в train/val/test наборах, что критично для медицинских данных с несбалансированными классами. **Возможности:** - Автоматический поиск `predefined_classes.txt` в папке эксперимента - Автоматическая перенумерация 1-based → 0-based для YOLOv8 - Поддержка детекции, сегментации или обеих задач одновременно - Стратифицированное разбиение по частоте классов - Автоматическая генерация `data.yaml` с абсолютными путями - Создание изолированной папки `labels/` (полное копирование) - Автоматическая очистка старых `.cache` файлов **Параметры:** | Параметр | Описание | По умолчанию | |----------|----------|--------------| | `--task` | detect / segment / both | *обязательный* | | `--images-dir` | Папка с изображениями | *обязательный* | | `--labels-dir` | Папка с bbox или полигонами | *обязательный* | | `--polygons-dir` | Папка с полигонами (both) | - | | `--output-dir` | Папка для результатов | *обязательный* | | `--predefined-classes` | Путь к файлу классов | `/predefined_classes.txt` | | `--train-ratio` | Доля обучающей выборки | 0.8 | | `--val-ratio` | Доля валидационной выборки | 0.1 | | `--seed` | Seed для воспроизводимости | 42 | ### scripts/train_yolo.py — Обучение детекции (bounding boxes) **Параметры:** | Параметр | Описание | По умолчанию | |----------|----------|--------------| | `--data` | Путь к `data.yaml` | *обязательный* | | `--model` | Предобученная модель | `yolov8s.pt` | | `--epochs` | Количество эпох | 100 | | `--batch` | Batch size | 16 | | `--imgsz` | Размер изображения | 512 | | `--device` | Устройство (0, cpu) | 0 | | `--workers` | DataLoader workers | 0 | | `--project` | Директория проектов | `runs/detect` | | `--name` | Имя эксперимента | `experiment` | ### scripts/train_yolo_seg.py — Обучение сегментации (полигоны/маски) **Параметры (аналогичны train_yolo.py, но со спецификой сегментации):** | Параметр | Описание | По умолчанию | |----------|----------|--------------| | `--data` | Путь к `data.yaml` | *обязательный* | | `--model` | Предобученная модель | `yolov8s-seg.pt` | | `--epochs` | Количество эпох | 100 | | `--batch` | Batch size | 16 | | `--imgsz` | Размер изображения | 512 | | `--device` | Устройство (0, cpu) | 0 | | `--workers` | DataLoader workers | 0 | | `--project` | Директория проектов | `runs/segment` | | `--name` | Имя эксперимента | `seg_experiment` | ### scripts/nrrd_to_yolo.py — Конвертация NRRD → YOLO (Тема 2.2) Конвертирует 3D NRRD файлы в 2D срезы формата YOLO с сохранением структуры папок. **Использование:** ```bash python scripts/Тема\ 2.2/nrrd_to_yolo.py ``` ### Скрипты темы 2.1 (scripts/Тема 2.1/) - `analysis.py` — Анализ данных и визуализация - `config_3d.py` — Конфигурация для 3D обработки - `feature_3d.py` — Извлечение признаков из 3D данных - `segmentation.py` — Сегментация 3D данных ## 📁 Структура результатов обучения После обучения YOLOv8 генерирует отчёты в: `runs/{detect|segment}/{name}/` ``` runs/segment/kidney_seg_exp1/ │ ├── weights/ │ ├── best.pt # Лучшая модель (для инференса) │ └── last.pt # Модель после последней эпохи │ ├── results.png # Графики loss и метрик по эпохам ├── confusion_matrix.png # Матрица ошибок ├── confusion_matrix_normalized.png ├── F1_curve.png # F1-score по confidence ├── PR_curve.png # Precision-Recall кривая ├── P_curve.png # Precision по confidence ├── R_curve.png # Recall по confidence ├── results.csv # Числовые метрики по эпохам └── args.yaml # Сохранённые параметры обучения ``` ## 🔮 Инференс (применение обученной модели) Пример Python-кода: ```python from ultralytics import YOLO # Загрузка обученной модели model = YOLO('runs/segment/kidney_seg_exp1/weights/best.pt') # Предсказание на новых изображениях results = model.predict( source='data/1_2236040_zno_cyst_AF/images/slice_0573.png', conf=0.25, # Порог уверенности iou=0.45, # Порог IoU для NMS save=True, # Сохранить результат project='predictions', name='inference_test' ) # Анализ результатов for r in results: print(f"Обнаружено объектов: {len(r.boxes)}") for box in r.boxes: cls_id = int(box.cls[0]) cls_name = model.names[cls_id] conf = float(box.conf[0]) print(f" - {cls_name}: {conf:.2f}") ``` ## 🆕 Создание нового эксперимента ### 1. Создание структуры вручную ```bash mkdir -p data/new_experiment/{images,images_labels/polygons,images_result} ``` Или используйте шаблон из папки `data/example/`. ### 2. Создание схемы классов ```bash notepad data\new_experiment\predefined_classes.txt ``` Запишите классы (по одному на строку): ``` organ tissue_type_1 tissue_type_2 lesion ``` ### 3. Помещение данных Скопируйте изображения в: - `data/new_experiment/images/` Скопируйте разметку в: - `data/new_experiment/images_labels/` (для детекции) - `data/new_experiment/images_labels/polygons/` (для сегментации) ### 4. Запуск обучения ```bash python scripts/ttv_freq2.py --task segment ^ --images-dir data/new_experiment/images ^ --labels-dir data/new_experiment/images_labels/polygons ^ --output-dir data/new_experiment python scripts/train_yolo_seg.py ^ --data data/new_experiment/data.yaml ^ --epochs 100 ^ --name new_experiment_seg ``` ## ⚠️ Особенности Windows 1. **Многопоточность DataLoader:** Используйте `--workers 0` при ошибках доступа к файлам. На Linux/macOS можно ставить `--workers 8` для ускорения. 2. **Пути:** В `data.yaml` и `.txt`-файлах используются абсолютные пути с прямыми слэшами (`/`) для совместимости с YOLOv8. 3. **Кодировка:** Все файлы обрабатываются в UTF-8, кириллица в именах классов поддерживается. 4. **Пути с пробелами:** Имена файлов с пробелами могут вызывать проблемы. Рекомендуется переименовывать файлы, убирая пробелы. ## 📚 Образовательные материалы ### Лекции (`lectures/`) - `К26_1_1.pdf` — Введение в обработку медицинских изображений - `К26_2_1.pdf` — Архитектуры нейронных сетей для медицинской визуализации - `К26_2_2.pdf` — Применение YOLO в медицинской диагностике ### Семинары (`seminars/`) - `Тема 1.1/` — Работа с датасетами, шумоподавление, сегментация - `Тема 1.2/` — Практикум по обучению моделей - `Тема 2.1/` — Радиомика и 3D-сегментация - `Тема 2.2/` — Конвертация NRRD в YOLO формат ### Лабораторные работы (`labs/`) - Пошаговые инструкции по темам курса - Включают теоретический материал и практические задания ## 🛠️ Известные проблемы и решения **Проблема:** "Label class X exceeds dataset class count N" **Решение:** Скрипт `ttv_freq2.py` автоматически перенумеровывает классы из 1-based (Label Studio) в 0-based (YOLOv8). **Проблема:** "Image Not Found" ошибки **Решение:** Использовать `--workers 0`, проверить наличие изображений, пересоздать сплит. Убедиться, что пути в `data.yaml` корректны. **Проблема:** Редкие классы показывают Recall=0 **Решение:** Увеличить число эпох (100-300), использовать `imgsz=640`, стратифицированный сплит гарантирует минимум 1 пример в train для каждого класса. **Проблема:** Не удаётся прочитать NRRD файлы **Решение:** Убедитесь, что установлены зависимости: `pip install nrrd pydicom scipy` **Проблема:** Ошибки с путями в Windows (пробелы в именах) **Решение:** Переименуйте файлы, убрав пробелы. Например: `"501 arterial ax 1mm iDose (5).nrrd"` → `"501_arterial_ax_1mm_iDose_5.nrrd"` ## 📝 Changelog ### 2026-08-19 (текущая версия) - ✅ Поддержка двух экспериментов: `1_2236040_zno_cyst_AF` и `prep` - ✅ Реальная структура данных: DICOM (1042 среза), PNG (300 срезов) - ✅ Разметка в формате YOLO для 300 изображений - ✅ Образовательные материалы: лекции (3 PDF), семинары (Jupyter ноутбуки) - ✅ Скрипты для работы с 3D данными (Тема 2.1 и 2.2) - ✅ Виртуальное окружение с полным набором зависимостей - ✅ `predefined_classes.txt` для каждого эксперимента - ✅ Стратифицированный сплиттер `ttv_freq2.py` - ✅ Скрипты обучения детекции и сегментации ### Структура данных - **DICOM файлы:** 1042 среза (slice_0000.dcm — slice_1041.dcm) - **PNG изображения:** 300 срезов (slice_0573.png — slice_0872.png) - **Разметка:** 300 файлов `.txt` в формате YOLO - **Классы:** 12 классов (почки, сегменты, опухоли, кисты, абсцесс) ## 📄 Лицензия Образовательный проект. Медицинские данные используются в исследовательских и учебных целях.