torch_em.data.datasets.histopathology.deepliif

DeepLIIF contains annotations for nucleus segmentation and classification in IHC images of lung, bladder and breast cancer tissue.

The lung and bladder tissue shares one archive per split. The breast cancer tissue, which is stained for Ki67, stems from an earlier release of the data and has its own archives. It only covers the train and the val split.

Every image comes as six 512x512 panels of the same region, which are stitched next to each other: the IHC input, the hematoxylin channel and the multiplex immunofluorescence modalities (mpIF DAPI, mpIF Lap2 and the mpIF marker), followed by the segmentation mask. The mask marks cells with positive protein expression in red and negative cells in blue. A green boundary surrounds each cell, so that this module can separate touching cells and derive instance labels from the mask. NOTE: The labels keep every cell of the mask. A few cells are only a few pixels large, since saving the masks as png introduced compression artifacts. NOTE: The segmentations align with the mpIF DAPI channel. They are slightly misaligned with all other modalities.

The data is hosted at https://zenodo.org/records/4751737 and licensed under CC-BY-4.0. This dataset is from the publication https://doi.org/10.1038/s42256-022-00471-x. Please cite it if you use this dataset for your research.

  1"""DeepLIIF contains annotations for nucleus segmentation and classification in IHC images
  2of lung, bladder and breast cancer tissue.
  3
  4The lung and bladder tissue shares one archive per split. The breast cancer tissue, which is
  5stained for Ki67, stems from an earlier release of the data and has its own archives. It only
  6covers the train and the val split.
  7
  8Every image comes as six 512x512 panels of the same region, which are stitched next to each other:
  9the IHC input, the hematoxylin channel and the multiplex immunofluorescence modalities
 10(mpIF DAPI, mpIF Lap2 and the mpIF marker), followed by the segmentation mask.
 11The mask marks cells with positive protein expression in red and negative cells in blue.
 12A green boundary surrounds each cell, so that this module can separate touching cells
 13and derive instance labels from the mask.
 14NOTE: The labels keep every cell of the mask. A few cells are only a few pixels large,
 15since saving the masks as png introduced compression artifacts.
 16NOTE: The segmentations align with the mpIF DAPI channel. They are slightly misaligned with
 17all other modalities.
 18
 19The data is hosted at https://zenodo.org/records/4751737 and licensed under CC-BY-4.0.
 20This dataset is from the publication https://doi.org/10.1038/s42256-022-00471-x.
 21Please cite it if you use this dataset for your research.
 22"""
 23
 24import os
 25from glob import glob
 26from natsort import natsorted
 27from typing import Union, Tuple, List, Literal, Optional
 28
 29import numpy as np
 30import imageio.v3 as imageio
 31from skimage.measure import label as connected_components
 32from skimage.segmentation import watershed, find_boundaries, relabel_sequential
 33
 34from torch.utils.data import Dataset, DataLoader
 35
 36import torch_em
 37
 38from .. import util
 39
 40
 41URL = "https://zenodo.org/records/4751737/files/{filename}?download=1"
 42
 43# The lung and bladder tissue shares one archive per split, the breast cancer tissue has its own.
 44FILENAMES = {
 45    ("lung_bladder", "train"): "DeepLIIF_Training_Set.zip",
 46    ("lung_bladder", "val"): "DeepLIIF_Validation_Set.zip",
 47    ("lung_bladder", "test"): "DeepLIIF_Testing_Set.zip",
 48    ("breast", "train"): "BC-DeepLIIF_Training_Set.zip",
 49    ("breast", "val"): "BC-DeepLIIF_Validation_Set.zip",
 50}
 51
 52CHECKSUMS = {
 53    ("lung_bladder", "train"): "704b75ad9d15d5c5ffda8c48a53a7037544208bbcb7a1f3bbb2b1ce9c4f63d02",
 54    ("lung_bladder", "val"): "e8dcec56d4cb44a7037170060e39ec503ba3b70f817abd00cb36fb86eb4e7e1a",
 55    ("lung_bladder", "test"): "7663611b1274049b677dd18deee8fbd1e44370884ec1f4d8d7196924d2a7acec",
 56    ("breast", "train"): "598bef02f1dcc54f888976ad5ed267e1672816e9326c2011a35c68d5b0167d8e",
 57    ("breast", "val"): "349278854a95b0a31790e81acd21f87c7afaa8f3641ce5fb4c47b09987e45b23",
 58}
 59
 60SPLITS = ["train", "val", "test"]
 61
 62TISSUES = ["lung", "bladder", "breast"]
 63
 64# The lung and bladder images carry their tissue in the filename, the breast cancer images do not.
 65FILE_PREFIXES = {"lung": "Lung_", "bladder": "Bladder_"}
 66
 67# The image panels, in the order in which they are stitched together. The mask follows them.
 68MODALITIES = ["ihc", "hematoxylin", "dapi", "lap2", "marker"]
 69
 70# Half of the boundary that the mask draws around each cell, measured per archive. The watershed
 71# grows the cells over the full boundary, so shrinking them by this puts their edge in its middle.
 72EROSION = {"lung_bladder": 2, "breast": 3}
 73
 74
 75def _get_archive(tissue, split):
 76    """Map a tissue to the archive that holds it for a split."""
 77    key = ("breast" if tissue == "breast" else "lung_bladder", split)
 78    if key not in FILENAMES:
 79        raise ValueError(f"The '{tissue}' tissue has no '{split}' split.")
 80    return key
 81
 82
 83def _get_labels(mask, n_erode):
 84    """Derive the instance and the semantic labels from the segmentation panel.
 85
 86    The panel paints cells with positive expression red and negative cells blue, and draws a
 87    green boundary around every cell. The cell interiors are separate already, so they seed a
 88    watershed that grows them back over the boundary. This recovers the full extent of a cell,
 89    which taking the interiors alone would shrink by the width of the boundary. Eroding the
 90    result afterwards moves the edge of a cell from the outside of the boundary to its middle.
 91
 92    The class of a cell follows from the color of its interior, so that the semantic labels
 93    and the instances agree on where a cell ends.
 94    """
 95    positive, negative = mask[..., 0] > 127, mask[..., 2] > 127
 96    interior = positive | negative
 97    foreground = interior | (mask[..., 1] > 127)
 98
 99    seeds = connected_components(interior)
