Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

3600 Apply unused kwargs for 3rd party APIs in WSIReader #3601

Merged
merged 11 commits into from
Jan 7, 2022
18 changes: 16 additions & 2 deletions monai/data/image_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -711,20 +711,26 @@ class WSIReader(ImageReader):
backend: backend library to load the images, available options: "cuCIM", "OpenSlide" and "TiffFile".
level: the whole slide image level at which the image is extracted. (default=0)
This is overridden if the level argument is provided in `get_data`.
kwargs: additional args for backend reading API in `read()`, more details in `cuCIM`, `TiffFile`, `OpenSlide`:
https://github.com/rapidsai/cucim/blob/v21.12.00/cpp/include/cucim/cuimage.h#L100.
https://scikit-image.org/docs/0.14.x/api/skimage.external.tifffile.html#skimage.external.tifffile.TiffFile.
Nic-Ma marked this conversation as resolved.
Show resolved Hide resolved
https://openslide.org/api/python/#openslide.OpenSlide.

Note:
While "cuCIM" and "OpenSlide" backends both can load patches from large whole slide images
without loading the entire image into memory, "TiffFile" backend needs to load the entire image into memory
before extracting any patch; thus, memory consideration is needed when using "TiffFile" backend for
patch extraction.

"""

def __init__(self, backend: str = "OpenSlide", level: int = 0):
def __init__(self, backend: str = "OpenSlide", level: int = 0, **kwargs):
super().__init__()
self.backend = backend.lower()
func = require_pkg(self.backend)(self._set_reader)
self.wsi_reader = func(self.backend)
self.level = level
self.kwargs = kwargs

@staticmethod
def _set_reader(backend: str):
Expand Down Expand Up @@ -752,6 +758,12 @@ def read(self, data: Union[Sequence[PathLike], PathLike, np.ndarray], **kwargs):

Args:
data: file name or a list of file names to read.
kwargs: additional args for backend reading API in `read()`, will override `self.kwargs` for existing keys.
more details in `cuCIM`, `TiffFile`, `OpenSlide`:
https://github.com/rapidsai/cucim/blob/v21.12.00/cpp/include/cucim/cuimage.h#L100.
https://scikit-image.org/docs/0.14.x/api/skimage.external.tifffile.html
#skimage.external.tifffile.TiffFile.
https://openslide.org/api/python/#openslide.OpenSlide.

Returns:
image object or list of image objects
Expand All @@ -760,8 +772,10 @@ def read(self, data: Union[Sequence[PathLike], PathLike, np.ndarray], **kwargs):
img_: List = []

filenames: Sequence[PathLike] = ensure_tuple(data)
kwargs_ = self.kwargs.copy()
kwargs_.update(kwargs)
for name in filenames:
img = self.wsi_reader(name)
img = self.wsi_reader(name, **kwargs_)
if self.backend == "openslide":
img.shape = (img.dimensions[1], img.dimensions[0], 3)
img_.append(img)
Expand Down
5 changes: 3 additions & 2 deletions tests/test_wsireader.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,9 @@ def test_read_whole_image(self, file_path, level, expected_shape):

@parameterized.expand([TEST_CASE_1, TEST_CASE_2, TEST_CASE_5])
def test_read_region(self, file_path, patch_info, expected_img):
reader = WSIReader(self.backend)
with reader.read(file_path) as img_obj:
kwargs = {"name": None, "offset": None} if self.backend == "tifffile" else {}
reader = WSIReader(self.backend, **kwargs)
with reader.read(file_path, **kwargs) as img_obj:
if self.backend == "tifffile":
with self.assertRaises(ValueError):
reader.get_data(img_obj, **patch_info)[0]
Expand Down