Source code for cellmil.data.cucim_deepzoom

# -*- coding: utf-8 -*-
# Support for Deep Zoom images.
#
# This module provides functionality for generating Deep Zoom images from
# CuImage objects
#
# References:
# CellViT: Vision Transformers for precise cell segmentation and classification
# Fabian Hörst et al., Medical Image Analysis, 2024
# DOI: https://doi.org/10.1016/j.media.2024.103143

import numpy as np
from cucim import CuImage  # type: ignore
from cucim.clara.cache import preferred_memory_capacity  # type: ignore
from openslide import OpenSlide
from openslide.deepzoom import DeepZoomGenerator
from PIL import Image
from typing import Any, cast


[docs]class DeepZoomGeneratorCucim(DeepZoomGenerator): """Create a DeepZoomGenerator, but instead of utilizing OpenSlide, use cucim to read regions. Args: osr (OpenSlide): OpenSlide Image. Needed for OS compatibility and for retrieving metadata. cucim_slide (CuImage): CuImage slide. Used for retrieving image data. tile_size (int, optional): the width and height of a single tile. For best viewer performance, tile_size + 2 * overlap should be a power of two. Defaults to 254. overlap (int, optional): the number of extra pixels to add to each interior edge of a tile. Defaults to 1. limit_bounds (bool, optional): True to render only the non-empty slide region. Defaults to False. """
[docs] def __init__( self, osr: OpenSlide, cucim_slide: Any, tile_size: int = 254, overlap: int = 1, limit_bounds: bool = False, ): super().__init__(osr, tile_size, overlap, limit_bounds) self._cucim_slide = cucim_slide self.memory_capacity = cast( Any, preferred_memory_capacity( self._cucim_slide, patch_size=(tile_size, tile_size) ), ) self.cache = CuImage.cache( # type: ignore "per_process", memory_capacity=self.memory_capacity, record_stat=True )
[docs] def get_tile(self, level: int, address: tuple[int, int]) -> Image.Image: """Return an RGB PIL.Image for a tile. Args: level (int): the Deep Zoom level address (tuple[int, int]): the address of the tile within the level as a (col, row) tuple Returns: Image.Image: PIL Image """ args, z_size = self._get_tile_info(level, address) tile = self._cucim_slide.read_region( location=args[0], level=args[1], size=args[2], ) tile = Image.fromarray(np.array(tile), mode="RGB") # CuImage is RGB # Scale to the correct size if tile.size != z_size: # Image.Resampling added in Pillow 9.1.0 # Image.LANCZOS removed in Pillow 10 tile.thumbnail( z_size, getattr(Image, "Resampling", Image).LANCZOS, # type: ignore ) return tile