torch_em.data.datasets.histopathology.khoshdeli

The Khoshdeli dataset contains annotations for nucleus segmentation in H&E stained histopathology images of brain tumor (TCGA) and breast cancer tissue.

The dataset is located at https://doi.org/10.6084/m9.figshare.6944522. This dataset is from the publication https://doi.org/10.1186/s12859-018-2285-0. Please cite it if you use this dataset for your research.

  1"""The Khoshdeli dataset contains annotations for nucleus segmentation in H&E stained
  2histopathology images of brain tumor (TCGA) and breast cancer tissue.
  3
  4The dataset is located at https://doi.org/10.6084/m9.figshare.6944522.
  5This dataset is from the publication https://doi.org/10.1186/s12859-018-2285-0.
  6Please cite it if you use this dataset for your research.
  7"""
  8
  9import os
 10from glob import glob
 11from tqdm import tqdm
 12from natsort import natsorted
 13from typing import Tuple, Union, List
 14
 15import imageio.v3 as imageio
 16from bioimage_cpp.segmentation import label as connected_components
 17
 18from torch.utils.data import Dataset, DataLoader
 19
 20import torch_em
 21
 22from .. import util
 23
 24
 25URL = "https://ndownloader.figshare.com/files/12737267"
 26CHECKSUM = "929db05b0fff9139d25c8119daebe27baf6696bb6cedfc935e6e4d4be75a7620"
 27
 28
 29def get_khoshdeli_data(path: Union[os.PathLike, str], download: bool = False) -> str:
 30    """Download the Khoshdeli dataset.
 31
 32    Args:
 33        path: Filepath to a folder where the downloaded data will be saved.
 34        download: Whether to download the data if it is not present.
 35
 36    Returns:
 37        Filepath where the data is downloaded.
 38    """
 39    data_dir = os.path.join(path, "Nuclear-Segmentation-Data")
 40    if os.path.exists(data_dir):
 41        return data_dir
 42
 43    os.makedirs(path, exist_ok=True)
 44
 45    zip_path = os.path.join(path, "khoshdeli_supplement.zip")
 46    util.download_source(path=zip_path, url=URL, download=download, checksum=CHECKSUM)
 47    util.unzip(zip_path=zip_path, dst=path)
 48
 49    tar_path = os.path.join(path, "12859_2018_2285_MOESM1_ESM", "Nuclear-Segmentation-Data.tar")
 50    util.unzip_tarfile(tar_path=tar_path, dst=path)
 51
 52    return data_dir
 53
 54
 55def get_khoshdeli_paths(path: Union[os.PathLike, str], download: bool = False) -> Tuple[List[str], List[str]]:
 56    """Get paths to the Khoshdeli data.
 57
 58    Args:
 59        path: Filepath to a folder where the downloaded data will be saved.
 60        download: Whether to download the data if it is not present.
 61
 62    Returns:
 63        List of filepaths for the image data.
 64        List of filepaths for the label data.
 65    """
 66    data_dir = get_khoshdeli_data(path, download)
 67
 68    raw_paths = natsorted(glob(os.path.join(data_dir, "Images", "*.bmp")))
 69    mask_paths = natsorted(glob(os.path.join(data_dir, "Masks", "*_MASK.bmp")))
 70    assert len(raw_paths) == len(mask_paths) and len(raw_paths) > 0
 71
 72    label_paths = []
 73    for mpath in tqdm(mask_paths, desc="Preprocessing 'khoshdeli' labels"):
 74        label_path = mpath.replace("_MASK.bmp", "_instances.tif")
 75        label_paths.append(label_path)
 76        if os.path.exists(label_path):
 77            continue
 78
 79        mask = imageio.imread(mpath) > 0
 80        label = connected_components(mask)  # run connected components to derive nucleus instances.
 81        imageio.imwrite(label_path, label, compression="zlib")
 82
 83    return raw_paths, label_paths
 84
 85
 86def get_khoshdeli_dataset(
 87    path: Union[os.PathLike, str],
 88    patch_shape: Tuple[int, int],
 89    resize_inputs: bool = False,
 90    download: bool = False,
 91    **kwargs
 92) -> Dataset:
 93    """Get the Khoshdeli dataset for nucleus segmentation.
 94
 95    Args:
 96        path: Filepath to a folder where the downloaded data will be saved.
 97        patch_shape: The patch shape to use for training.
 98        resize_inputs: Whether to resize the inputs.
 99        download: Whether to download the data if it is not present.
100        kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset`.
101
102    Returns:
103        The segmentation dataset.
104    """
105    raw_paths, label_paths = get_khoshdeli_paths(path, download)
106
107    if resize_inputs:
108        resize_kwargs = {"patch_shape": patch_shape, "is_rgb": True}
109        kwargs, patch_shape = util.update_kwargs_for_resize_trafo(
110            kwargs=kwargs, patch_shape=patch_shape, resize_inputs=resize_inputs, resize_kwargs=resize_kwargs
111        )
112
113    return torch_em.default_segmentation_dataset(
114        raw_paths=raw_paths,
115        raw_key=None,
116        label_paths=label_paths,
117        label_key=None,
118        is_seg_dataset=False,
119        patch_shape=patch_shape,
120        ndim=2,
121        with_channels=True,
122        **kwargs
123    )
124
125
126def get_khoshdeli_loader(
127    path: Union[os.PathLike, str],
128    batch_size: int,
129    patch_shape: Tuple[int, int],
130    resize_inputs: bool = False,
131    download: bool = False,
132    **kwargs
133) -> DataLoader:
134    """Get the Khoshdeli dataloader for nucleus segmentation.
135
136    Args:
137        path: Filepath to a folder where the downloaded data will be saved.
138        batch_size: The batch size for training.
139        patch_shape: The patch shape to use for training.
140        resize_inputs: Whether to resize the inputs.
141        download: Whether to download the data if it is not present.
142        kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset` or for the PyTorch DataLoader.
143
144    Returns:
145        The DataLoader.
146    """
147    ds_kwargs, loader_kwargs = util.split_kwargs(torch_em.default_segmentation_dataset, **kwargs)
148    dataset = get_khoshdeli_dataset(path, patch_shape, resize_inputs, download, **ds_kwargs)
149    return torch_em.get_data_loader(dataset, batch_size, **loader_kwargs)
URL = 'https://ndownloader.figshare.com/files/12737267'
CHECKSUM = '929db05b0fff9139d25c8119daebe27baf6696bb6cedfc935e6e4d4be75a7620'
def get_khoshdeli_data(path: Union[os.PathLike, str], download: bool = False) -> str:
30def get_khoshdeli_data(path: Union[os.PathLike, str], download: bool = False) -> str:
31    """Download the Khoshdeli dataset.
32
33    Args:
34        path: Filepath to a folder where the downloaded data will be saved.
35        download: Whether to download the data if it is not present.
36
37    Returns:
38        Filepath where the data is downloaded.
39    """
40    data_dir = os.path.join(path, "Nuclear-Segmentation-Data")
41    if os.path.exists(data_dir):
42        return data_dir
43
44    os.makedirs(path, exist_ok=True)
45
46    zip_path = os.path.join(path, "khoshdeli_supplement.zip")
47    util.download_source(path=zip_path, url=URL, download=download, checksum=CHECKSUM)
48    util.unzip(zip_path=zip_path, dst=path)
49
50    tar_path = os.path.join(path, "12859_2018_2285_MOESM1_ESM", "Nuclear-Segmentation-Data.tar")
51    util.unzip_tarfile(tar_path=tar_path, dst=path)
52
53    return data_dir