100    instances = watershed(mask[..., 1], markers=seeds, mask=foreground)
101
102    # Erode every cell on its own, so that cells which touch stay apart.
103    for _ in range(n_erode):
104        instances[find_boundaries(instances, mode="inner")] = 0
105
106    # The erosion removes the smallest cells, so make the labels consecutive again.
107    instances = relabel_sequential(instances)[0].astype("uint16")
108
109    # A cell is positive if its interior holds more red than blue pixels.
110    n_labels = int(instances.max()) + 1
111    n_positive = np.bincount(instances[positive], minlength=n_labels)
112    n_negative = np.bincount(instances[negative], minlength=n_labels)
113
114    classes = np.where(n_positive >= n_negative, 2, 1).astype("uint8")
115    classes[(n_positive + n_negative) == 0] = 0
116    classes[0] = 0
117    semantic = classes[instances]
118
119    return instances, semantic
120
121
122def _preprocess_data(input_dir, data_dir, n_erode):
123    import h5py
124
125    os.makedirs(data_dir, exist_ok=True)
126    image_paths = natsorted(glob(os.path.join(input_dir, "*.png")))
127    if not image_paths:
128        raise RuntimeError(f"Could not find the images in {input_dir}.")
129
130    for image_path in image_paths:
131        fname = os.path.splitext(os.path.basename(image_path))[0]
132        out_path = os.path.join(data_dir, f"{fname}.h5")
133        if os.path.exists(out_path):
134            continue
135
136        panels = np.split(imageio.imread(image_path)[..., :3], len(MODALITIES) + 1, axis=1)
137        instances, semantic = _get_labels(panels[-1], n_erode)
138
139        with h5py.File(out_path, "a") as f:
140            for modality, panel in zip(MODALITIES, panels):
141                f.create_dataset(f"raw/{modality}", data=panel.transpose(2, 0, 1), compression="gzip")
142
143            f.create_dataset("labels/instances", data=instances, compression="gzip")
144            f.create_dataset("labels/semantic", data=semantic, compression="gzip")
145
146
147def _get_tissues(tissue, split):
148    """Resolve the tissue argument to the tissues that the split actually holds."""
149    if tissue is None:
150        return [name for name in TISSUES if ("breast" if name == "breast" else "lung_bladder", split) in FILENAMES]
151
152    tissues = [tissue] if isinstance(tissue, str) else list(tissue)
153    for name in tissues:
154        if name not in TISSUES:
155            raise ValueError(f"'{name}' is not a valid tissue. Choose one of {TISSUES}.")
156    return tissues
157
158
159def get_deepliif_data(
160    path: Union[os.PathLike, str],
161    split: Literal["train", "val", "test"],
162    tissue: Optional[Union[str, List[str]]] = None,
163    download: bool = False,
164) -> List[str]:
165    """Download the DeepLIIF dataset for one split.
166
167    Args:
168        path: The folder where the function stores the data.
169        split: The split of the dataset. Either 'train', 'val' or 'test'.
170        tissue: The tissue to download. See `TISSUES` for the valid choices. By default this
171            downloads every tissue that the split holds.
172        download: Whether to download the data if it is not present.
173
174    Returns:
175        The list of filepaths to the folders with the prepared data.
176    """
177    if split not in SPLITS:
178        raise ValueError(f"'{split}' is not a valid split. Choose one of {SPLITS}.")
179
180    data_dirs = []
181    for archive in dict.fromkeys(_get_archive(name, split) for name in _get_tissues(tissue, split)):
182        archive_dir = os.path.join(path, "_".join(archive))
183        data_dir = os.path.join(archive_dir, "data")
184        data_dirs.append(data_dir)
185        if glob(os.path.join(data_dir, "*.h5")):
186            continue
187
188        os.makedirs(archive_dir, exist_ok=True)
189        filename = FILENAMES[archive]
190        input_dir = os.path.join(archive_dir, os.path.splitext(filename)[0])
191        if not os.path.exists(input_dir):
192            zip_path = os.path.join(archive_dir, filename)
193            util.download_source(
194                path=zip_path, url=URL.format(filename=filename), download=download, checksum=CHECKSUMS[archive]
195            )
196            util.unzip(zip_path=zip_path, dst=archive_dir)
197
198        _preprocess_data(input_dir, data_dir, EROSION[archive[0]])
199
200    return data_dirs
201
202
203def get_deepliif_paths(
204    path: Union[os.PathLike, str],
205    split: Literal["train", "val", "test"],
206    tissue: Optional[Union[str, List[str]]] = None,
207    download: bool = False,
208) -> List[str]:
209    """Get the paths to the DeepLIIF data.
210
211    Args:
212        path: The folder where the function stores the data.
213        split: The split of the dataset. Either 'train', 'val' or 'test'.
214        tissue: The tissue to use. See `TISSUES` for the valid choices. By default this uses
215            every tissue that the split holds.
216        download: Whether to download the data if it is not present.
217
218    Returns:
219        The list of filepaths to the input data.
220    """
221    tissues = _get_tissues(tissue, split)
222    get_deepliif_data(path, split, tissues, download)
223
224    volume_paths = []
225    for name in tissues:
226        data_dir = os.path.join(path, "_".join(_get_archive(name, split)), "data")
227        prefix = FILE_PREFIXES.get(name, "")
228        volume_paths.extend(natsorted(glob(os.path.join(data_dir, f"{prefix}*.h5"))))
229
230    assert len(volume_paths) > 0, f"Could not find data for the split '{split}' and the tissue '{tissue}'."
231    return natsorted(volume_paths)
232
233
234def get_deepliif_dataset(
235    path: Union[os.PathLike, str],
236    patch_shape: Tuple[int, int],
237    split: Literal["train", "val", "test"],
238    tissue: Optional[Union[str, List[str]]] = None,
239    modality: Literal["ihc", "hematoxylin", "dapi", "lap2", "marker"] = "ihc",
240    label_choice: Literal["instances", "semantic"] = "instances",
241    download: bool = False,
242    **kwargs
243) -> Dataset:
244    """Get the DeepLIIF dataset for nucleus segmentation and classification in IHC images.
245
246    Args:
247        path: The folder where the function stores the data.
248        patch_shape: The patch shape to use for training.
249        split: The split of the dataset. Either 'train', 'val' or 'test'.
250        tissue: The tissue to use. See `TISSUES` for the valid choices. By default this uses
251            every tissue that the split holds. Note that 'breast' has no test split.
252        modality: The image modality to use as input. See `MODALITIES` for the valid choices.
253        label_choice: The choice of labels. Either 'instances' for the nucleus instances, or
254            'semantic' for the classification into background, negative cells and positive cells.
255        download: Whether to download the data if it is not present.
256        kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset`.
257
258    Returns:
259        The segmentation dataset.
260    """
261    if modality not in MODALITIES:
262        raise ValueError(f"'{modality}' is not a valid modality. Choose one of {MODALITIES}.")
263
264    if label_choice not in ["instances", "semantic"]:
265        raise ValueError(f"'{label_choice}' is not a valid label choice. Choose 'instances' or 'semantic'.")
266
267    volume_paths = get_deepliif_paths(path, split, tissue, download)
268    kwargs = util.update_kwargs(kwargs, "with_channels", True)
269
270    return torch_em.default_segmentation_dataset(
271        raw_paths=volume_paths,
272        raw_key=f"raw/{modality}",
273        label_paths=volume_paths,
274        label_key=f"labels/{label_choice}",
275        patch_shape=patch_shape,
276        is_seg_dataset=True,
277        ndim=2,
278        **kwargs
279    )
280
281
282def get_deepliif_loader(
283    path: Union[os.PathLike, str],
284    batch_size: int,
285    patch_shape: Tuple[int, int],
286    split: Literal["train", "val", "test"],
287    tissue: Optional[Union[str, List[str]]] = None,
288    modality: Literal["ihc", "hematoxylin", "dapi", "lap2", "marker"] = "ihc",
289    label_choice: Literal["instances", "semantic"] = "instances",
290    download: bool = False,
291    **kwargs
292) -> DataLoader:
293    """Get the DeepLIIF dataloader for nucleus segmentation and classification in IHC images.
294
295    Args:
296        path: The folder where the function stores the data.
297        batch_size: The batch size for training.
298        patch_shape: The patch shape to use for training.
299        split: The split of the dataset. Either 'train', 'val' or 'test'.
300        tissue: The tissue to use. See `TISSUES` for the valid choices. By default this uses
301            every tissue that the split holds. Note that 'breast' has no test split.
302        modality: The image modality to use as input. See `MODALITIES` for the valid choices.
303        label_choice: The choice of labels. Either 'instances' for the nucleus instances, or
304            'semantic' for the classification into background, negative cells and positive cells.
305        download: Whether to download the data if it is not present.
306        kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset` or for the PyTorch DataLoader.
307
308    Returns:
309        The DataLoader.
310    """
311    ds_kwargs, loader_kwargs = util.split_kwargs(torch_em.default_segmentation_dataset, **kwargs)
312    dataset = get_deepliif_dataset(path, patch_shape, split, tissue, modality, label_choice, download, **ds_kwargs)
313    return torch_em.get_data_loader(dataset, batch_size=batch_size, **loader_kwargs)
URL = 'https://zenodo.org/records/4751737/files/{filename}?download=1'
FILENAMES = {('lung_bladder', 'train'): 'DeepLIIF_Training_Set.zip', ('lung_bladder', 'val'): 'DeepLIIF_Validation_Set.zip', ('lung_bladder', 'test'): 'DeepLIIF_Testing_Set.zip', ('breast', 'train'): 'BC-DeepLIIF_Training_Set.zip', ('breast', 'val'): 'BC-DeepLIIF_Validation_Set.zip'}
CHECKSUMS = {('lung_bladder', 'train'): '704b75ad9d15d5c5ffda8c48a53a7037544208bbcb7a1f3bbb2b1ce9c4f63d02', ('lung_bladder', 'val'): 'e8dcec56d4cb44a7037170060e39ec503ba3b70f817abd00cb36fb86eb4e7e1a', ('lung_bladder', 'test'): '7663611b1274049b677dd18deee8fbd1e44370884ec1f4d8d7196924d2a7acec', ('breast', 'train'): '598bef02f1dcc54f888976ad5ed267e1672816e9326c2011a35c68d5b0167d8e', ('breast', 'val'): '349278854a95b0a31790e81acd21f87c7afaa8f3641ce5fb4c47b09987e45b23'}
SPLITS = ['train', 'val', 'test']
TISSUES = ['lung', 'bladder', 'breast']
FILE_PREFIXES = {'lung': 'Lung_', 'bladder': 'Bladder_'}
MODALITIES = ['ihc', 'hematoxylin', 'dapi', 'lap2', 'marker']
EROSION = {'lung_bladder': 2, 'breast': 3}
def get_deepliif_data( path: Union[os.PathLike, str], split: Literal['train', 'val', 'test'], tissue: Union[List[str], str, NoneType] = None, download: bool = False) -> List[str]:
160def get_deepliif_data(
161    path: Union[os.PathLike, str],
162    split: Literal["train", "val", "test"],
163    tissue: Optional[Union[str, List[str]]] = None,
164    download: bool = False,
165) -> List[str]:
166    """Download the DeepLIIF dataset for one split.
167
168    Args:
169        path: The folder where the function stores the data.
170        split: The split of the dataset. Either 'train', 'val' or 'test'.
171        tissue: The tissue to download. See `TISSUES` for the valid choices. By default this
172            downloads every tissue that the split holds.
173        download: Whether to download the data if it is not present.
174
175    Returns:
176        The list of filepaths to the folders with the prepared data.
177    """
178    if split not in SPLITS:
179        raise ValueError(f"'{split}' is not a valid split. Choose one of {SPLITS}.")
180
181    data_dirs = []
182    for archive in dict.fromkeys(_get_archive(name, split) for name in _get_tissues(tissue, split)):
183        archive_dir = os.path.join(path, "_".join(archive))
184        data_dir = os.path.join(archive_dir, "data")
185        data_dirs.append(data_dir)
186        if glob(os.path.join(data_dir, "*.h5")):
187            continue
188
189        os.makedirs(archive_dir, exist_ok=True)
190        filename = FILENAMES[archive]
191        input_dir = os.path.join(archive_dir, os.path.splitext(filename)[0])
192        if not os.path.exists(input_dir):
193            zip_path = os.path.join(archive_dir, filename)
194            util.download_source(
195                path=zip_path, url=URL.format(filename=filename), download=download, checksum=CHECKSUMS[archive]
196            )
197            util.unzip(zip_path=zip_path, dst=archive_dir)
198
199        _preprocess_data(input_dir, data_dir, EROSION[archive[0]])
200
201    return data_dirs

