Metadata-Version: 2.5
Name: med-image-seg
Version: 0.1.1
Summary: Interactive polygon annotation for DICOM, NIfTI, and UBD volumes
Author-email: GGN_2015 <neko@jlulug.org>
License: MIT
License-File: LICENSE
Requires-Python: >=3.12
Requires-Dist: ct-mri-dicom-nii-reader
Requires-Dist: numpy<3,>=1.26
Requires-Dist: pyside6<7,>=6.8
Requires-Dist: scikit-image<1,>=0.24
Requires-Dist: scipy<2,>=1.13
Requires-Dist: simpleitk<3,>=2.5
Description-Content-Type: text/markdown

# med-image-seg

`med-image-seg` is a standalone, programmable multi-polygon annotation tool for medical images. It supports DICOM series, NIfTI, and `.ubd.npz` volumes.

The GUI is bilingual. English is the default, and users can switch between English and Chinese at runtime without reloading the image.

## Screenshot

![med-image-seg showing machine and manual bone contours on a real pelvic CBCT](https://raw.githubusercontent.com/GGN-2015/med-image-seg/main/docs/images/annotation-workflow.png)

The example shows a real pelvic CBCT with machine-generated contours in orange and purple, plus manual corrections in green and red on the same slice. The anonymized image is case `2PB043` from the [SynthRAD2023 dataset](https://doi.org/10.5281/zenodo.7260705), released under [CC BY-NC 4.0](https://creativecommons.org/licenses/by-nc/4.0/).

## Installation and launch

Python 3.12 or later is required.

```powershell
uv sync --frozen
uv run med-image-seg
```

Launching without arguments opens an empty image collection. Use **Import image files** to select one or more NIfTI, UBD, or DICOM files, or use **Import DICOM folder** for a series directory.

The CLI can provide the initial image collection. Inputs are deduplicated, and the first item is loaded automatically:

```powershell
uv run med-image-seg `
  --image "D:\dicom-series" `
  --image "D:\images\pelvis.nii.gz" `
  --image "D:\images\knee.ubd.npz" `
  --spacing 0.8
```

Positional image paths remain supported. When `--image PATH` opens a single image, the application checks the corresponding JSON location listed below. If found, it validates the source fingerprint and volume geometry before displaying the existing machine and manual contours.

To inspect a result generated by `cbct-bone`:

```powershell
uv run med-image-seg --image "D:\images\scan.nii.gz"
```

Start directly in Chinese with `--language zh`; `--language en` is the default:

```powershell
uv run med-image-seg --language zh --image "D:\images\scan.nii.gz"
```

## Annotation file locations

Annotations are always stored beside the source image:

| Image type | Annotation JSON | Exported mask |
| --- | --- | --- |
| DICOM directory or a DICOM file inside it | `<DICOM directory>/.med-image-seg.json` | `<DICOM directory>/med-image-seg-mask.nii.gz` |
| `scan.nii` / `scan.nii.gz` | `scan.med-image-seg.json` | `scan.med-image-seg-mask.nii.gz` |
| `scan.ubd.npz` | `scan.med-image-seg.json` | `scan.med-image-seg-mask.nii.gz` |

The JSON does not store source paths or DICOM identity fields. It contains only the content fingerprint, resampled geometry, contours, and review state. Every polygon addition, vertex drag, deletion, copy, clear, or review action is saved immediately with atomic replacement. A rolling `.json.bak` backup and a 10-second fallback autosave are also maintained.

## GUI controls

- Loading and resampling run on a background thread. A modal progress indicator is visible and the main GUI is disabled while loading.
- Left-click adds vertices. Right-click, double-click, or `Space` closes a polygon.
- Drag a colored vertex to reshape an existing polygon.
- `Ctrl+Z` or **Delete last edited polygon on this slice** removes the polygon most recently added or vertex-edited on the current slice.
- `C` copies the previous slice annotation; `M` marks the current slice as reviewed.
- **Force no segmentation on this slice** keeps the output slice empty and suppresses blue interpolation. Saved contours remain intact and reappear when the option is cleared. Adding a new contour also clears the forced-empty state.
- Empty slices between two keyframes are interpolated dynamically with signed distance fields and displayed as translucent blue regions.
- Machine add/erase contours use orange/purple; manual add/erase contours use green/red. Machine and manual regions on the same slice are processed independently and then combined by union, so both contribute to the final mask.
- `E` or the toolbar action exports a 3D NIfTI mask including interpolated slices.

## Python API

Launch with no initial images:

```python
from med_image_seg import AnnotationApplication

app = AnnotationApplication(spacing_mm=0.8)
app.run()
```

Launch with an initial collection and a Chinese interface:

```python
from med_image_seg import AnnotationApplication

app = AnnotationApplication.from_paths(
    ["D:/dicom-series", "D:/images/pelvis.nii.gz"],
    spacing_mm=0.8,
    language="zh",
)
app.add_image("D:/images/knee.nii.gz")
app.run()
```

The window language can also be changed programmatically without restarting:

```python
from med_image_seg import AnnotationMainWindow

window = AnnotationMainWindow(language="en")
window.set_language("zh")
```

The data model, interpolation, and exporter can be used independently:

```python
from med_image_seg import (
    AnnotationExporter,
    AnnotationProject,
    ImageSource,
    MedicalVolumeReader,
    PolygonAnnotation,
)

source = ImageSource.from_path("D:/images/pelvis.nii.gz")
volume = MedicalVolumeReader(0.8).read(source.path)
project = AnnotationProject.create(
    image_id=source.source_id,
    source_fingerprint=source.fingerprint,
    volume=volume,
)
project.add_polygon(
    10,
    PolygonAnnotation(points=((20, 20), (80, 20), (50, 90))),
)
project.save(source.annotation_path)
AnnotationExporter().export(project, volume, source.mask_path)
```

The public API includes `ImageSource`, `ImageCollection`, `MedicalVolumeReader`, `AnnotationProject`, `PolygonAnnotation`, `AnnotationExporter`, `AnnotationApplication`, `AnnotationMainWindow`, `SliceCanvas`, `VolumeLoadThread`, and `launch_annotation_app`. GUI import, asynchronous loading, editing, saving, language switching, and export methods are callable directly from Python.

## Development checks

```powershell
uv run pytest
uv run ruff check .
uv run ruff format --check .
uv build
```
