torch_em.data.datasets.medical.hcc_tace

The HCC-TACE-Seg dataset contains annotations for liver, tumor and vessel segmentation in multiphasic contrast-enhanced CT of patients with hepatocellular carcinoma treated with transarterial chemoembolization (TACE).

It consists of 105 CT volumes (the pre-treatment CT phase that was segmented) with semantic labels for: 1: liver, 2: tumor, 3: tumor necrosis (only annotated for one patient), 4: portal vein, 5: abdominal aorta. The CT scans are distributed as DICOM series and the labels as DICOM-SEG objects, which are converted and stored in hdf5 files by this module. The segments are painted in the order of their ids, i.e. the tumor overwrites the liver and the necrosis overwrites the tumor.

The collection contains several CT phases per patient (28.6 GB in total), but only one of them is segmented. Hence, this module downloads the DICOM-SEG objects and the CT series they reference via the TCIA REST API instead of the full collection manifest.

NOTE: This requires the pydicom python package.

The dataset is located at https://www.cancerimagingarchive.net/collection/hcc-tace-seg/.

This dataset is from the publication https://doi.org/10.1038/s41597-023-01928-3. The data was released at https://doi.org/10.7937/TCIA.5FNA-0924. Please cite it if you use this dataset in your research.

  1"""The HCC-TACE-Seg dataset contains annotations for liver, tumor and vessel segmentation in multiphasic
  2contrast-enhanced CT of patients with hepatocellular carcinoma treated with transarterial chemoembolization (TACE).
  3
  4It consists of 105 CT volumes (the pre-treatment CT phase that was segmented) with semantic labels for:
  51: liver, 2: tumor, 3: tumor necrosis (only annotated for one patient), 4: portal vein,
  65: abdominal aorta. The CT scans are distributed as DICOM series and the labels as DICOM-SEG objects, which are
  7converted and stored in hdf5 files by this module. The segments are painted in the order of their ids, i.e. the
  8tumor overwrites the liver and the necrosis overwrites the tumor.
  9
 10The collection contains several CT phases per patient (28.6 GB in total), but only one of them is segmented.
 11Hence, this module downloads the DICOM-SEG objects and the CT series they reference via the TCIA REST API
 12instead of the full collection manifest.
 13
 14NOTE: This requires the pydicom python package.
 15
 16The dataset is located at https://www.cancerimagingarchive.net/collection/hcc-tace-seg/.
 17
 18This dataset is from the publication https://doi.org/10.1038/s41597-023-01928-3.
 19The data was released at https://doi.org/10.7937/TCIA.5FNA-0924.
 20Please cite it if you use this dataset in your research.
 21"""
 22
 23import os
 24from glob import glob
 25from tqdm import tqdm
 26from warnings import warn
 27from natsort import natsorted
 28from collections import Counter, defaultdict
 29from typing import Union, Tuple, List
 30
 31import numpy as np
 32import requests
 33
 34from torch.utils.data import Dataset, DataLoader
 35
 36import torch_em
 37
 38from .. import util
 39
 40
 41NBIA_API_URL = "https://services.cancerimagingarchive.net/nbia-api/services/v1"
 42COLLECTION = "HCC-TACE-Seg"
 43
 44# The DICOM series are downloaded individually from TCIA.
 45CHECKSUM = None
 46
 47NUM_VOLUMES = 105
 48
 49LABEL_IDS = {"liver": 1, "tumor": 2, "necrosis": 3, "portal_vein": 4, "abdominal_aorta": 5}
 50
 51# The segment labels used in the DICOM-SEG objects.
 52SEGMENT_NAMES = {
 53    "Liver": "liver", "Mass": "tumor", "Necrosis": "necrosis", "Portal vein": "portal_vein",
 54    "Abdominal aorta": "abdominal_aorta",
 55}
 56
 57
 58def _download_series(series_uid, dicom_dir, download):
 59    """Download a DICOM series via the NBIA REST API and extract it to '<dicom_dir>/<series_uid>'."""
 60    series_dir = os.path.join(dicom_dir, series_uid)
 61    if os.path.exists(series_dir):
 62        return series_dir
 63
 64    zip_path = os.path.join(dicom_dir, f"{series_uid}.zip")
 65    url = f"{NBIA_API_URL}/getImage?SeriesInstanceUID={series_uid}"
 66    util.download_source(path=zip_path, url=url, download=download, checksum=None)
 67    util.unzip(zip_path=zip_path, dst=f"{series_dir}.tmp")
 68    os.rename(f"{series_dir}.tmp", series_dir)
 69    return series_dir
 70
 71
 72def _get_series_per_patient(download):
 73    """Get the metadata of all series in the collection from the NBIA REST API, grouped by patient."""
 74    if not download:
 75        raise RuntimeError("Cannot find the data, but download was set to False.")
 76    response = requests.get(f"{NBIA_API_URL}/getSeries", params={"Collection": COLLECTION})
 77    response.raise_for_status()
 78
 79    series_per_patient = defaultdict(list)
 80    for series in response.json():
 81        series_per_patient[series["PatientID"]].append(series)
 82    return series_per_patient
 83
 84
 85def _get_candidate_series(seg_path, ct_series):
 86    """Rank the CT series of a patient by how likely it is that the DICOM-SEG object was drawn on them.
 87
 88    The series referenced by the DICOM-SEG object is tried first. This reference is missing for one patient
 89    (HCC_048) and points to a series that does not overlap with the segmentation for another one (HCC_089),
 90    so the other CT series are ranked by the difference between their slice count and the number of segmented
 91    slices and are used as fall-backs.
 92
 93    Returns a list of (series UID, SOP instance UIDs of the referenced slices) tuples.
 94    """
 95    import pydicom
 96
 97    seg = pydicom.dcmread(seg_path, stop_before_pixels=True)
 98    z_positions = {
 99        round(float(group.PlanePositionSequence[0].ImagePositionPatient[2]), 2)
100        for group in seg.PerFrameFunctionalGroupsSequence
101    }
102
103    referenced_uid, referenced_sop_uids = None, set()
104    if "ReferencedSeriesSequence" in seg:
105        assert len(seg.ReferencedSeriesSequence) == 1, f"Expected a single referenced CT series in {seg_path}."
106        referenced_series = seg.ReferencedSeriesSequence[0]
107        referenced_uid = str(referenced_series.SeriesInstanceUID)
108        referenced_sop_uids = {
109            str(instance.ReferencedSOPInstanceUID) for instance in referenced_series.ReferencedInstanceSequence
110        }
111
112    ranked = sorted(ct_series, key=lambda series: abs(int(series["ImageCount"]) - len(z_positions)))
113    candidates = [(referenced_uid, referenced_sop_uids)] if referenced_uid is not None else []
114    candidates += [(str(series["SeriesInstanceUID"]), set()) for series in ranked
115                   if str(series["SeriesInstanceUID"]) != referenced_uid]
116    return candidates
117
118
119def _load_dicom_volume(series_dir, referenced_sop_uids):
120    """Stack a DICOM series into a volume with axes (z, y, x) and slices sorted by ascending patient z position.
121
122    Some series contain several acquisitions (CT phases) with overlapping slice positions. In this case, only the
123    acquisition referenced by the DICOM-SEG object is kept, so that each slice position occurs once.
124    Returns the volume in Hounsfield units and the geometry needed to align the DICOM-SEG frames with the volume.
125    """
126    import pydicom
127
128    slices = [pydicom.dcmread(dcm_path) for dcm_path in natsorted(glob(os.path.join(series_dir, "*.dcm")))]
129
130    acquisitions = Counter(dcm.get("AcquisitionNumber") for dcm in slices if dcm.SOPInstanceUID in referenced_sop_uids)
131    acquisition = acquisitions.most_common(1)[0][0] if acquisitions else None
132    slices_per_position = {}
133    for dcm in slices:
134        z = round(float(dcm.ImagePositionPatient[2]), 2)
135        priority = (dcm.SOPInstanceUID in referenced_sop_uids, dcm.get("AcquisitionNumber") == acquisition)
136        if z not in slices_per_position or priority > slices_per_position[z][0]:
137            slices_per_position[z] = (priority, dcm)
138    slices = [dcm for _, dcm in sorted(slices_per_position.values(), key=lambda item: item[1].ImagePositionPatient[2])]
139
140    volume = np.stack([dcm.pixel_array for dcm in slices]).astype("float32")
141    volume = volume * float(slices[0].RescaleSlope) + float(slices[0].RescaleIntercept)
142    volume = np.round(volume).astype("int16")
143
144    geometry = {
145        "sop_uids": {str(dcm.SOPInstanceUID): i for i, dcm in enumerate(slices)},
146        "z_positions": np.array([float(dcm.ImagePositionPatient[2]) for dcm in slices]),
147        "orientation": np.round([float(v) for v in slices[0].ImageOrientationPatient]).astype("int"),
148    }
149    return volume, geometry
150
151
152def _load_dicom_seg(seg_path, shape, geometry):
153    """Convert a DICOM-SEG object into binary masks (one per segment) aligned with the reference CT volume.
154
155    Each frame is mapped to its CT slice via the source image it was derived from (or its z position).
156    """
157    import pydicom
158
159    seg = pydicom.dcmread(seg_path)
160    frames = seg.pixel_array
161    if frames.ndim == 2:  # A segmentation with a single frame.
162        frames = frames[None]
163
164    segment_names = {int(segment.SegmentNumber): str(segment.SegmentLabel) for segment in seg.SegmentSequence}
165
166    # The segmentation frames may use a different in-plane orientation than the CT slices,
167    # in which case they have to be flipped to align them.
168    seg_orientation = seg.SharedFunctionalGroupsSequence[0].PlaneOrientationSequence[0].ImageOrientationPatient
169    seg_orientation = np.round([float(v) for v in seg_orientation]).astype("int")
170    orientation = geometry["orientation"]
171    assert np.all(np.abs(seg_orientation) == np.abs(orientation)), f"Unexpected orientation in {seg_path}."
172    flip_axes = []
173    if np.any(seg_orientation[3:] != orientation[3:]):  # The direction of the rows differs.
174        flip_axes.append(0)
175    if np.any(seg_orientation[:3] != orientation[:3]):  # The direction of the columns differs.
176        flip_axes.append(1)
177
178    # Frames are matched to CT slices via their z position, if they cannot be matched via the source image.
179    z_positions = geometry["z_positions"]
180    tolerance = np.diff(z_positions).min() / 2 if len(z_positions) > 1 else 1.0
181
182    masks = {name: np.zeros(shape, dtype="bool") for name in segment_names.values()}
183    for frame, frame_group in zip(frames, seg.PerFrameFunctionalGroupsSequence):
184        segment_number = int(frame_group.SegmentIdentificationSequence[0].ReferencedSegmentNumber)
185        mask = frame.astype("bool")
186
187        z = None
188        derivation = frame_group.get("DerivationImageSequence", [])
189        if derivation and derivation[0].get("SourceImageSequence"):
190            z = geometry["sop_uids"].get(str(derivation[0].SourceImageSequence[0].ReferencedSOPInstanceUID))
191        if z is None:
192            frame_z = float(frame_group.PlanePositionSequence[0].ImagePositionPatient[2])
193            z = int(np.argmin(np.abs(z_positions - frame_z)))
194            if abs(z_positions[z] - frame_z) > tolerance:
195                if mask.any():
196                    warn(f"Skipping a frame of '{segment_names[segment_number]}' at z={frame_z} in {seg_path}, "
197                         "which does not match a CT slice.")
198                continue
199
200        if flip_axes:
201            mask = np.flip(mask, axis=flip_axes)
202        masks[segment_names[segment_number]][z] |= mask
203
204    return masks
205
206
207def _preprocess_hcc_tace(seg_path, ct_dir, referenced_sop_uids, out_path):
208    """Convert a CT series and the segmentation drawn on it into an hdf5 file.
209
210    Returns whether the segmentation could be mapped onto the CT series.
211    """
212    import h5py
213
214    volume, geometry = _load_dicom_volume(ct_dir, referenced_sop_uids)
215    masks = _load_dicom_seg(seg_path, volume.shape, geometry)
216
217    unknown = [name for name in masks if name not in SEGMENT_NAMES]
218    if unknown:
219        raise ValueError(f"Unknown segment labels {unknown} in {seg_path}.")
220
221    labels = np.zeros(volume.shape, dtype="uint8")
222    for name in sorted(masks, key=lambda name: LABEL_IDS[SEGMENT_NAMES[name]]):
223        labels[masks[name]] = LABEL_IDS[SEGMENT_NAMES[name]]
224
225    if labels.max() == 0:  # The segmentation does not belong to this CT series.
226        return False
227
228    with h5py.File(out_path, "w") as f:
229        f.create_dataset("raw", data=volume, compression="gzip")
230        f.create_dataset("labels", data=labels, compression="gzip")
231    return True
232
233
234def get_hcc_tace_data(path: Union[os.PathLike, str], download: bool = False) -> str:
235    """Download the HCC-TACE-Seg dataset.
236
237    Args:
238        path: Filepath to a folder where the data is downloaded for further processing.
239        download: Whether to download the data if it is not present.
240
241    Returns:
242        Filepath where the preprocessed data is stored.
243    """
244    preprocessed_dir = os.path.join(path, "preprocessed")
245    if len(glob(os.path.join(preprocessed_dir, "*.h5"))) == NUM_VOLUMES:
246        return preprocessed_dir
247
248    dicom_dir = os.path.join(path, "dicom")
249    os.makedirs(dicom_dir, exist_ok=True)
250
251    # Download the DICOM-SEG object of each patient and the CT series it references, then convert them.
252    series_per_patient = _get_series_per_patient(download)
253    for patient_id, series in tqdm(sorted(series_per_patient.items()), desc="Download and preprocess HCC-TACE-Seg"):
254        out_path = os.path.join(preprocessed_dir, f"{patient_id}.h5")
255        if os.path.exists(out_path):
256            continue
257
258        seg_series = [s for s in series if s["Modality"] == "SEG"]
259        assert len(seg_series) == 1, f"Expected a single segmentation for the patient '{patient_id}'."
260        seg_dir = _download_series(str(seg_series[0]["SeriesInstanceUID"]), dicom_dir, download)
261        seg_path = glob(os.path.join(seg_dir, "*.dcm"))[0]
262
263        os.makedirs(preprocessed_dir, exist_ok=True)
264        candidates = _get_candidate_series(seg_path, [s for s in series if s["Modality"] == "CT"])
265        for ct_uid, referenced_sop_uids in candidates:
266            ct_dir = _download_series(ct_uid, dicom_dir, download)
267            if _preprocess_hcc_tace(seg_path, ct_dir, referenced_sop_uids, out_path):
268                break
269        else:
270            raise RuntimeError(f"Could not find the CT series that belongs to {seg_path}.")
271
272    return preprocessed_dir
273
274
275def get_hcc_tace_paths(path: Union[os.PathLike, str], download: bool = False) -> List[str]:
276    """Get paths to the HCC-TACE-Seg data.
277
278    Args:
279        path: Filepath to a folder where the data is downloaded for further processing.
280        download: Whether to download the data if it is not present.
281
282    Returns:
283        List of filepaths for the hdf5 files, which contain the image data ('raw') and the label data ('labels').
284    """
285    data_dir = get_hcc_tace_data(path, download)
286    volume_paths = natsorted(glob(os.path.join(data_dir, "*.h5")))
287    return volume_paths
288
289
290def get_hcc_tace_dataset(
291    path: Union[os.PathLike, str],
292    patch_shape: Tuple[int, ...],
293    resize_inputs: bool = False,
294    download: bool = False,
295    **kwargs
296) -> Dataset:
297    """Get the HCC-TACE-Seg dataset for liver, tumor and vessel segmentation.
298
299    Args:
300        path: Filepath to a folder where the data is downloaded for further processing.
301        patch_shape: The patch shape to use for training.
302        resize_inputs: Whether to resize inputs to the desired patch shape.
303        download: Whether to download the data if it is not present.
304        kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset`.
305
306    Returns:
307        The segmentation dataset.
308    """
309    volume_paths = get_hcc_tace_paths(path, download)
310
311    if resize_inputs:
312        resize_kwargs = {"patch_shape": patch_shape, "is_rgb": False}
313        kwargs, patch_shape = util.update_kwargs_for_resize_trafo(
314            kwargs=kwargs, patch_shape=patch_shape, resize_inputs=resize_inputs, resize_kwargs=resize_kwargs
315        )
316
317    return torch_em.default_segmentation_dataset(
318        raw_paths=volume_paths,
319        raw_key="raw",
320        label_paths=volume_paths,
321        label_key="labels",
322        patch_shape=patch_shape,
323        is_seg_dataset=True,
324        **kwargs
325    )
326
327
328def get_hcc_tace_loader(
329    path: Union[os.PathLike, str],
330    batch_size: int,
331    patch_shape: Tuple[int, ...],
332    resize_inputs: bool = False,
333    download: bool = False,
334    **kwargs
335) -> DataLoader:
336    """Get the HCC-TACE-Seg dataloader for liver, tumor and vessel segmentation.
337
338    Args:
339        path: Filepath to a folder where the data is downloaded for further processing.
340        batch_size: The batch size for training.
341        patch_shape: The patch shape to use for training.
342        resize_inputs: Whether to resize inputs to the desired patch shape.
343        download: Whether to download the data if it is not present.
344        kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset` or for the PyTorch DataLoader.
345
346    Returns:
347        The DataLoader.
348    """
349    ds_kwargs, loader_kwargs = util.split_kwargs(torch_em.default_segmentation_dataset, **kwargs)
350    dataset = get_hcc_tace_dataset(path, patch_shape, resize_inputs, download, **ds_kwargs)
351    return torch_em.get_data_loader(dataset, batch_size, **loader_kwargs)
NBIA_API_URL = 'https://services.cancerimagingarchive.net/nbia-api/services/v1'
COLLECTION = 'HCC-TACE-Seg'
CHECKSUM = None
NUM_VOLUMES = 105
LABEL_IDS = {'liver': 1, 'tumor': 2, 'necrosis': 3, 'portal_vein': 4, 'abdominal_aorta': 5}
SEGMENT_NAMES = {'Liver': 'liver', 'Mass': 'tumor', 'Necrosis': 'necrosis', 'Portal vein': 'portal_vein', 'Abdominal aorta': 'abdominal_aorta'}
def get_hcc_tace_data(path: Union[os.PathLike, str], download: bool = False) -> str:
235def get_hcc_tace_data(path: Union[os.PathLike, str], download: bool = False) -> str:
236    """Download the HCC-TACE-Seg dataset.
237
238    Args:
239        path: Filepath to a folder where the data is downloaded for further processing.
240        download: Whether to download the data if it is not present.
241
242    Returns:
243        Filepath where the preprocessed data is stored.
244    """
245    preprocessed_dir = os.path.join(path, "preprocessed")
246    if len(glob(os.path.join(preprocessed_dir, "*.h5"))) == NUM_VOLUMES:
247        return preprocessed_dir
248
249    dicom_dir = os.path.join(path, "dicom")
250    os.makedirs(dicom_dir, exist_ok=True)
251
252    # Download the DICOM-SEG object of each patient and the CT series it references, then convert them.
253    series_per_patient = _get_series_per_patient(download)
254    for patient_id, series in tqdm(sorted(series_per_patient.items()), desc="Download and preprocess HCC-TACE-Seg"):
255        out_path = os.path.join(preprocessed_dir, f"{patient_id}.h5")
256        if os.path.exists(out_path):
257            continue
258
259        seg_series = [s for s in series if s["Modality"] == "SEG"]
260        assert len(seg_series) == 1, f"Expected a single segmentation for the patient '{patient_id}'."
261        seg_dir = _download_series(str(seg_series[0]["SeriesInstanceUID"]), dicom_dir, download)
262        seg_path = glob(os.path.join(seg_dir, "*.dcm"))[0]
263
264        os.makedirs(preprocessed_dir, exist_ok=True)
265        candidates = _get_candidate_series(seg_path, [s for s in series if s["Modality"] == "CT"])
266        for ct_uid, referenced_sop_uids in candidates:
267            ct_dir = _download_series(ct_uid, dicom_dir, download)
268            if _preprocess_hcc_tace(seg_path, ct_dir, referenced_sop_uids, out_path):
269                break
270        else:
271            raise RuntimeError(f"Could not find the CT series that belongs to {seg_path}.")
272
273    return preprocessed_dir