Download the DeepLIIF dataset for one split.

Arguments:
  • path: The folder where the function stores the data.
  • split: The split of the dataset. Either 'train', 'val' or 'test'.
  • tissue: The tissue to download. See TISSUES for the valid choices. By default this downloads every tissue that the split holds.
  • download: Whether to download the data if it is not present.
Returns:

The list of filepaths to the folders with the prepared data.

def get_deepliif_paths( path: Union[os.PathLike, str], split: Literal['train', 'val', 'test'], tissue: Union[List[str], str, NoneType] = None, download: bool = False) -> List[str]:
204def get_deepliif_paths(
205    path: Union[os.PathLike, str],
206    split: Literal["train", "val", "test"],
207    tissue: Optional[Union[str, List[str]]] = None,
208    download: bool = False,
209) -> List[str]:
210    """Get the paths to the DeepLIIF data.
211
212    Args:
213        path: The folder where the function stores the data.
214        split: The split of the dataset. Either 'train', 'val' or 'test'.
215        tissue: The tissue to use. See `TISSUES` for the valid choices. By default this uses
216            every tissue that the split holds.
217        download: Whether to download the data if it is not present.
218
219    Returns:
220        The list of filepaths to the input data.
221    """
222    tissues = _get_tissues(tissue, split)
223    get_deepliif_data(path, split, tissues, download)
224
225    volume_paths = []
226    for name in tissues:
227        data_dir = os.path.join(path, "_".join(_get_archive(name, split)), "data")
228        prefix = FILE_PREFIXES.get(name, "")
229        volume_paths.extend(natsorted(glob(os.path.join(data_dir, f"{prefix}*.h5"))))
230
231    assert len(volume_paths) > 0, f"Could not find data for the split '{split}' and the tissue '{tissue}'."
232    return natsorted(volume_paths)

