Slide reading#
Open a slide, find tissue and choose regions to predict. For a complete workflow, see the whole-slide guide.
Open a slide#
from cellseg_models_pytorch.wsi import SlideReader
reader = SlideReader("data/slide.svs", backend="OPENSLIDE")
level = reader.level_from_max_dimension(1024)
thumbnail = reader.read_level(level)
Choose a reader installed in your environment:
Backend |
Required software |
|---|---|
|
OpenSlide Python bindings and native library |
|
cuCIM; CUDA tile reads also need CuPy and a compatible GPU |
|
BioIO and a reader plugin for your format |
Use OpenSlide or cuCIM for this workflow. BioIO’s whole-level reads currently need correction.
Choose tiles#
threshold, tissue_mask = reader.get_tissue_mask(level=level)
tiles = reader.get_tile_coordinates(
width=256,
tissue_mask=tissue_mask,
overlap=0.25,
out_of_bounds=False,
)
tile = reader.read_region(tiles[0], level=0)
preview = reader.get_annotated_thumbnail(thumbnail, tiles)
properties = tiles.get_properties(
level=0, level_downsample=reader.level_downsamples[0]
)
This assumes at least one tissue tile is found. Pass tissue_mask=None to keep
background tiles. Use a mask spanning the full slide; height and width may use
different scales.
Dimensions use (height, width). Region bounds use (x, y, width, height) in full-resolution pixels, with (0, 0) at the top left. Reading another level reduces the returned image size; keep the region bounds in level-zero pixels.
pixel_size gives physical height and width per level-zero pixel, in micrometers.
Reading pixel_size raises an error if this information is missing.
You can still read tiles without it.
- class SlideReader(path, backend='OPENSLIDE')#
Read slide images, find tissue and choose tiles for prediction.
Open a slide with the selected reader.
- Parameters:
path (Union[str, Path]) – Path to a slide supported by the backend.
backend (str) – “OPENSLIDE”, “CUCIM” or “BIOIO”. Install the chosen reader and its native libraries or format plugins before opening the slide.
- Raises:
FileNotFoundError – The slide path does not exist.
ValueError – The backend name or file suffix is unsupported.
ImportError – The selected reader is not installed.
- property backend_name: str#
OPENSLIDE, CUCIM or BIOIO.
- Type:
Active reader name
- property data_bounds: tuple[int, int, int, int]#
Image-data bounds as (x, y, width, height) in level-zero pixels.
Some formats store tissue in a smaller area than the full image. Region coordinates still refer to the full image origin.
- property dimensions: tuple[int, int]#
Full-resolution slide size as (height, width) in pixels.
- get_annotated_thumbnail(image, coordinates, linewidth=1)#
Draw tile or spot rectangles on a slide overview.
- Parameters:
image (ndarray) – RGB uint8 NumPy overview spanning the full slide.
coordinates (Sequence[tuple[int, int, int, int]] | TileCoordinates | SpotCoordinates) – Level-zero bounds, as a TileCoordinates, SpotCoordinates or a list of (x, y, width, height) tuples.
linewidth (int) – Rectangle line width in overview pixels.
- Returns:
A new PIL image. Spot collections include names; tile collections highlight the first tile. Coordinates are scaled to the overview size.
- Return type:
Image
- get_spot_coordinates(tissue_mask, *, min_area_pixel=10, max_area_pixel=None, min_area_relative=0.2, max_area_relative=2.0)#
Find tissue microarray spots from a tissue mask.
- Parameters:
tissue_mask (ndarray) – 2D uint8 full-slide mask; height and width may use different scales. Use 1 for tissue and 0 for background. Remove artifacts first.
min_area_pixel (int) – Smallest contour area in mask pixels.
max_area_pixel (int | None) – Largest contour area in mask pixels, or None for no limit.
min_area_relative (float) – Smallest area as a fraction of the median area after pixel-area filtering.
max_area_relative (float | None) – Largest area as a multiple of that median, or None.
- Returns:
SpotCoordinates with level-zero bounds, corresponding spot_names and the cleaned mask at its original resolution. Bounds and names have matching order; names describe positions in the detected spot grid.
- Return type:
- get_tile_coordinates(width, *, tissue_mask, height=None, overlap=0.0, max_background=0.95, out_of_bounds=True)#
Choose slide tiles, optionally excluding mostly empty regions.
- Parameters:
width (int) – Tile width in level-zero pixels; no larger than the slide width.
tissue_mask (ndarray | None) – 2D tissue mask spanning the full slide. Height and width may use different scales. Pass None to disable background filtering.
height (int | None) – Tile height in level-zero pixels. None uses width.
overlap (float) – Fraction shared by neighboring tiles, in [0, 1).
max_background (float) – Largest allowed background fraction. Ignored without a tissue mask. Outside-slide pixels count as background.
out_of_bounds (bool) – Keep tiles extending beyond the slide; reads pad those areas.
- Returns:
TileCoordinates with level-zero (x, y, width, height) bounds in row order. An all-background mask can leave the collection empty.
- Raises:
TypeError – Tile dimensions are not integers.
ValueError – Tile dimensions are invalid or overlap is outside [0, 1).
- Return type:
- get_tissue_mask(*, level=None, threshold=None, multiplier=1.05, sigma=0.0)#
Find tissue on a slide image level.
- Parameters:
level (int | None) – Level for detection. None chooses a level with level_from_max_dimension().
threshold (int | None) – Grayscale cutoff from 0 to 255. None chooses it automatically with Otsu’s method. Darker pixels are treated as tissue.
multiplier (float) – Scale the automatic cutoff; ignored with a fixed threshold.
sigma (float) – Blur strength in detection-image pixels; 0 disables blurring.
- Returns:
1 is tissue and 0 is background. The first value is the cutoff, not the image level.
- Return type:
(threshold, mask), with a 2D uint8 mask at the detection image size
- Raises:
ValueError – The threshold or level is invalid.
- property level_count: int#
Number of image levels, from full resolution to smaller images.
- property level_dimensions: dict[int, tuple[int, int]]#
Dictionary mapping each level to its (height, width) in pixels.
- property level_downsamples: dict[int, tuple[float, float]]#
Dictionary mapping each level to its height/width reduction factors.
For example, (2.0, 2.0) means half as many pixels along each axis.
- level_from_dimensions(dimensions)#
Choose the level closest to an image size.
- Parameters:
dimensions (tuple[int, int]) – Desired (height, width) in pixels.
- Returns:
Level with the smallest total difference in height and width. Ties use the first matching level.
- Return type:
int
- level_from_max_dimension(max_dimension=4096)#
Choose a level small enough to fit within the requested size.
- Parameters:
max_dimension (int) – Maximum height and width, in pixels.
- Returns:
First level with both dimensions within the limit, or the smallest available level if none fits.
- Return type:
int
- property name: str#
Slide filename without its final extension.
- property path: str#
Absolute slide file path.
- property pixel_size: tuple[float, float]#
Level-zero pixel size as (height, width) in micrometers.
The two values can differ. They describe physical size, not level downsampling.
- Raises:
ValueError – Calibration is missing, invalid or uses unsupported units.
- read_level(level)#
Read a whole image level into CPU memory.
- Parameters:
level (int) – Image level; 0 is full resolution and -1 is the smallest level.
- Returns:
OpenSlide/CUCIM return an RGB uint8 NumPy image with height, width, channels axes. OpenSlide uses its thumbnail reader, which can return a slightly different image size from the level metadata. A full-resolution read can be large. BIOIO whole-level reading currently needs a separate correction.
- Raises:
ValueError – The requested level is unavailable.
- Return type:
ndarray
- read_region(xywh, level=0, *, device=None)#
Read one rectangular region of the slide.
- Parameters:
xywh (tuple[int, int, int, int]) – (x, y, width, height) bounds in level-zero pixels, even when reading another level. Out-of-image areas are padded with white pixels.
level (int) – Image level to read; 0 gives full resolution.
device (str | torch.device | None) – None returns a CPU NumPy array. A CUDA device is supported only by CUCIM and returns a tensor on that device.
- Returns:
RGB uint8 pixels with height, width, channels axes. Width and height are reduced by the chosen level’s downsample factors.
- Raises:
ValueError – The level or device request is unsupported.
- Return type:
np.ndarray | torch.Tensor
- property suffix: str#
Final file extension, including the dot.
Coordinate collections#
from cellseg_models_pytorch.wsi.data import SpotCoordinates, TileCoordinates
Index or iterate over either collection to get region bounds. Use
tiles.coordinates when passing a list to WsiSegmenter.
- class TileCoordinates(coordinates, width, height, overlap, max_background=None, tissue_mask=None)#
Tile bounds and the settings used to generate them.
Iterate or index this collection to get (x, y, width, height) tuples in level-zero slide pixels. Names and filtering settings are stored separately.
- Parameters:
coordinates (list[tuple[int, int, int, int]]) – Tile bounds in reading order.
width (int) – Tile width in level-zero pixels.
height (int) – Tile height in level-zero pixels.
overlap (float) – Fraction shared by neighboring tiles, from 0 up to but excluding 1.
max_background (float | None) – Largest allowed background fraction, or None if not filtered.
tissue_mask (ndarray | None) – Optional 2D mask used for filtering: 1 is tissue, 0 background.
- __getitem__(index)#
Return the tile bounds at an index; negative indices count from the end.
- Parameters:
index (int)
- Return type:
tuple[int, int, int, int]
- __iter__()#
Iterate over tile bounds in their stored order.
- Return type:
Iterator[tuple[int, int, int, int]]
- __len__()#
Return the number of tile bounds.
- Return type:
int
- get_properties(level, level_downsample)#
Return the tile settings as a dictionary.
- Parameters:
level (int) – Read level to record.
level_downsample (tuple[float, float]) – Height/width downsample factors to record for that level.
- Returns:
Keys num_tiles, level, level_downsample, width, height, overlap and max_background. Width and height keep their level-zero values; this method records the supplied level metadata without changing coordinates.
- Return type:
dict[str, int | float | tuple[float, float] | None]
- cellseg_models_pytorch.wsi.data.TileCoordinates.coordinates#
Tile bounds in reading order, as level-zero (x, y, width, height) tuples.
- cellseg_models_pytorch.wsi.data.TileCoordinates.width#
Tile width in level-zero pixels.
- cellseg_models_pytorch.wsi.data.TileCoordinates.height#
Tile height in level-zero pixels.
- cellseg_models_pytorch.wsi.data.TileCoordinates.overlap#
Fraction shared by neighboring tiles.
- cellseg_models_pytorch.wsi.data.TileCoordinates.max_background#
Largest allowed background fraction, or None when filtering was disabled.
- cellseg_models_pytorch.wsi.data.TileCoordinates.tissue_mask#
Mask used to choose tiles, or None.
For tissue microarrays, detect spots from a cleaned tissue mask:
spots = reader.get_spot_coordinates(tissue_mask)
named_spots = list(zip(spots.spot_names, spots))
Names and bounds have the same order. Iterating over spots returns bounds only.
- class SpotCoordinates(coordinates, spot_names, tissue_mask)#
Detected tissue microarray spots and their names.
Iterate or index this collection to get (x, y, width, height) bounds in level-zero pixels. Iteration returns bounds only; pair them with spot_names when you also need names.
- Parameters:
coordinates (list[tuple[int, int, int, int]]) – One bounding box per spot.
spot_names (list[str]) – Names in the same order as coordinates, such as “spot_1”.
tissue_mask (ndarray) – Cleaned 2D uint8 mask at the detection image size; 1 is tissue.
- __getitem__(index)#
Return the spot bounds at an index; negative indices count from the end.
- Parameters:
index (int)
- Return type:
tuple[int, int, int, int]
- __iter__()#
Iterate over spot bounds; names remain in spot_names.
- Return type:
Iterator[tuple[int, int, int, int]]
- __len__()#
Return the number of spots.
- Return type:
int
- cellseg_models_pytorch.wsi.data.SpotCoordinates.coordinates#
Spot bounds as a list of level-zero (x, y, width, height) tuples.
- cellseg_models_pytorch.wsi.data.SpotCoordinates.spot_names#
Names in the same order as coordinates.
- cellseg_models_pytorch.wsi.data.SpotCoordinates.tissue_mask#
Cleaned tissue mask at its detection resolution.