bone_2026/docs/architecture-analytical.md

653 lines
20 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Аналитический документ: DXA Quality Assessment System
## Содержание
1. [Обзор системы](#обзор-системы)
2. [Архитектура](#архитектура)
3. [Компоненты системы](#компоненты-системы)
4. [Пайплайн обработки](#пайплайн-обработки)
5. [API Endpoints](#api-endpoints)
6. [Модели и алгоритмы](#модели-и-алгоритмы)
7. [PlantUML Диаграммы](#plantuml-диаграммы)
---
## Обзор системы
Система DXA Quality Assessment — это медицинский AI-сервис для автоматизированной оценки качества исследований DXA (денситометрия костей). Система анализирует DICOM файлы и определяет:
- **Анатомическую область**: позвоночник (spine) или бедро (hip_left/hip_right)
- **Качество изображения**: OK (класс 0) или нарушение (класс 1)
- **Тип нарушения**: движение, артефакты, позиционирование, ROI, ротация
### Целевое назначение
| Параметр | Значение |
|----------|----------|
| Тип | Медицинский AI сервис |
| Входные данные | DICOM файлы (DXA исследования) |
| Выходные данные | JSON / XLSX отчеты |
| Тип классификации | Бинарный (OK / Violation) |
| Целевые регионы | Позвоночник (L1-L4), Бедро (левое/правое) |
---
## Архитектура
### Высокоуровневая архитектура
```
┌─────────────────────────────────────────────────────────────────────────┐
│ DXA Quality Assessment │
├─────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────────┐ │
│ │ Клиент │───▶│ FastAPI │───▶│ Orchestrator │ │
│ │ (Web UI) │ │ Server │ │ (Pipeline Control) │ │
│ └──────────────┘ └──────────────┘ └───────────┬──────────────┘ │
│ │ │
│ ┌───────────────────┼───────────────┐ │
│ ▼ ▼ ▼ │
│ ┌───────────────┐ ┌─────────────┐ ┌──────────┐ │
│ │ DXA Classifier │ │ Segmentor │ │ Quality │ │
│ │ (ResNet18) │ │ (Threshold) │ │ Scorer │ │
│ └───────────────┘ └─────────────┘ └──────────┘ │
│ │
│ ┌────────────────────────────────────────────────────────────────────┐ │
│ │ Detailed Assessment Module │ │
│ │ ┌─────────┐ ┌──────────┐ ┌─────────┐ ┌───────┐ ┌────────┐ │ │
│ │ │ Motion │ │ Artifact │ │ Position│ │ ROI │ │Rotation│ │ │
│ │ │Detector │ │ Detector │ │Validator│ │ Check │ │ Checker│ │ │
│ │ └─────────┘ └──────────┘ └─────────┘ └───────┘ └────────┘ │ │
│ └────────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────┘
```
### Технологический стек
| Компонент | Технология |
|-----------|------------|
| Backend | Python 3.10, FastAPI, Uvicorn |
| ML/DL | PyTorch, torchvision (ResNet18) |
| Image Processing | PIL, OpenCV, pydicom, scipy |
| Data Handling | pandas, openpyxl |
| Containerization | Docker |
---
## Компоненты системы
### 1. API Layer (`src/main.py`)
Точка входа — FastAPI приложение с REST эндпоинтами.
**Основные функции:**
- Прием DICOM файлов через multipart/form-data
- Предобработка изображений (нормализация, ресайз до 224x224)
- Инференс модели
- Формирование ответов
```python
# Основной API эндпоинт
@app.post("/api/v1/analyze/detailed")
async def analyze_dicom_detailed(file: UploadFile = File(...)):
# 1. Загрузка модели
# 2. Предобработка DICOM
# 3. Инференс ResNet18
# 4. Генерация сегментации
# 5. Детальная оценка качества
# 6. Формирование ответа
```
### 2. DXA Classifier (`src/dxa/model.py`)
Модель для бинарной классификации качества изображения.
**Архитектура:**
```
Input (224x224x3)
│
▼
ResNet18 (pretrained on ImageNet)
│
├── Remove final FC layer
│
▼
Classifier Head:
├── Dropout(0.3)
├── Linear(512 → 256)
├── ReLU
├── Dropout(0.3)
└── Linear(256 → 2)
│
▼
Output: [prob_OK, prob_Violation]
```
**Параметры модели:**
- Backbone: ResNet18 (ImageNet pretrained)
- Input: 224x224 RGB
- Output: 2 класса (OK / Violation)
- Dropout: 0.3
### 3. Segmentator (Простая реализация)
Для сегментации используется простой пороговый метод:
```python
# Threshold-based segmentation
threshold = np.percentile(image, 90)
segmentation = (image > threshold).astype(np.uint8)
```
**Планируется:** Замена на UNet или TotalSegmentator для более точной сегментации.
### 4. Detailed Assessment (`src/quality/detailed_assessment.py`)
Модуль детальной оценки качества включает:
#### 4.1 Motion Detection
- **Laplacian variance** — дисперсия лапласиана (ниже = размытие)
- **FFT blur** — анализ высокочастотной энергии (ниже = размытие)
- **Edge duplication** — проверка "призрачных" краев
#### 4.2 Artifact Detection
- **Metal detection** — яркие пятна (>99.5 перцентиль)
- **Implant detection** — линейные структуры
- **Cement detection** — локальные яркие области
- **Calcification** — малые яркие пятна
#### 4.3 Region-Specific Checks
**Для позвоночника (spine):**
- Проверка количества позвонков (3-4 для поясничного отдела)
- Проверка полноты (не обрезаны ли позвонки)
- Проверка выравнивания позвонков
- Проверка контуров позвонков
**Для бедра (hip):**
- Проверка полноты видимости (шейка бедра, головка)
- Проверка ротации (угол главной оси)
- Проверка соотношения сторон
#### 4.4 ROI Validation
- Проверка отступов от краев
- Проверка размера ROI
### 5. Region Detector (`src/dxa/inference.py`)
Определение анатомической области по содержимому изображения:
**Алгоритм:**
1. Пороговая бинаризация (95 перцентиль)
2. Вычисление bounding box яркой области
3. Соотношение сторон bbox:
- < 1.5 → **spine** (более квадратная область)
- ≥ 1.5 → **hip** (вытянутая область)
4. Для hip: определение левого/правого по асимметрии яркости
---
## Пайплайн обработки
### Основной пайплайн
```plantuml
@startuml
title DXA Quality Assessment Pipeline
start
:Upload DICOM file;
:Parse DICOM metadata;
:Preprocess image;
note right
- Normalize to 0-1
- Convert to 3-channel
- Resize to 224x224
end note
:Model Inference (ResNet18);
note right
- Get prediction (OK/Violation)
- Get confidence scores
end note
:Determine Anatomical Region;
note right
- bbox_aspect ratio analysis
- left/right brightness ratio
end note
:Generate Segmentation;
note right
- Threshold-based (90th percentile)
end note
:Detailed Quality Assessment;
note right
- Motion detection
- Artifact detection
- Region-specific checks
- ROI validation
end note
:Determine Violation Type;
note right
- correct
- position_error
- artifact_motion
- artifact_other
- labeling_error
- incomplete_view
- roi_error
- rotation
end note
:Generate Response;
stop
@enduml
```
### Детальная диаграмма последовательности
```plantuml
@startuml
title Sequence: Detailed Analysis
actor User
participant "FastAPI" as API
participant "DXA Model" as Model
participant "Region Detector" as Region
participant "Segmentator" as Seg
participant "Quality Assessor" as QA
User -> API: POST /api/v1/analyze/detailed
API -> API: preprocess_dicom()
API -> Model: predict(image)
Model --> API: [prediction, confidence]
API -> Region: determine_region(image)
Region --> API: "spine" | "hip_left" | "hip_right"
API -> Seg: segment(image)
Seg --> API: segmentation_mask
API -> QA: generate_quality_report()
note over QA
- detect_motion_blur()
- detect_artifacts()
- check_spine_completeness() / check_hip_completeness()
- check_hip_rotation()
- check_roi_boundaries()
- determine_violation_type()
end note
QA --> API: quality_report
API -> API: convert_to_serializable()
API --> User: JSON response
@enduml
```
---
## API Endpoints
| Method | Endpoint | Description |
|--------|----------|-------------|
| GET | `/` | Web interface |
| GET | `/api/v1/health` | Health check |
| POST | `/api/v1/analyze` | Basic analysis |
| POST | `/api/v1/analyze/detailed` | Detailed analysis with metrics |
| POST | `/api/v1/analyze/sr` | DICOM SR report |
| POST | `/api/v1/batch` | Batch processing |
| POST | `/api/v1/export` | Export to XLSX |
### Response Format (Detailed)
```json
{
"anatomical_region": "spine",
"quality_class": 1,
"quality_label": "Violation detected",
"violation_type": "artifact_motion",
"reason": "Обнаружен артефакт движения (размытие)",
"confidence": 0.85,
"confidence_per_class": {
"correct": 0.15,
"violation": 0.85
},
"view_quality": "full",
"metrics": {
"motion": {
"motion_detected": true,
"blur_laplacian": 0.001,
"severity": "HIGH"
},
"artifacts": {
"any_detected": false,
"metal_detected": false
},
"roi_check": {
"valid": true
}
},
"overall_quality": "POOR",
"severity": "HIGH"
}
```
---
## Модели и алгоритмы
### Типы нарушений
**Для позвоночника:**
- `correct` — качество соответствует норме
- `position_error` — ошибка позиционирования
- `artifact_motion` — артефакт движения (размытие)
- `artifact_other` — другие артефакты
- `labeling_error` — ошибка маркировки
- `incomplete_view` — неполный вид
- `roi_error` — ошибка ROI
**Для бедра:**
- `correct` — качество соответствует норме
- `position_error` — ошибка позиционирования
- `rotation` — нарушение ротации
- `artifact_motion` — артефакт движения
- `artifact_other` — другие артефакты
- `roi_error` — ошибка ROI
- `incomplete_view` — неполный вид
### Метрики детекции движения
| Метрика | Порог | Описание |
|---------|-------|----------|
| Laplacian variance | < 0.002 | Низкая дисперсия = размытие |
| FFT high-freq ratio | < 0.3 | Низкая высокочастотная энергия |
| Edge duplication | bool | Дублирование краев |
### Алгоритм определения региона
```plantuml
@startuml
title Region Detection Algorithm
start
:Load DICOM image;
:Normalize to 0-1;
:Threshold at 95th percentile;
if (binary.sum > 0?) then (yes)
:Calculate bounding box;
:Compute bbox_aspect = height / width;
if (bbox_aspect < 1.5) then (yes)
:return "spine";
else (no)
if (bbox_aspect < 1.8) then (yes)
:Calculate symmetry;
if (symmetry > 0.35) then (yes)
:return "spine";
else (no)
:return "hip";
end
else (no)
:Calculate left/right brightness ratio;
if (ratio > 1.3) then (yes)
:return "hip_right";
else if (ratio < 0.7) then (yes)
:return "hip_left";
else (no)
:return "hip";
end
end
end
else (no)
:Fallback: height < 270 → hip;
:return "spine";
end
stop
@enduml
```
---
## PlantUML Диаграммы
### Диаграмма компонентов
```plantuml
@startuml
!theme plain
skinparam componentStyle uml2
component "Web Client" as Client {
[Web UI]
}
component "FastAPI Server" as API {
[Upload Handler]
[Preprocessor]
[Response Builder]
}
component "DXA Models" as Models {
[ResNet18 Classifier]
[Region Detector]
[Segmentator]
}
component "Quality Assessment" as QA {
[Motion Detector]
[Artifact Detector]
[Position Validator]
[ROI Checker]
[Rotation Checker]
}
database "File System" as FS {
[DICOM Files]
[Model Weights]
}
Client -down-> API : HTTP
API -down-> FS : Read/Write
API -right-> Models : Inference
Models -down-> QA : Quality Metrics
@enduml
```
### Диаграмма классов (основные сущности)
```plantuml
@startuml
!theme plain
class DXAQualityClassifier {
+backbone: str
+num_classes: int
+forward(x: Tensor) -> Tensor
+extract_features(x: Tensor) -> Tensor
}
class DXAQualityModel {
+model: DXAQualityClassifier
+device: str
+predict(images: Tensor) -> (preds, probs)
+train_epoch(loader)
+validate(loader)
}
class DetailedAssessment {
+detect_motion_blur(image) -> Dict
+detect_artifacts(image, segmentation) -> Dict
+check_spine_completeness(segmentation) -> Dict
+check_hip_completeness(segmentation) -> Dict
+check_hip_rotation(segmentation, image) -> Dict
+check_roi_boundaries(segmentation, shape) -> Dict
+generate_quality_report(...) -> Dict
}
class RegionDetector {
+determine_region_from_image(image) -> str
+determine_anatomical_region(dcm_path) -> str
}
DXAQualityModel --> DXAQualityClassifier
DXAQualityModel ..> DetailedAssessment : uses
RegionDetector ..> DetailedAssessment : provides region
@enduml
```
### Диаграмма развертывания
```plantuml
@startuml
!theme plain
skinparam rectangle {
BackgroundColor #White
BorderColor #Black
}
rectangle "Client Layer" {
rectangle "Browser" as Browser
rectangle "Web UI (HTML/JS)" as WebUI
}
rectangle "Application Layer" {
rectangle "FastAPI" as API
rectangle "Uvicorn" as Uvicorn
}
rectangle "ML Pipeline" {
rectangle "DXA Classifier" as Classifier
rectangle "Segmentator" as Segmentator
rectangle "Quality Assessor" as Assessor
}
rectangle "Infrastructure" {
rectangle "CPU/GPU" as Compute
rectangle "File System" as Storage
rectangle "Docker" as Docker
}
Browser -right-> WebUI
WebUI -right-> API
API -right-> Uvicorn
Uvicorn -right-> Classifier
Uvicorn -right-> Segmentator
Classifier -right-> Assessor
Classifier -up-> Compute : PyTorch
Segmentator -up-> Compute : NumPy/SciPy
API -down-> Storage : Models/Data
Compute -up-> Docker
@enduml
```
---
## Потоки данных
```plantuml
@startuml
!theme plain
skinparam ranksep 50
skinparam nodesep 50
node "Input" {
[DICOM File]
}
node "Preprocessing" {
[Normalization]
[3-Channel Conv]
[Resize 224x224]
}
node "ML Models" {
[ResNet18]
[Region Detector]
[Threshold Seg]
}
node "Quality Analysis" {
[Motion Detection]
[Artifact Detection]
[Completeness Check]
[ROI Validation]
}
node "Output" {
[JSON Response]
[XLSX Export]
}
[DICOM File] --> [Normalization]
[Normalization] --> [3-Channel Conv]
[3-Channel Conv] --> [Resize 224x224]
[Resize 224x224] --> [ResNet18]
[Resize 224x224] --> [Region Detector]
[Resize 224x224] --> [Threshold Seg]
[ResNet18] --> [Quality Analysis]
[Region Detector] --> [Quality Analysis]
[Threshold Seg] --> [Quality Analysis]
[Quality Analysis] --> [JSON Response]
[Quality Analysis] --> [XLSX Export]
@enduml
```
---
## Ограничения и планы развития
### Текущие ограничения
1. **Сегментация** — простая пороговая обработка, требует замены на Deep Learning (UNet/TotalSegmentator)
2. **Модель** — бинарная классификация, нужно расширение до многоклассовой для типов нарушений
3. **Dataset** — ~100 исследований, требуется расширение до 500+
4. **F1 Score** — текущий ~0.27, требует улучшения
### Планируемые улучшения
| Компонент | План |
|-----------|------|
| Region Detector | Отдельная модель для детекции региона |
| Segmentator | UNet или TotalSegmentator |
| Quality Classifier | Расширение на 8 классов нарушений |
| Violation Classifier | Отдельная модель для классификации типа нарушения |
| Artifact Detector | CNN для детекции металла/имплантатов |
| Visualization | Grad-CAM для внимания модели |
---
## Заключение
Система DXA Quality Assessment представляет собой полнофункциональный AI-сервис для автоматизированной оценки качества DXA исследований. Архитектура построена на принципах модульности и расширяемости, что позволяет поэтапно улучшать отдельные компоненты.
Основные характеристики:
- ✅ RESTful API с FastAPI
- ✅ Глубокое обучение (ResNet18)
- ✅ Детальная оценка качества с метриками
- ✅ Поддержка нескольких типов нарушений
- ✅ Экспорт в XLSX/CSV
- ✅ Docker контейнеризация