Get the paths to the DeepLIIF data.

Arguments:
  • path: The folder where the function stores the data.
  • split: The split of the dataset. Either 'train', 'val' or 'test'.
  • tissue: The tissue to use. See TISSUES for the valid choices. By default this uses every tissue that the split holds.
  • download: Whether to download the data if it is not present.
Returns:

The list of filepaths to the input data.

def get_deepliif_dataset( path: Union[os.PathLike, str], patch_shape: Tuple[int, int], split: Literal['train', 'val', 'test'], tissue: Union[List[str], str, NoneType] = None, modality: Literal['ihc', 'hematoxylin', 'dapi', 'lap2', 'marker'] = 'ihc', label_choice: Literal['instances', 'semantic'] = 'instances', download: bool = False, **kwargs) -> torch.utils.data.dataset.Dataset:
235def get_deepliif_dataset(
236    path: Union[os.PathLike, str],
237    patch_shape: Tuple[int, int],
238    split: Literal["train", "val", "test"],
239    tissue: Optional[Union[str, List[str]]] = None,
240    modality: Literal["ihc", "hematoxylin", "dapi", "lap2", "marker"] = "ihc",
241    label_choice: Literal["instances", "semantic"] = "instances",
242    download: bool = False,
243    **kwargs
244) -> Dataset:
245    """Get the DeepLIIF dataset for nucleus segmentation and classification in IHC images.
246
247    Args:
248        path: The folder where the function stores the data.
249        patch_shape: The patch shape to use for training.
250        split: The split of the dataset. Either 'train', 'val' or 'test'.
251        tissue: The tissue to use. See `TISSUES` for the valid choices. By default this uses
252            every tissue that the split holds. Note that 'breast' has no test split.
253        modality: The image modality to use as input. See `MODALITIES` for the valid choices.
254        label_choice: The choice of labels. Either 'instances' for the nucleus instances, or
255            'semantic' for the classification into background, negative cells and positive cells.
256        download: Whether to download the data if it is not present.
257        kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset`.
258
259    Returns:
260        The segmentation dataset.
261    """
262    if modality not in MODALITIES:
263        raise ValueError(f"'{modality}' is not a valid modality. Choose one of {MODALITIES}.")
264
265    if label_choice not in ["instances", "semantic"]:
266        raise ValueError(f"'{label_choice}' is not a valid label choice. Choose 'instances' or 'semantic'.")
267
268    volume_paths = get_deepliif_paths(path, split, tissue, download)
269    kwargs = util.update_kwargs(kwargs, "with_channels", True)
270
271    return torch_em.default_segmentation_dataset(
272        raw_paths=volume_paths,
273        raw_key=f"raw/{modality}",
274        label_paths=volume_paths,
275        label_key=f"labels/{label_choice}",
276        patch_shape=patch_shape,
277        is_seg_dataset=True,
278        ndim=2,
279        **kwargs
280    )

