Metadata-Version: 2.1
Name: medics-ext-image-labeler
Version: 202608281603
Summary: Image labeling extension for MedICS - 2D image annotation and analysis
Author-email: MedICS <medics.support@gmail.com>
License: Proprietary
Project-URL: Homepage, https://Medical-Image-Computing-Suite.github.io
Project-URL: Documentation, https://github.com/Medical-Image-Computing-Suite/Community/wiki
Project-URL: Repository, https://github.com/Medical-Image-Computing-Suite/MedICS-ext-image-labeler.git
Project-URL: Issues, https://github.com/Medical-Image-Computing-Suite/Community/issues
Keywords: medical,imaging,annotation,labeling,extension
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Healthcare Industry
Classifier: Intended Audience :: Science/Research
Classifier: License :: Other/Proprietary License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Scientific/Engineering :: Medical Science Apps.
Classifier: Topic :: Scientific/Engineering :: Visualization
Classifier: Topic :: Scientific/Engineering :: Image Processing
Requires-Python: >=3.11
Description-Content-Type: text/markdown
Requires-Dist: medics

# MedICS Image Labeler

A 2D image annotation extension for [MedICS](https://Medical-Image-Computing-Suite.github.io). Paint pixel-level semantic labels on medical images, manage multiple label maps per case, and export results in standard formats.

---

## Table of Contents

- [Installation](#installation)
- [Opening the Extension](#opening-the-extension)
- [Interface Overview](#interface-overview)
- [Quick Start Workflow](#quick-start-workflow)
- [Loading Images](#loading-images)
- [Working with Labels](#working-with-labels)
- [Annotation Tools](#annotation-tools)
- [Label Maps](#label-maps)
- [Saving Your Work](#saving-your-work)
- [Navigating a Dataset](#navigating-a-dataset)
- [Custom Data Loaders](#custom-data-loaders)
- [MedICS Workspace Integration](#medics-workspace-integration)
- [Keyboard Shortcuts](#keyboard-shortcuts)
- [Supported File Formats](#supported-file-formats)
- [Tips and Troubleshooting](#tips-and-troubleshooting)

---

## Installation

### As a MedICS extension (recommended)

Install the package into the same Python environment as MedICS:

```bash
pip install medics-ext-image-labeler
```

Or with [uv](https://docs.astral.sh/uv/):

```bash
uv pip install medics-ext-image-labeler
```

**Requirements:** Python 3.11+, MedICS (`medics` package).

After installation, restart MedICS. The extension appears as **Image Labeler** in the extensions list.

### Standalone mode (without the full MedICS UI)

You can run the labeler as a standalone window for local testing:

```bash
git clone <this-repo>
cd medics-ext-image-labeler
uv sync
uv run python main.py
```

Standalone mode supports file-based loading and annotation. MedICS workspace drag-and-drop requires running inside MedICS.

---

## Opening the Extension

1. Launch MedICS.
2. Open the **Extensions** panel or menu.
3. Select **Image Labeler**.

The main window opens with dockable panels. You can rearrange, float, or resize docks to fit your screen.

---

## Interface Overview

```
┌─────────────────────────────────────────────────────────────────────────────┐
│  Toolbox (annotation tools, filters, notes)                                 │
├──────────────┬──────────────────────────────────────────────────────────────┤
│ Left panel   │  Image panel(s) — main image + optional reference views      │
│              │                                                              │
│ Load / nav   │  Each panel: windowing, colormap, link, label transparency   │
│ Save         │                                                              │
│ Label maps   │                                                              │
│ Labels       │                                                              │
├──────────────┴──────────────────────────────────────────────────────────────┤
│ Status bar — cursor position, pixel value, label stats, image size          │
└─────────────────────────────────────────────────────────────────────────────┘
```

### Left panel

| Section | Purpose |
|---------|---------|
| **Settings...** | Configure custom Python data and label-map loaders |
| **Load Images...** | Open the load dialog (files, folders, lists, references, label maps) |
| **Navigation** | Previous / Next, index spinbox, filename dropdown |
| **Save path** | Output folder for label files (`Save path` button to change) |
| **AutoSave** | Save automatically when you move to another image |
| **Export format** | `.tiff` (default) or `.med` |
| **Label maps** | Load, add, delete, and switch between maps for the current image |
| **Labels** | Select the active label, edit colors, edit label metadata |

### Image panels

Up to **four** panels can be shown:

| Panel | Role |
|-------|------|
| **Image** | Main image you annotate |
| **Reference 1–3** | Optional side-by-side views (same index as main image) |

Each panel toolbar includes:

- **Windowing** — low/high spinboxes and colorbar (right-click colorbar to change colormap)
- **Link** — sync zoom and pan with other linked panels
- **Show label** — toggle label overlay
- **Transparency** — label overlay opacity (0.0–1.0)

### Toolbox (top bar)

| Group | Controls |
|-------|----------|
| **Brush settings** | Size, shape (disk / square / rod), angle |
| **Post-processing** | Fill holes, region filter (minimum region size) |
| **Tools** | Brush, Change Label, T-Min, T-Max, T-Range |
| **Notes** | Free-text notes stored with the current label map |

### Status bar

Shows mouse coordinates, pixel value under cursor, label coverage for the first two labels, and current image dimensions.

---

## Quick Start Workflow

1. **Load images** — click **Load Images...** or drag files onto the window.
2. **Choose a label** — click a row in the label list on the left.
3. **Pick a tool** — click **Brush** in the toolbox.
4. **Paint** — click and drag on the main image panel (focus the image first).
5. **Save** — set **Save path**, enable **AutoSave**, then use **Next** to save and advance.
6. **Export** — label files are written next to your images (see [Saving Your Work](#saving-your-work)).

---

## Loading Images

### Drag and drop

Drop any of the following onto the main window or an image panel:

- One or more image files
- A folder (all supported images inside are collected)
- A text file with one image path per line
- A MedICS workspace variable (when running inside MedICS)

Supported image extensions: `.jpg`, `.jpeg`, `.png`, `.bmp`, `.tif`, `.tiff`, `.gif`, `.webp`

### Load Images... dialog

Click **Load Images...** to open a structured load dialog.

#### Main images

Choose one of three source modes:

| Mode | Use when |
|------|----------|
| **File list** | You have a `.txt` file listing image paths |
| **Folder** | You want to scan a directory (optional pattern filter, optional recursive search) |
| **Explorer** | You want to pick files manually in a file browser |

#### Reference images (optional)

Enable **Reference images** to load up to three aligned reference series. Each reference set uses the same three modes (list / folder / explorer). Reference paths should correspond index-by-index with the main image list.

#### Label maps (optional)

Enable **Label maps** to attach existing annotation files when loading. If you skip this, the labeler tries to find existing maps automatically (see [Auto-discovery](#auto-discovery-of-existing-label-maps)).

Click **OK** to start loading. The first image appears immediately; remaining images load in the background.

---

## Working with Labels

The label list shows every label class you can paint with.

### Select a label

Click a label row. The selected row is highlighted. All painting tools use this label value.

### Change label color

Use the color button in the **Color** column.

### Edit label name and description

Click the **Edit** (pencil) button on a row. The edit dialog lets you change name, color, and description.

### Label values

Labels use numeric IDs internally (shown in the default label set). When you paint, pixels are set to the selected label’s ID.

---

## Annotation Tools

Select a tool in the toolbox, then interact with the **main image panel**. Make sure the image view has focus (click it once) so keyboard shortcuts work.

### Brush

Freehand painting.

- **Size** — spinbox or scroll wheel over the image
- **Shape** — disk, square, or rod
- **Angle** — rotation for rod-shaped brush

### Change Label

Click an already-labeled region to reassign it to the currently selected label.

### T-Min (threshold low)

Click a pixel. Connected pixels with intensity **below** `clicked value + offset` are filled with the current label. Adjust the offset in the toolbox spinbox.

### T-Max (threshold high)

Same as T-Min, but selects connected pixels **above** the threshold.

### T-Range (threshold range)

Click a pixel. Connected pixels within a symmetric intensity range around the clicked value are filled.

### Post-processing (Fill Holes / Region Filter)

Applied after each stroke:

| Setting | Effect |
|---------|--------|
| **Fill Holes** | Fills small holes inside painted regions |
| **Region Filter** | Removes regions smaller than the given pixel count |

Increase **Region Filter** to remove speckle; increase **Fill Holes** to close gaps in irregular shapes.

---

## Label Maps

Each image can have **multiple independent label maps** — useful for multi-rater studies, drafts vs. final labels, or different annotation tasks on the same image.

### Switch maps

Click a map name in the **Label maps** list. The overlay updates to that map.

### Add a map

1. Load an image first.
2. Click **Add...**
3. Enter a unique map name.

A new empty map (same size as the image) is created.

### Load a map from file

Click **Load Label Map...** and select a file (`.tiff`, `.png`, or `.med`). Maps are merged into the current image’s map collection. Spatial dimensions must match the image.

### Delete a map

Select a map and click the **Delete** button in its row. At least one map must remain.

### Auto-discovery of existing label maps

When you load images without specifying label files, the labeler looks next to each image for:

1. `{image_basename}_lmp.tiff`
2. `{image_basename}_lmp.med`
3. `{image_basename}_ungradable.json`

If several exist, the most recently modified file is used.

---

## Saving Your Work

### Save path

The **Save path** field shows where label files are written. Click **Save path** to choose a different folder. By default it is set to the common parent directory of your loaded images.

### AutoSave

Enable **AutoSave** to write the current image’s label map when you go to the **Previous** or **Next** image.

### Export format

| Format | What is saved | Output filename |
|--------|---------------|-----------------|
| **.tiff** (default) | All label maps for the current image as a multi-layer TIFF stack, with colormap and metadata | `{basename}_lmp.tiff` |
| **.med** | Current map, full label definitions, and notes | `{basename}_lmp.med` |

The `.tiff` stack stores map names and notes in image metadata. The `.med` format preserves label colors and definitions for reloading in MedICS tools.

### Notes

Use the **Notes** text field in the toolbox to attach free-text notes to the current label map. Notes are included in exported `.tiff` and `.med` files.

---

## Navigating a Dataset

| Action | How |
|--------|-----|
| Next image | **Next** button, or `→`, `↓`, `Page Down` (with image panel focused) |
| Previous image | **Previous** button, or `←`, `↑`, `Page Up` |
| Jump by index | Spinbox showing `current / total` |
| Jump by filename | Dropdown below the spinbox |

When **AutoSave** is on, changing images saves the map you were working on.

Background loading continues while you annotate early images. Watch the status bar for progress messages.

---

## Custom Data Loaders

Use custom loaders when your images or label maps are stored in a proprietary format not supported by the built-in readers.

Open **Settings...** in the left panel to manage loaders.

### Loader storage

Custom loader scripts live in:

```text
~/.medics/customDataLoader/
├── my_loader.py
├── another_loader.py
└── ...
```

Each `.py` file is one module. Functions defined at the top level become available in the settings dialog.

### Settings dialog layout

```
┌─────────────────────────────────────────────────────────────────────────┐
│ Load Data Settings                                                      │
├──────────────────┬──────────────────────────────────────────────────────┤
│ [function list]  │ [Data >>]      [read-only assignment field]  [Clear] │
│ module.function  │ [Label Map >>] [read-only assignment field]  [Clear] │
│ ...              │ [syntax-highlighted source preview]                  │
│ [Remove]         │                                                      │
│ [Add from file]  │                                                      │
│ [Add from code]  │                                                      │
├──────────────────┴──────────────────────────────────────────────────────┤
│                                              [OK]  [Cancel]             │
└─────────────────────────────────────────────────────────────────────────┘
```

### Assign loaders

1. Select a function in the list on the left.
2. Click **Data >>** to assign it as the **image loader**, or **Label Map >>** for the **label-map loader**.
3. Click **OK**.

Leave an assignment empty (or click **Clear**) to use the built-in default loader for that role.

### Add from code

Opens a Python editor with a starter template:

```python
def load_image(file_path):
    """Load a 2D image. Return a numpy array (H, W) or (H, W, C)."""
    ...

def load_label_map(file_path, app_name="imagelabeler"):
    """Load label maps. Return (maps_dict, notes) or a maps dict."""
    ...
```

Steps:

1. Click **Add from code**.
2. Edit the template (implement the functions you need).
3. Set **Save name** (file name without `.py`).
4. Click **Test** to verify the script loads without errors.
5. Click **OK** to save into `~/.medics/customDataLoader/`.
6. Back in the settings dialog, select functions and assign them with **Data >>** / **Label Map >>**.

### Add from file

Copy an existing `.py` loader script into `~/.medics/customDataLoader/`. The function list refreshes automatically.

### Remove a function

Select a function and click **Remove**. The function is marked `#deleted` in the source file (soft delete) and hidden from the list. If every function in a file is deleted, the file is removed.

### Loader function contracts

**Image loader** — called as `loader(image_path)`:

- Must return a NumPy array, shape `(H, W)` or `(H, W, C)`.

**Label-map loader** — called as `loader(label_path, app_name="imagelabeler")`:

- Must return `(maps_dict, notes)` where `maps_dict` maps map names to 2D `uint8` arrays, **or** a dict that the built-in reader can interpret.

Recognized data-loader function names (first match is preferred after import): `load_image_data`, `load_data`, `load_image`.

---

## MedICS Workspace Integration

When running inside MedICS, you can load data without exporting files first.

### Drag workspace variables

Drag a workspace variable from the MedICS workspace panel onto the Image Labeler window. The extension resolves paths like `ws.images['slice']` and loads compatible NumPy arrays or lists of arrays.

Supported data:

- 2D NumPy arrays
- Lists of 2D arrays (loaded as an image series)
- Nested structures that resolve to the above

If the dropped variable cannot be converted to images, a message appears in the status bar.

### Workflow tip

Process data in another MedICS extension, keep results in the workspace, then drag them directly into the labeler for annotation.

---

## Keyboard Shortcuts

Shortcuts apply when an **image panel** has focus (click the image first).

| Shortcut | Action |
|----------|--------|
| `Page Down`, `→`, `↓` | Next image |
| `Page Up`, `←`, `↑` | Previous image |
| Scroll wheel (over image) | Adjust brush size |

---

## Supported File Formats

### Input

| Type | Formats |
|------|---------|
| Images | `.jpg`, `.jpeg`, `.png`, `.bmp`, `.tif`, `.tiff`, `.gif`, `.webp` |
| Label maps | `.tiff`, `.png`, `.med` |
| Custom | Any format supported by your Python loader scripts |

### Output

| Format | Contents |
|--------|----------|
| `{name}_lmp.tiff` | Multi-map TIFF stack + colormap + metadata |
| `{name}_lmp.med` | Maps, label definitions, notes (MedICS format) |

---

## Tips and Troubleshooting

### Painting has no effect

- Confirm a label is selected in the left panel.
- Confirm a tool (e.g. **Brush**) is active in the toolbox.
- Click the image panel to give it focus.

### Label map shape mismatch

Label maps must match the main image height and width. Reload or resize data before importing a map.

### Custom loader not used

After editing loaders in **Settings...**, click **OK** to apply. Both assignments cannot be `default` if you want custom loading — assign at least one loader explicitly.

### Images not found when loading a folder

Check the **filter** pattern in the folder tab (e.g. `*.png`). Enable **recursive** search if images are in subfolders.

### Reference panels look wrong

Reference file lists must align index-by-index with the main image list. Image 3’s reference should be the third path in each reference list.

### Getting help

- MedICS community wiki: [Medical-Image-Computing-Suite/Community/wiki](https://github.com/Medical-Image-Computing-Suite/Community/wiki)
- Report issues: [Medical-Image-Computing-Suite/Community/issues](https://github.com/Medical-Image-Computing-Suite/Community/issues)

---

## License

Proprietary — MedICS Image Labeler extension. See package metadata for licensing terms.