Download the Khoshdeli dataset.

Arguments:
  • path: Filepath to a folder where the downloaded data will be saved.
  • download: Whether to download the data if it is not present.
Returns:

Filepath where the data is downloaded.

def get_khoshdeli_paths( path: Union[os.PathLike, str], download: bool = False) -> Tuple[List[str], List[str]]:
56def get_khoshdeli_paths(path: Union[os.PathLike, str], download: bool = False) -> Tuple[List[str], List[str]]:
57    """Get paths to the Khoshdeli data.
58
59    Args:
60        path: Filepath to a folder where the downloaded data will be saved.
61        download: Whether to download the data if it is not present.
62
63    Returns:
64        List of filepaths for the image data.
65        List of filepaths for the label data.
66    """
67    data_dir = get_khoshdeli_data(path, download)
68
69    raw_paths = natsorted(glob(os.path.join(data_dir, "Images", "*.bmp")))
70    mask_paths = natsorted(glob(os.path.join(data_dir, "Masks", "*_MASK.bmp")))
71    assert len(raw_paths) == len(mask_paths) and len(raw_paths) > 0
72
73    label_paths = []
74    for mpath in tqdm(mask_paths, desc="Preprocessing 'khoshdeli' labels"):
75        label_path = mpath.replace("_MASK.bmp", "_instances.tif")
76        label_paths.append(label_path)
77        if os.path.exists(label_path):
78            continue
79
80        mask = imageio.imread(mpath) > 0
81        label = connected_components(mask)  # run connected components to derive nucleus instances.
82        imageio.imwrite(label_path, label, compression="zlib")
83
84    return raw_paths, label_paths