Get the DeepLIIF dataset for nucleus segmentation and classification in IHC images.

Arguments:
  • path: The folder where the function stores the data.
  • patch_shape: The patch shape to use for training.
  • split: The split of the dataset. Either 'train', 'val' or 'test'.
  • tissue: The tissue to use. See TISSUES for the valid choices. By default this uses every tissue that the split holds. Note that 'breast' has no test split.
  • modality: The image modality to use as input. See MODALITIES for the valid choices.
  • label_choice: The choice of labels. Either 'instances' for the nucleus instances, or 'semantic' for the classification into background, negative cells and positive cells.
  • 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_deepliif_loader( path: Union[os.PathLike, str], batch_size: int, patch_shape: Tuple[int, int], split: Literal['train', 'val', 'test'], tissue: Union[List[str], str, NoneType] = None, modality: Literal['ihc', 'hematoxylin', 'dapi', 'lap2', 'marker'] = 'ihc', label_choice: Literal['instances', 'semantic'] = 'instances', download: bool = False, **kwargs) -> torch.utils.data.dataloader.DataLoader:
283def get_deepliif_loader(
284    path: Union[os.PathLike, str],
285    batch_size: int,
286    patch_shape: Tuple[int, int],
287    split: Literal["train", "val", "test"],
288    tissue: Optional[Union[str, List[str]]] = None,
289    modality: Literal["ihc", "hematoxylin", "dapi", "lap2", "marker"] = "ihc",
290    label_choice: Literal["instances", "semantic"] = "instances",
291    download: bool = False,
292    **kwargs
293) -> DataLoader:
294    """Get the DeepLIIF dataloader for nucleus segmentation and classification in IHC images.
295
296    Args:
297        path: The folder where the function stores the data.
298        batch_size: The batch size for training.
299        patch_shape: The patch shape to use for training.
300        split: The split of the dataset. Either 'train', 'val' or 'test'.
301        tissue: The tissue to use. See `TISSUES` for the valid choices. By default this uses
302            every tissue that the split holds. Note that 'breast' has no test split.
303        modality: The image modality to use as input. See `MODALITIES` for the valid choices.
304        label_choice: The choice of labels. Either 'instances' for the nucleus instances, or
305            'semantic' for the classification into background, negative cells and positive cells.
306        download: Whether to download the data if it is not present.
307        kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset` or for the PyTorch DataLoader.
308
309    Returns:
310        The DataLoader.
311    """
312    ds_kwargs, loader_kwargs = util.split_kwargs(torch_em.default_segmentation_dataset, **kwargs)
313    dataset = get_deepliif_dataset(path, patch_shape, split, tissue, modality, label_choice, download, **ds_kwargs)
314    return torch_em.get_data_loader(dataset, batch_size=batch_size, **loader_kwargs)

Get the DeepLIIF dataloader for nucleus segmentation and classification in IHC images.

Arguments:
  • path: The folder where the function stores the data.
  • batch_size: The batch size for training.
  • patch_shape: The patch shape to use for training.
  • split: The split of the dataset. Either 'train', 'val' or 'test'.
  • tissue: The tissue to use. See TISSUES for the valid choices. By default this uses every tissue that the split holds. Note that 'breast' has no test split.
  • modality: The image modality to use as input. See MODALITIES for the valid choices.
  • label_choice: The choice of labels. Either 'instances' for the nucleus instances, or 'semantic' for the classification into background, negative cells and positive cells.
  • 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.