Download the HCC-TACE-Seg dataset.

Arguments:
  • path: Filepath to a folder where the data is downloaded for further processing.
  • download: Whether to download the data if it is not present.
Returns:

Filepath where the preprocessed data is stored.

def get_hcc_tace_paths(path: Union[os.PathLike, str], download: bool = False) -> List[str]:
276def get_hcc_tace_paths(path: Union[os.PathLike, str], download: bool = False) -> List[str]:
277    """Get paths to the HCC-TACE-Seg data.
278
279    Args:
280        path: Filepath to a folder where the data is downloaded for further processing.
281        download: Whether to download the data if it is not present.
282
283    Returns:
284        List of filepaths for the hdf5 files, which contain the image data ('raw') and the label data ('labels').
285    """
286    data_dir = get_hcc_tace_data(path, download)
287    volume_paths = natsorted(glob(os.path.join(data_dir, "*.h5")))
288    return volume_paths

Get paths to the HCC-TACE-Seg data.

Arguments:
  • path: Filepath to a folder where the data is downloaded for further processing.
  • download: Whether to download the data if it is not present.
Returns:

List of filepaths for the hdf5 files, which contain the image data ('raw') and the label data ('labels').

def get_hcc_tace_dataset( path: Union[os.PathLike, str], patch_shape: Tuple[int, ...], resize_inputs: bool = False, download: bool = False, **kwargs) -> torch.utils.data.dataset.Dataset:
291def get_hcc_tace_dataset(
292    path: Union[os.PathLike, str],
293    patch_shape: Tuple[int, ...],
294    resize_inputs: bool = False,
295    download: bool = False,
296    **kwargs
297) -> Dataset:
298    """Get the HCC-TACE-Seg dataset for liver, tumor and vessel segmentation.
299
300    Args:
301        path: Filepath to a folder where the data is downloaded for further processing.
302        patch_shape: The patch shape to use for training.
303        resize_inputs: Whether to resize inputs to the desired patch shape.
304        download: Whether to download the data if it is not present.
305        kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset`.
306
307    Returns:
308        The segmentation dataset.
309    """
310    volume_paths = get_hcc_tace_paths(path, download)
311
312    if resize_inputs:
313        resize_kwargs = {"patch_shape": patch_shape, "is_rgb": False}
314        kwargs, patch_shape = util.update_kwargs_for_resize_trafo(
315            kwargs=kwargs, patch_shape=patch_shape, resize_inputs=resize_inputs, resize_kwargs=resize_kwargs
316        )
317
318    return torch_em.default_segmentation_dataset(
319        raw_paths=volume_paths,
320        raw_key="raw",
321        label_paths=volume_paths,
322        label_key="labels",
323        patch_shape=patch_shape,
324        is_seg_dataset=True,
325        **kwargs
326    )

