20 KiB
Аналитический документ: DXA Quality Assessment System
Содержание
- Обзор системы
- Архитектура
- Компоненты системы
- Пайплайн обработки
- API Endpoints
- Модели и алгоритмы
- 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)
- Инференс модели
- Формирование ответов
# Основной 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 (Простая реализация)
Для сегментации используется простой пороговый метод:
# 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)
Определение анатомической области по содержимому изображения:
Алгоритм:
- Пороговая бинаризация (95 перцентиль)
- Вычисление bounding box яркой области
- Соотношение сторон bbox:
- < 1.5 → spine (более квадратная область)
- ≥ 1.5 → hip (вытянутая область)
- Для hip: определение левого/правого по асимметрии яркости
Пайплайн обработки
Основной пайплайн
@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
Детальная диаграмма последовательности
@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)
{
"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— ошибка ROIincomplete_view— неполный вид
Метрики детекции движения
| Метрика | Порог | Описание |
|---|---|---|
| Laplacian variance | < 0.002 | Низкая дисперсия = размытие |
| FFT high-freq ratio | < 0.3 | Низкая высокочастотная энергия |
| Edge duplication | bool | Дублирование краев |
Алгоритм определения региона
@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 Диаграммы
Диаграмма компонентов
@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
Диаграмма классов (основные сущности)
@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
Диаграмма развертывания
@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
Потоки данных
@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
Ограничения и планы развития
Текущие ограничения
- Сегментация — простая пороговая обработка, требует замены на Deep Learning (UNet/TotalSegmentator)
- Модель — бинарная классификация, нужно расширение до многоклассовой для типов нарушений
- Dataset — ~100 исследований, требуется расширение до 500+
- 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 контейнеризация