Skip to content

HistoSlice Documentation

PyPI - Version PyPI - Python Version

Overview

HistoSlice makes is easy to prepare your histological slide images for deep learning models. You can easily cut large slide images into smaller tiles and then preprocess those tiles (remove tiles with shitty tissue, finger marks etc).

This project was forked from HistoPrep, and further modified for additional features and improvements.

Installation

Install install HistoSlice with uv or pip!

uv add histoslice
# or
pip install histoslice

Or install latest development version from GitHub:

uv add git+https://github.com/rmuraix/HistoSlice
# or
pip install git+https://github.com/rmuraix/HistoSlice

Alternatively, you can install the package from source:

git clone https://github.com/rmuraix/HistoSlice.git
cd HistoSlice
uv sync

Usage

Cutting Slide Images

Cut each slide image into smaller tile images.

histoslice --help will show you all available options. For Python API usage, see the API documentation.

histoslice \
    --input './images/*.tiff' \
    --output ./tiles \
    --width 512 \
    --overlap 0.5 \
    --max-background 0.5 \
    --metrics \
    --thumbnail
from histoslice import SlideReader

# Read slide image.
reader = SlideReader("./parh/to/slide_image.tiff")
# Detect tissue.
threshold, tissue_mask = reader.get_tissue_mask(level=-1)
# Extract overlapping tile coordinates with less than 50% background.
tile_coordinates = reader.get_tile_coordinates(
    tissue_mask, width=512, overlap=0.5, max_background=0.5
)
# Save tile images with image metrics for preprocessing.
tile_metadata, failures = reader.save_regions(
    "./tiles/",
    tile_coordinates,
    threshold=threshold,
    save_metrics=True,
    save_thumbnail=True
)
if failures:
    print(f"Some tiles failed: {len(failures)}")

Physical Scale Normalization

HistoSlice supports normalizing slides to a consistent physical resolution using target_mpp. This ensures both consistent physical scale AND consistent tensor dimensions for deep learning pipelines.

# Normalize to 0.5 mpp with 512x512 pixel tiles
# All slides will produce 512x512 tiles representing the same physical area
histoslice \
    --input './images/*.tiff' \
    --output ./tiles \
    --width 512 \
    --target-mpp 0.5 \
    --overlap 0.5 \
    --max-background 0.5

# Override slide mpp if metadata is missing or incorrect
histoslice \
    --input './images/*.tiff' \
    --output ./tiles \
    --mpp 0.5 \
    --width 512 \
    --target-mpp 0.25
from histoslice import SlideReader

# Read slide image - mpp extracted from metadata
reader = SlideReader("./path/to/slide.tiff")
print(f"Slide mpp: {reader.mpp}")  # e.g., (0.25, 0.25)

# Override mpp if needed
reader = SlideReader("./path/to/slide.tiff", mpp=(0.5, 0.5))

# Normalize to target resolution - always get 512x512 pixel tiles
threshold, tissue_mask = reader.get_tissue_mask(level=-1)
tile_coordinates = reader.get_tile_coordinates(
    tissue_mask, 
    width=512,       # Output tile size in pixels
    target_mpp=0.5,  # Target resolution (512px * 0.5mpp = 256µm physical size)
    overlap=0.5, 
    max_background=0.5
)
# Result: 512x512 pixel tiles representing 256x256 µm physical area

Resolution Normalization

When target_mpp is specified:

  • Tiles are extracted at the appropriate resolution to achieve the target mpp
  • Output tiles are always width x height pixels (consistent tensor dimensions)
  • Each tile represents width * target_mpp x height * target_mpp microns
  • Example: 512px tiles at 0.5 mpp = 256µm x 256µm physical area

This is ideal for deep learning where you need: - Consistent physical scale across slides (same biological structures) - Consistent tensor shape for neural networks (e.g., always 512x512)

MPP Extraction

HistoSlice automatically extracts microns-per-pixel (mpp) from slide metadata when available. It supports:

  • OpenSlide properties (openslide.mpp-x, openslide.mpp-y)
  • TIFF resolution tags with unit conversion
  • Generic resolution metadata (xres, yres)

If your slides don't have mpp metadata, you can provide it manually using the --mpp CLI option or mpp parameter in the Python API.

Output directory structure will look like this:

tiles
└── slide_id
    ├── metadata.parquet       # tile metadata
    ├── failures.json          # per-tile failures (only written if any failures occur)
    ├── properties.json        # tile properties
    ├── thumbnail.jpeg         # thumbnail image (or .png if JPEG unsupported)
    ├── thumbnail_tiles.jpeg   # thumbnail with tiles (or .png if JPEG unsupported)
    ├── thumbnail_tissue.jpeg  # thumbnail of the tissue mask (or .png if JPEG unsupported)
    └── tiles

Note

If Pillow lacks JPEG support in your environment, HistoSlice will write .png files and update filenames accordingly. Developers can check support via histoslice.functional.has_jpeg_support().

Note

If any tiles fail during extraction, the CLI prints a warning and writes failures.json with per-tile error details.

Prostate biopsy sample Tissue mask Thumbnail with tiles

Remove Bad Tiles

Histological slide images often contain areas that we would not like to include into our training data. Might seem like a daunting task but let's try it out!

# First, extract tiles with metrics
histoslice slice \
    --input './images/*.tiff' \
    --output ./tiles \
    --width 512 \
    --metrics

# Then, detect outliers using clustering and save metadata_clean.parquet
# Specify the parent directory containing slide outputs
histoslice clean \
    --input './tiles/*' \
    --num-clusters 4

# For parallel processing of multiple slides
histoslice clean \
    --input './tiles/*' \
    --num-clusters 4 \
    --num-workers 4
from histoslice.utils import OutlierDetector

# Let's wrap the tile metadata with a helper class.
detector = OutlierDetector(tile_metadata)
# Cluster tiles based on image metrics.
clusters = detector.cluster_kmeans(num_clusters=4, random_state=666)
# Visualise first cluster.
reader.get_annotated_thumbnail(
    image=reader.read_level(-1), coordinates=detector.coordinates[clusters == 0]
)

Now we can mark tiles in cluster 0 as outliers!

Tiles in cluster 0

The clean command automatically detects outliers in cluster 0 (the cluster most distant from the mean cluster center after k-means clustering orders them by distance) and saves a metadata_clean.parquet file in each slide directory. This file contains all original metric columns plus two extra columns: is_outlier (boolean) and method (the detection method used, e.g. "clustering"). The command supports parallel processing of multiple slides using the --num-workers option.

For more information on how to use the OutlierDetector, see the API documentation.