Spaces:
Sleeping
Sleeping
Copilot Instructions for seg_app
This document is the authoritative design contract for this project. All implementations must conform to it unless explicitly revised.
Project Intent
seg_app is an interactive 3D medical image segmentation tool for CT and MR volumes.
- Target users: Radiologists
- Purpose: Clinical decision-support and research prototyping
- Deployment: Hugging Face Spaces (Gradio frontend, PyTorch backend)
- Scope: Research/prototype use only β NOT regulatory-approved
Explicit Non-Goals
- NOT a PACS viewer or DICOM study manager
- NOT a real-time or streaming inference system
- NOT for multi-user hospital deployment or high concurrency
- NOT intended for FDA/CE clinical use
Architecture Overview
UI (Gradio) β Inference Orchestrator β Models β Data I/O
β
Metrics & Postprocessing
Architectural Invariants (Must Not Be Broken)
- UI code must never call model code directly β all inference goes through the orchestrator
- Model backends must be swappable without UI changes β UI depends only on
orchestrator.py - Radiologists interact with tasks, not model architectures β task names are user-facing, model IDs are internal
- No model weights are hardcoded locally β all weights load from HF Hub (or user-uploaded paths)
- Spatial metadata must flow through the entire pipeline β required for accurate volume calculations
Project Structure
web_app/
βββ app.py # HF Spaces entry point
βββ requirements.txt
βββ README.md # HF Spaces metadata (YAML frontmatter)
βββ seg_app/
βββ config/
β βββ settings.py # Global settings, HF Hub IDs, defaults
β βββ tasks.py # Task definitions β model mappings
βββ data/
β βββ io.py # NIfTI loading/saving (nibabel)
β βββ preprocessing.py # Normalization, resampling, orientation
βββ inference/
β βββ orchestrator.py # Task β model dispatch, inference pipeline
β βββ model_registry.py # Model registration, lazy loading
β βββ postprocess.py # Thresholding, connected components
βββ metrics/
β βββ segmentation_metrics.py # Volume (mmΒ³), Dice, surface metrics
βββ models/
β βββ base.py # Abstract base class for all models
β βββ monai_autoseg.py # MONAI Auto3DSeg wrapper
β βββ unet3d.py # Task-specific 3D U-Net / VNet
β βββ medical_sam.py # Medical SAM for interactive refinement
βββ ui/
βββ gradio_app.py # Gradio Blocks layout, component wiring
βββ viewer.py # Multi-planar renderer (axial/sag/cor)
βββ overlays.py # Segmentation mask overlay rendering
User Workflow
- User uploads a 3D CT or MR volume (NIfTI format)
- Volume displayed in multi-planar view (axial scrollable, sagittal, coronal)
- User selects a segmentation task (e.g., "Liver", "Brain Lesion")
- Default model runs automatically for that task
- User may refine with point/bounding-box prompts (optional)
- Outputs: on-screen overlays, volume metrics (mmΒ³), downloadable mask (future)
Key Module Responsibilities
config/tasks.py
Defines task registry as Python dataclasses or dicts:
TASKS = {
"liver": TaskConfig(
display_name="Liver Segmentation",
model_id="monai-auto3dseg-liver",
hf_hub_path="your-org/liver-seg-model",
supports_refinement=True,
),
"brain_lesion": TaskConfig(
display_name="Brain Lesion (Tumor) Segmentation",
model_id="unet3d-brain-tumor",
hf_hub_path="your-org/brain-tumor-model",
supports_refinement=True,
),
}
inference/orchestrator.py
Single entry point for inference:
def run_segmentation(
volume: np.ndarray,
task_name: str,
prompts: Optional[Prompts] = None,
full_reinference: bool = False, # Default: SAM refinement only
) -> SegmentationResult:
- If
promptsprovided andfull_reinference=False: run SAM refinement on existing mask - If
full_reinference=True: run complete pipeline with prompts
inference/model_registry.py
Model loading strategy:
- Primary: Lazy-load from Hugging Face Hub on first use
- Alternative: Support local file upload for custom weights
def load_model(model_id: str, local_path: Optional[str] = None) -> BaseModel:
models/base.py
Abstract interface all models must implement:
class BaseModel(ABC):
def load(self, weights_source: str) -> None: ...
def preprocess(self, volume: np.ndarray, config: dict) -> torch.Tensor: ...
def predict(self, tensor: torch.Tensor, prompts: Optional[Prompts] = None) -> torch.Tensor: ...
def postprocess(self, tensor: torch.Tensor) -> np.ndarray: ...
ui/viewer.py
Multi-planar viewer behavior:
- Renders axial, sagittal, coronal views simultaneously
- Default: Center slice on initial load and after segmentation
- Optional: Maintain slice position across runs (configurable)
- Uses matplotlib/PIL for pure Python rendering (no JS viewer)
Data Flow
- Input: NIfTI volumes via
data/io.py(nibabel) - Preprocessing: Normalization, resampling, RAS orientation in
data/preprocessing.py - Inference: Task lookup in
config/tasks.pyβ model dispatch viaorchestrator.py - Postprocessing: Label cleanup in
inference/postprocess.py - Metrics: Volume calculation (mmΒ³) in
metrics/segmentation_metrics.py - Output: Overlay rendering via
ui/overlays.py
Conventions
- Type hints: Required for all function signatures
- Array ordering: Medical imaging arrays use
(D, H, W)or(C, D, H, W) - Configuration: All settings in
config/, never hardcoded - Model weights: Lazy-loaded to minimize startup time
- Dependencies: MONAI, segment-anything (Medical SAM), Gradio, nibabel, PyTorch
Environment
- Python environment managed via Conda (see
.vscode/settings.json) - Deployment target: Hugging Face Spaces (GPU tier required)
- Single-user / low-concurrency research usage