From 3c2f72022e42fce03d4f6ce56594e2c64cf0e19c Mon Sep 17 00:00:00 2001 From: Behrooz <3968947+drbeh@users.noreply.github.com> Date: Tue, 2 Nov 2021 12:37:14 +0000 Subject: [PATCH 1/4] Add level argument to __init__ for WSIReader Signed-off-by: Behrooz <3968947+drbeh@users.noreply.github.com> --- monai/data/image_reader.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/monai/data/image_reader.py b/monai/data/image_reader.py index 622a4865d1..097f1b44f0 100644 --- a/monai/data/image_reader.py +++ b/monai/data/image_reader.py @@ -672,7 +672,7 @@ class WSIReader(ImageReader): """ - def __init__(self, reader_lib: str = "OpenSlide"): + def __init__(self, reader_lib: str = "OpenSlide", level: int = 0): super().__init__() self.reader_lib = reader_lib.lower() if self.reader_lib == "openslide": @@ -681,6 +681,7 @@ def __init__(self, reader_lib: str = "OpenSlide"): self.wsi_reader, *_ = optional_import("cucim", name="CuImage") else: raise ValueError('`reader_lib` should be either "cuCIM" or "OpenSlide"') + self.level = level def verify_suffix(self, filename: Union[Sequence[str], str]) -> bool: """ @@ -695,11 +696,13 @@ def verify_suffix(self, filename: Union[Sequence[str], str]) -> bool: def read(self, data: Union[Sequence[str], str, np.ndarray], **kwargs): """ Read image data from specified file or files. - Note that the returned object is CuImage or list of CuImage objects. Args: data: file name or a list of file names to read. + Returns: + image object or list of image objects + """ img_: List = [] @@ -717,7 +720,7 @@ def get_data( img, location: Tuple[int, int] = (0, 0), size: Optional[Tuple[int, int]] = None, - level: int = 0, + level: Optional[int] = None, dtype: DtypeLike = np.uint8, grid_shape: Tuple[int, int] = (1, 1), patch_size: Optional[Union[int, Tuple[int, int]]] = None, @@ -736,6 +739,8 @@ def get_data( grid_shape: (row, columns) tuple define a grid to extract patches on that patch_size: (height, width) the size of extracted patches at the given level """ + if level is None: + level = self.level if self.reader_lib == "openslide" and size is None: # the maximum size is set to WxH From 8c5522ab8c26c54b19ae9f53b389735d0faef259 Mon Sep 17 00:00:00 2001 From: Behrooz <3968947+drbeh@users.noreply.github.com> Date: Tue, 2 Nov 2021 12:39:29 +0000 Subject: [PATCH 2/4] Change reader_lib to backend Signed-off-by: Behrooz <3968947+drbeh@users.noreply.github.com> --- monai/data/image_reader.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/monai/data/image_reader.py b/monai/data/image_reader.py index 097f1b44f0..ac91a0f00a 100644 --- a/monai/data/image_reader.py +++ b/monai/data/image_reader.py @@ -668,19 +668,19 @@ class WSIReader(ImageReader): Read whole slide imaging and extract patches. Args: - reader_lib: backend library to load the images, available options: "OpenSlide" or "cuCIM". + backend: backend library to load the images, available options: "OpenSlide" or "cuCIM". """ - def __init__(self, reader_lib: str = "OpenSlide", level: int = 0): + def __init__(self, backend: str = "OpenSlide", level: int = 0): super().__init__() - self.reader_lib = reader_lib.lower() - if self.reader_lib == "openslide": + self.backend = backend.lower() + if self.backend == "openslide": self.wsi_reader, *_ = optional_import("openslide", name="OpenSlide") - elif self.reader_lib == "cucim": + elif self.backend == "cucim": self.wsi_reader, *_ = optional_import("cucim", name="CuImage") else: - raise ValueError('`reader_lib` should be either "cuCIM" or "OpenSlide"') + raise ValueError('`backend` should be either "cuCIM" or "OpenSlide"') self.level = level def verify_suffix(self, filename: Union[Sequence[str], str]) -> bool: @@ -709,7 +709,7 @@ def read(self, data: Union[Sequence[str], str, np.ndarray], **kwargs): filenames: Sequence[str] = ensure_tuple(data) for name in filenames: img = self.wsi_reader(name) - if self.reader_lib == "openslide": + if self.backend == "openslide": img.shape = (img.dimensions[1], img.dimensions[0], 3) img_.append(img) @@ -742,7 +742,7 @@ def get_data( if level is None: level = self.level - if self.reader_lib == "openslide" and size is None: + if self.backend == "openslide" and size is None: # the maximum size is set to WxH size = (img.shape[0] // (2 ** level) - location[0], img.shape[1] // (2 ** level) - location[1]) @@ -783,7 +783,7 @@ def _extract_region( def convert_to_rgb_array(self, raw_region, dtype: DtypeLike = np.uint8): """Convert to RGB mode and numpy array""" - if self.reader_lib == "openslide": + if self.backend == "openslide": # convert to RGB raw_region = raw_region.convert("RGB") # convert to numpy From 7c0e6a4db66d9fecda031ffebda16e559cad3639 Mon Sep 17 00:00:00 2001 From: Behrooz <3968947+drbeh@users.noreply.github.com> Date: Tue, 2 Nov 2021 12:54:40 +0000 Subject: [PATCH 3/4] Update some comments Signed-off-by: Behrooz <3968947+drbeh@users.noreply.github.com> --- monai/data/image_reader.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/monai/data/image_reader.py b/monai/data/image_reader.py index ac91a0f00a..21b0364bb4 100644 --- a/monai/data/image_reader.py +++ b/monai/data/image_reader.py @@ -665,7 +665,7 @@ def _get_spatial_shape(self, img): class WSIReader(ImageReader): """ - Read whole slide imaging and extract patches. + Read whole slide images and extract patches. Args: backend: backend library to load the images, available options: "OpenSlide" or "cuCIM". @@ -695,7 +695,7 @@ def verify_suffix(self, filename: Union[Sequence[str], str]) -> bool: def read(self, data: Union[Sequence[str], str, np.ndarray], **kwargs): """ - Read image data from specified file or files. + Read image data from given file or list of files. Args: data: file name or a list of file names to read. @@ -743,7 +743,7 @@ def get_data( level = self.level if self.backend == "openslide" and size is None: - # the maximum size is set to WxH + # the maximum size is set to WxH at the specified level size = (img.shape[0] // (2 ** level) - location[0], img.shape[1] // (2 ** level) - location[1]) region = self._extract_region(img, location=location, size=size, level=level, dtype=dtype) From 7e0dbcfa203111ebf7febac92b3dba6179f4063d Mon Sep 17 00:00:00 2001 From: Behrooz <3968947+drbeh@users.noreply.github.com> Date: Tue, 2 Nov 2021 14:28:01 +0000 Subject: [PATCH 4/4] Update docstring Signed-off-by: Behrooz <3968947+drbeh@users.noreply.github.com> --- monai/data/image_reader.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/monai/data/image_reader.py b/monai/data/image_reader.py index 21b0364bb4..a4ca34dae3 100644 --- a/monai/data/image_reader.py +++ b/monai/data/image_reader.py @@ -669,6 +669,8 @@ class WSIReader(ImageReader): Args: backend: backend library to load the images, available options: "OpenSlide" or "cuCIM". + level: the whole slide image level at which the image is extracted. (default=0) + Note that this is overridden by the level argument in `get_data`. """