Metadata-Version: 2.4
Name: labelimage-tools
Version: 0.1.3
Summary: Utilities for 2-D labeled tissue segmentation images
Author: zen-lab, mwappner
License-Expression: BSD-3-Clause
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy>=1.24
Requires-Dist: scipy>=1.10
Provides-Extra: tiff
Requires-Dist: tifffile>=2022.8.12; extra == "tiff"
Provides-Extra: pillow
Requires-Dist: pillow>=9; extra == "pillow"
Provides-Extra: plot
Requires-Dist: matplotlib>=3.7; extra == "plot"
Requires-Dist: scikit-image>=0.21; extra == "plot"
Requires-Dist: networkx>=3.0; extra == "plot"
Provides-Extra: graph-standard
Requires-Dist: networkx>=3.0; extra == "graph-standard"
Provides-Extra: junctions-accelerated
Requires-Dist: numba>=0.57; extra == "junctions-accelerated"
Provides-Extra: recommended
Requires-Dist: tifffile>=2022.8.12; extra == "recommended"
Requires-Dist: numba>=0.57; extra == "recommended"
Provides-Extra: all
Requires-Dist: tifffile>=2022.8.12; extra == "all"
Requires-Dist: pillow>=9; extra == "all"
Requires-Dist: matplotlib>=3.7; extra == "all"
Requires-Dist: scikit-image>=0.21; extra == "all"
Requires-Dist: networkx>=3.0; extra == "all"
Requires-Dist: numba>=0.57; extra == "all"
Provides-Extra: test
Requires-Dist: pytest>=7; extra == "test"
Requires-Dist: tifffile>=2022.8.12; extra == "test"
Requires-Dist: pillow>=9; extra == "test"
Requires-Dist: matplotlib>=3.7; extra == "test"
Requires-Dist: scikit-image>=0.21; extra == "test"
Requires-Dist: networkx>=3.0; extra == "test"
Requires-Dist: numba>=0.57; extra == "test"
Provides-Extra: dev
Requires-Dist: pytest>=7; extra == "dev"
Requires-Dist: ruff>=0.5; extra == "dev"
Requires-Dist: tifffile>=2022.8.12; extra == "dev"
Requires-Dist: pillow>=9; extra == "dev"
Requires-Dist: matplotlib>=3.7; extra == "dev"
Requires-Dist: scikit-image>=0.21; extra == "dev"
Requires-Dist: networkx>=3.0; extra == "dev"
Requires-Dist: numba>=0.57; extra == "dev"
Dynamic: license-file

# labelimage-tools

`labelimage-tools` is a small utility package for 2-D labeled tissue
segmentation images. It provides loading, validation, preprocessing, adjacency
and contact extraction, junction detection, graph coloring, contours, and
matplotlib plotting helpers.

## Conventions

- Label images are 2-D NumPy arrays.
- Image coordinates are represented as `(y, x)`.
- The default background label is `0`.
- Labels do not need to be consecutive.
- Integer label values are preserved unless a function explicitly documents a
  relabeling operation.

## Installation

### Light install

```bash
pip install labelimage-tools
```

The light install supports array-based preprocessing, adjacency/contact graph
calculation, and native NPZ/JSON graph I/O.

### TIFF image I/O

For label-image I/O, installing the `tiff` extra is recommended because most
scientific label images are TIFF files:

```bash
pip install "labelimage-tools[tiff]"
```

This installs `tifffile`, the recommended backend for scientific TIFF label
images.

### Recommended scientific-image install

For most scientific label-image workflows, install TIFF support plus accelerated
junction scanning:

```bash
pip install "labelimage-tools[recommended]"
```

### Other optional features

```bash
pip install "labelimage-tools[pillow]"          # PNG/JPEG/general image I/O
pip install "labelimage-tools[plot]"            # plotting, contours, graph coloring
pip install "labelimage-tools[graph-standard]"  # GraphML/GEXF graph I/O
pip install "labelimage-tools[junctions-accelerated]"  # numba-accelerated junction scanning
pip install "labelimage-tools[all]"             # everything
```

| Feature | Install |
|---|---|
| Core array processing, adjacency, NPZ/JSON graph I/O | `labelimage-tools` |
| TIFF image I/O | `labelimage-tools[tiff]` |
| TIFF image I/O + accelerated junction scanning | `labelimage-tools[recommended]` |
| PNG/JPEG/general image I/O | `labelimage-tools[pillow]` |
| Plotting, contours, graph coloring | `labelimage-tools[plot]` |
| GraphML/GEXF graph I/O | `labelimage-tools[graph-standard]` |
| Everything | `labelimage-tools[all]` |

From a source checkout:

```bash
python -m pip install -e .
```

For tests:

```bash
python -m pip install -e '.[test]'
python -m pytest
```