Get the HCC-TACE-Seg dataset for liver, tumor and vessel segmentation.

Arguments:
  • path: Filepath to a folder where the data is downloaded for further processing.
  • patch_shape: The patch shape to use for training.
  • resize_inputs: Whether to resize inputs to the desired patch shape.
  • 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_hcc_tace_loader( path: Union[os.PathLike, str], batch_size: int, patch_shape: Tuple[int, ...], resize_inputs: bool = False, download: bool = False, **kwargs) -> torch.utils.data.dataloader.DataLoader:
329def get_hcc_tace_loader(
330    path: Union[os.PathLike, str],
331    batch_size: int,
332    patch_shape: Tuple[int, ...],
333    resize_inputs: bool = False,
334    download: bool = False,
335    **kwargs
336) -> DataLoader:
337    """Get the HCC-TACE-Seg dataloader for liver, tumor and vessel segmentation.
338
339    Args:
340        path: Filepath to a folder where the data is downloaded for further processing.
341        batch_size: The batch size for training.
342        patch_shape: The patch shape to use for training.
343        resize_inputs: Whether to resize inputs to the desired patch shape.
344        download: Whether to download the data if it is not present.
345        kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset` or for the PyTorch DataLoader.
346
347    Returns:
348        The DataLoader.
349    """
350    ds_kwargs, loader_kwargs = util.split_kwargs(torch_em.default_segmentation_dataset, **kwargs)
351    dataset = get_hcc_tace_dataset(path, patch_shape, resize_inputs, download, **ds_kwargs)
352    return torch_em.get_data_loader(dataset, batch_size, **loader_kwargs)

Get the HCC-TACE-Seg dataloader for liver, tumor and vessel segmentation.

Arguments:
  • path: Filepath to a folder where the data is downloaded for further processing.
  • batch_size: The batch size for training.
  • patch_shape: The patch shape to use for training.
  • resize_inputs: Whether to resize inputs to the desired patch shape.
  • 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.