Get paths to the Khoshdeli data.

Arguments:
  • path: Filepath to a folder where the downloaded data will be saved.
  • download: Whether to download the data if it is not present.
Returns:

List of filepaths for the image data. List of filepaths for the label data.

def get_khoshdeli_dataset( path: Union[os.PathLike, str], patch_shape: Tuple[int, int], resize_inputs: bool = False, download: bool = False, **kwargs) -> torch.utils.data.dataset.Dataset:
 87def get_khoshdeli_dataset(
 88    path: Union[os.PathLike, str],
 89    patch_shape: Tuple[int, int],
 90    resize_inputs: bool = False,
 91    download: bool = False,
 92    **kwargs
 93) -> Dataset:
 94    """Get the Khoshdeli dataset for nucleus segmentation.
 95
 96    Args:
 97        path: Filepath to a folder where the downloaded data will be saved.
 98        patch_shape: The patch shape to use for training.
 99        resize_inputs: Whether to resize the inputs.
100        download: Whether to download the data if it is not present.
101        kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset`.
102
103    Returns:
104        The segmentation dataset.
105    """
106    raw_paths, label_paths = get_khoshdeli_paths(path, download)
107
108    if resize_inputs:
109        resize_kwargs = {"patch_shape": patch_shape, "is_rgb": True}
110        kwargs, patch_shape = util.update_kwargs_for_resize_trafo(
111            kwargs=kwargs, patch_shape=patch_shape, resize_inputs=resize_inputs, resize_kwargs=resize_kwargs
112        )
113
114    return torch_em.default_segmentation_dataset(
115        raw_paths=raw_paths,
116        raw_key=None,
117        label_paths=label_paths,
118        label_key=None,
119        is_seg_dataset=False,
120        patch_shape=patch_shape,
121        ndim=2,
122        with_channels=True,
123        **kwargs
124    )

Get the Khoshdeli dataset for nucleus segmentation.

Arguments:
  • path: Filepath to a folder where the downloaded data will be saved.
  • patch_shape: The patch shape to use for training.
  • resize_inputs: Whether to resize the inputs.
  • download: Whether to download the data if it is not present.
  • kwargs: Additional keyword arguments for torch_em.default_segmentation_dataset.
Returns:

The segmentation dataset.

def get_khoshdeli_loader( path: Union[os.PathLike, str], batch_size: int, patch_shape: Tuple[int, int], resize_inputs: bool = False, download: bool = False, **kwargs) -> torch.utils.data.dataloader.DataLoader:
127def get_khoshdeli_loader(
128    path: Union[os.PathLike, str],
129    batch_size: int,
130    patch_shape: Tuple[int, int],
131    resize_inputs: bool = False,
132    download: bool = False,
133    **kwargs
134) -> DataLoader:
135    """Get the Khoshdeli dataloader for nucleus segmentation.
136
137    Args:
138        path: Filepath to a folder where the downloaded data will be saved.
139        batch_size: The batch size for training.
140        patch_shape: The patch shape to use for training.
141        resize_inputs: Whether to resize the inputs.
142        download: Whether to download the data if it is not present.
143        kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset` or for the PyTorch DataLoader.
144
145    Returns:
146        The DataLoader.
147    """
148    ds_kwargs, loader_kwargs = util.split_kwargs(torch_em.default_segmentation_dataset, **kwargs)
149    dataset = get_khoshdeli_dataset(path, patch_shape, resize_inputs, download, **ds_kwargs)
150    return torch_em.get_data_loader(dataset, batch_size, **loader_kwargs)

Get the Khoshdeli dataloader for nucleus segmentation.

Arguments:
  • path: Filepath to a folder where the downloaded data will be saved.
  • batch_size: The batch size for training.
  • patch_shape: The patch shape to use for training.
  • resize_inputs: Whether to resize the inputs.
  • download: Whether to download the data if it is not present.
  • kwargs: Additional keyword arguments for torch_em.default_segmentation_dataset or for the PyTorch DataLoader.
Returns:

The DataLoader.