## Load and preprocess labels

Use these helpers directly from scripts or notebooks. The intended starting
point is `load_image_pipeline(...)`: with its defaults, it crops foreground,
removes disconnected bits of repeated labels, and fills internal gaps. This
prepares the image so labels are clean, self-connected, unique regions that are
ready for adjacency, contour, and junction operations, with neighboring labels
touching across filled internal gaps rather than being separated by stray
background holes.

```python
import labelimage_tools as lit

labels = lit.load_image_pipeline("segmentation.tif")
```

## Adjacency and contact graph

Adjacency is computed by vectorized neighbor scanning. Contact values are
neighboring pixel-pair counts, useful as weights but not exact geometric
lengths. Original label IDs are preserved as graph node IDs.

```python
neighbors, contacts, centroids, pixel_counts = lit.graph_from_labels(labels)

lit.save_label_graph(
    "label_graph.npz",
    neighbors,
    contacts=contacts,
    centroids=centroids,
    pixel_counts=pixel_counts,
    source_image="segmentation.tif",
)

neighbors, contacts, centroids, pixel_counts, metadata = lit.load_label_graph(
    "label_graph.npz"
)

# JSON is a readable alternative for smaller graphs or inspection.
lit.save_label_graph("label_graph.json", neighbors, contacts=contacts)
```

## Junction detection

Junction pixels are pixels whose 3×3 neighborhood contains at least three
distinct labels. Connected junction pixels are clustered into `Junction`
objects with subpixel `(y, x)` centroids and the set of labels that meet there.

```python
junction_label_image, junctions = lit.junctions_from_labels(
    labels,
    background=None,
    min_labels=3,
    connectivity=2,
)

for junction in junctions:
    print(junction.id, junction.yx, sorted(junction.labels))
```

## Graph-colored plotting

Plotting helpers return matplotlib objects and never call `plt.show()`, so they
compose cleanly in notebooks.

```python
fig, ax = lit.plot_label_image(
    labels,
    use_graph_coloring=True,
    K=8,
    seed=1,
    title="Graph-colored labels",
)

fig, ax = lit.plot_junctions(labels, junctions=junctions, ax=ax)
```

You can also use the lower-level coloring helper:

```python
image, lut, ax = lit.show_map_with_colors(labels, K=8, seed=1)
```

## Examples and cookbook

The `examples/` directory contains script-style examples. Edit the constants at
the top of each script, run it, or copy sections into a notebook.

```bash
python examples/01_graph_coloring.py
python examples/02_preprocessing_gallery.py
python examples/03_junctions_and_contours.py
python examples/04_graph_io.py
```

The cookbook walks through the same workflows and embeds the generated images
in the GitHub/local documentation.

- Examples: <https://github.com/zen-laboratory/labelimage-tools/tree/main/examples>
- Cookbook: <https://github.com/zen-laboratory/labelimage-tools/blob/main/docs/cookbook.md>
- Generated example plots: <https://github.com/zen-laboratory/labelimage-tools/tree/main/examples/plots>

### Essential processing outputs

The GitHub README and cookbook show rendered images for the graph-colored label
image, detected junctions, and ordered contours. For PyPI/TestPyPI, those local
relative image embeds are replaced with repository links so the long
description renders safely.

Graph-colored label image using the cyclic `managua` colormap:

```python
labels = lit.load_image_pipeline("samples/test_cells2D.tif")

fig, ax = lit.plot_label_image(
    labels,
    use_graph_coloring=True,
    K=8,
    seed=4,
    cmap="managua",
    cyclic_cmap=True,
    title="Graph-colored label image",
)
```

![Graph-colored labels](https://raw.githubusercontent.com/zen-laboratory/labelimage-tools/main/examples/plots/graph_colored_managua.png)

Detected junctions:

```python
labels = lit.load_image_pipeline("samples/test_cells2D.tif")
junction_label_image, junctions = lit.junctions_from_labels(
    labels,
    background=0,
    min_labels=3,
    connectivity=2,
)
fig, ax = lit.plot_label_image(labels, cmap="managua", cyclic_cmap=True)
lit.plot_junctions(junctions=junctions, junction_mask=junction_label_image > 0, ax=ax)
```

![Detected junctions](https://raw.githubusercontent.com/zen-laboratory/labelimage-tools/main/examples/plots/junctions.png)

Ordered contours:

```python
labels = lit.load_image_pipeline("samples/test_cells2D.tif")
contours = lit.ordered_contours_from_labels(labels, background=0)
fig, ax = lit.plot_label_image(labels, cmap="managua", cyclic_cmap=True)
lit.plot_contours(labels, ax=ax, background=0, color="black", linewidth=0.6)
```

![Contours](https://raw.githubusercontent.com/zen-laboratory/labelimage-tools/main/examples/plots/contours.png)
