Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/pythonapp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ jobs:
python -m pip install torch==1.8.0+cpu torchvision==0.9.0+cpu -f https://download.pytorch.org/whl/torch_stable.html
# min. requirements for windows instances
python -c "f=open('requirements-dev.txt', 'r'); txt=f.readlines(); f.close(); print(txt); f=open('requirements-dev.txt', 'w'); f.writelines(txt[1:12]); f.close()"
- if: runner.os == 'macos'
name: Remove cucim installation (Mac only)
run: |
python -c "f=open('requirements-dev.txt', 'r'); txt=f.readlines(); f.close(); print(txt); f=open('requirements-dev.txt', 'w'); f.writelines([t for t in txt if not t.startswith('cucim')]); f.close()"
- name: Install the dependencies
run: |
python -m pip install torch==1.8.0 torchvision==0.9.0
Expand Down
1 change: 1 addition & 0 deletions docs/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pytorch-ignite==0.4.4
numpy>=1.17
itk>=5.0
nibabel
cucim==0.18.0
openslide-python==1.1.2
parameterized
scikit-image>=0.14.2
Expand Down
21 changes: 10 additions & 11 deletions monai/data/image_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,22 @@
from .utils import is_supported_format

if TYPE_CHECKING:
import cuimage
import cucim
import itk # type: ignore
import nibabel as nib
import openslide
from itk import Image # type: ignore
from nibabel.nifti1 import Nifti1Image
from PIL import Image as PILImage

has_itk = has_nib = has_pil = has_cux = has_osl = True
has_itk = has_nib = has_pil = has_cim = has_osl = True
else:
itk, has_itk = optional_import("itk", allow_namespace_pkg=True)
Image, _ = optional_import("itk", allow_namespace_pkg=True, name="Image")
nib, has_nib = optional_import("nibabel")
Nifti1Image, _ = optional_import("nibabel.nifti1", name="Nifti1Image")
PILImage, has_pil = optional_import("PIL.Image")
cuimage, has_cux = optional_import("cuimage")
cucim, has_cim = optional_import("cucim")
openslide, has_osl = optional_import("openslide")

__all__ = ["ImageReader", "ITKReader", "NibabelReader", "NumpyReader", "PILReader", "WSIReader"]
Expand Down Expand Up @@ -638,8 +638,7 @@ class WSIReader(ImageReader):
Read whole slide imaging and extract patches.

Args:
reader_lib: backend library to load the images, available options: "OpenSlide" or "cuClaraImage".
TODO: `cuClaraImage` package is unavailable so far, will enable the support later.
reader_lib: backend library to load the images, available options: "OpenSlide" or "cuCIM".

"""

Expand All @@ -649,11 +648,11 @@ def __init__(self, reader_lib: str = "OpenSlide"):
if self.reader_lib == "openslide":
if has_osl:
self.wsi_reader = openslide.OpenSlide
elif self.reader_lib == "cuclaraimage":
if has_cux:
self.wsi_reader = cuimage.CuImage
elif self.reader_lib == "cucim":
if has_cim:
self.wsi_reader = cucim.CuImage
else:
raise ValueError('`reader_lib` should be either "cuClaraImage" or "OpenSlide"')
raise ValueError('`reader_lib` should be either "cuCIM" or "OpenSlide"')

def verify_suffix(self, filename: Union[Sequence[str], str]) -> bool:
"""
Expand All @@ -676,8 +675,8 @@ def read(self, data: Union[Sequence[str], str, np.ndarray], **kwargs):
"""
if (self.reader_lib == "openslide") and (not has_osl):
raise ImportError("No module named 'openslide'")
elif (self.reader_lib == "cuclaraimage") and (not has_cux):
raise ImportError("No module named 'cuimage'")
elif (self.reader_lib == "cucim") and (not has_cim):
raise ImportError("No module named 'cucim'")

img_: List = []

Expand Down
1 change: 1 addition & 0 deletions requirements-dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,5 @@ Sphinx==3.3.0
recommonmark==0.6.0
sphinx-autodoc-typehints==1.11.1
sphinx-rtd-theme==0.5.0
cucim==0.18.0
openslide-python==1.1.2
3 changes: 3 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ all =
torchvision
itk>=5.0
tqdm>=4.47.0
cucim==0.18.0
openslide-python==1.1.2
nibabel =
nibabel
Expand All @@ -55,6 +56,8 @@ lmdb =
lmdb
psutil =
psutil
cucim =
cucim==0.18.0
openslide =
openslide-python==1.1.2

Expand Down
16 changes: 8 additions & 8 deletions tests/test_cuimage_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from monai.data.image_reader import WSIReader
from monai.utils import optional_import

_, has_cui = optional_import("cuimage")
_, has_cim = optional_import("cucim")


FILE_URL = "http://openslide.cs.cmu.edu/download/openslide-testdata/Generic-TIFF/CMU-1.tiff"
Expand Down Expand Up @@ -61,31 +61,31 @@
]


class TestCuClaraImageReader(unittest.TestCase):
class TestCuCIMReader(unittest.TestCase):
@parameterized.expand([TEST_CASE_0])
@skipUnless(has_cui, "Requires CuClaraImage")
@skipUnless(has_cim, "Requires CuCIM")
def test_read_whole_image(self, file_url, expected_shape):
filename = self.camelyon_data_download(file_url)
reader = WSIReader("CuClaraImage")
reader = WSIReader("cuCIM")
img_obj = reader.read(filename)
img = reader.get_data(img_obj)[0]
self.assertTupleEqual(img.shape, expected_shape)

@parameterized.expand([TEST_CASE_1, TEST_CASE_2])
@skipUnless(has_cui, "Requires CuClaraImage")
@skipUnless(has_cim, "Requires cuCIM")
def test_read_region(self, file_url, patch_info, expected_img):
filename = self.camelyon_data_download(file_url)
reader = WSIReader("CuClaraImage")
reader = WSIReader("cuCIM")
img_obj = reader.read(filename)
img = reader.get_data(img_obj, **patch_info)[0]
self.assertTupleEqual(img.shape, expected_img.shape)
self.assertIsNone(assert_array_equal(img, expected_img))

@parameterized.expand([TEST_CASE_3, TEST_CASE_4])
@skipUnless(has_cui, "Requires CuClaraImage")
@skipUnless(has_cim, "Requires cuCIM")
def test_read_patches(self, file_url, patch_info, expected_img):
filename = self.camelyon_data_download(file_url)
reader = WSIReader("CuClaraImage")
reader = WSIReader("cuCIM")
img_obj = reader.read(filename)
img = reader.get_data(img_obj, **patch_info)[0]
self.assertTupleEqual(img.shape, expected_img.shape)
Expand Down