torch_em.data.datasets.medical.couinaud
The Couinaud dataset contains annotations for the eight Couinaud liver segments in CT scans.
The annotations were made on the CT scans of the Medical Segmentation Decathlon task 8 (hepatic vessel),
so the images are downloaded from there. Two annotation sets are provided: 'couinaud' with the eight
Couinaud segments for 193 scans and 'liver' with a binary liver mask for 443 scans. The label ids of the
'couinaud' annotations are 1 to 8 for the Couinaud segments I to VIII. See also CLASS_IDS.
The dataset is located at https://github.com/GLCUnet/dataset and is distributed under the MIT license. This dataset is from the publication https://doi.org/10.1007/978-3-030-32692-0_32. Please cite it if you use this dataset in your research.
1"""The Couinaud dataset contains annotations for the eight Couinaud liver segments in CT scans. 2 3The annotations were made on the CT scans of the Medical Segmentation Decathlon task 8 (hepatic vessel), 4so the images are downloaded from there. Two annotation sets are provided: 'couinaud' with the eight 5Couinaud segments for 193 scans and 'liver' with a binary liver mask for 443 scans. The label ids of the 6'couinaud' annotations are 1 to 8 for the Couinaud segments I to VIII. See also `CLASS_IDS`. 7 8The dataset is located at https://github.com/GLCUnet/dataset and is distributed under the MIT license. 9This dataset is from the publication https://doi.org/10.1007/978-3-030-32692-0_32. 10Please cite it if you use this dataset in your research. 11""" 12 13import os 14from glob import glob 15from natsort import natsorted 16from typing import Union, Tuple, Literal, List 17 18from torch.utils.data import Dataset, DataLoader 19 20import torch_em 21 22from .msd import get_msd_data 23from .. import util 24 25 26URLS = { 27 "couinaud": "https://raw.githubusercontent.com/GLCUnet/dataset/master/couinaud_annotation.zip", 28 "liver": "https://raw.githubusercontent.com/GLCUnet/dataset/master/liver_annotation.zip", 29} 30 31CHECKSUMS = { 32 "couinaud": "fb2fc7809a7982267adc2785dddd5af3770070fea230e2f01142fe799a29f0cf", 33 "liver": "e14148cec317829a1d4068e82f60cfecea6df570decd7c06b474f172aff382a1", 34} 35 36CLASS_NAMES = [ 37 "segment_i", "segment_ii", "segment_iii", "segment_iv", 38 "segment_v", "segment_vi", "segment_vii", "segment_viii", 39] 40"""The Couinaud liver segments. The label id of a segment is its 1-based index.""" 41 42CLASS_IDS = {name: i + 1 for i, name in enumerate(CLASS_NAMES)} 43"""Mapping from the Couinaud segment name to its label id.""" 44 45 46def _get_image_paths(msd_dir): 47 image_paths = {} 48 for split in ["imagesTr", "imagesTs"]: 49 for path in glob(os.path.join(msd_dir, "Task08_HepaticVessel", split, "*.nii.gz")): 50 fname = os.path.basename(path) 51 # The MSD archives carry macOS resource fork files next to the actual volumes. 52 if fname.startswith("._"): 53 continue 54 image_paths[fname] = path 55 return image_paths 56 57 58def get_couinaud_data( 59 path: Union[os.PathLike, str], annotation: Literal["couinaud", "liver"] = "couinaud", download: bool = False 60) -> Tuple[str, str]: 61 """Download the Couinaud dataset. 62 63 Args: 64 path: Filepath to a folder where the data is downloaded for further processing. 65 annotation: The choice of annotations. Either 'couinaud' for the eight Couinaud segments 66 or 'liver' for a binary liver mask. 67 download: Whether to download the data if it is not present. 68 69 Returns: 70 Filepath where the annotations are downloaded. 71 Filepath where the images are downloaded. 72 """ 73 if annotation not in URLS: 74 raise ValueError(f"'{annotation}' is not a valid annotation. Choose from {list(URLS.keys())}.") 75 76 label_dir = os.path.join(path, f"{annotation}_annotation") 77 if not os.path.exists(label_dir): 78 os.makedirs(path, exist_ok=True) 79 zip_path = os.path.join(path, f"{annotation}_annotation.zip") 80 util.download_source( 81 path=zip_path, url=URLS[annotation], download=download, checksum=CHECKSUMS[annotation] 82 ) 83 util.unzip(zip_path=zip_path, dst=path, remove=False) 84 85 # The images are the hepatic vessel scans of the Medical Segmentation Decathlon. 86 msd_dir = get_msd_data(path=path, task_name="hepaticvessel", download=download) 87 88 return label_dir, msd_dir 89 90 91def get_couinaud_paths( 92 path: Union[os.PathLike, str], 93 annotation: Literal["couinaud", "liver"] = "couinaud", 94 download: bool = False, 95) -> Tuple[List[str], List[str]]: 96 """Get paths to the Couinaud data. 97 98 Args: 99 path: Filepath to a folder where the data is downloaded for further processing. 100 annotation: The choice of annotations. Either 'couinaud' for the eight Couinaud segments 101 or 'liver' for a binary liver mask. 102 download: Whether to download the data if it is not present. 103 104 Returns: 105 List of filepaths for the image data. 106 List of filepaths for the label data. 107 """ 108 label_dir, msd_dir = get_couinaud_data(path, annotation, download) 109 110 image_paths = _get_image_paths(msd_dir) 111 label_paths = natsorted(glob(os.path.join(label_dir, "*.nii.gz"))) 112 113 raw_paths, valid_label_paths = [], [] 114 for label_path in label_paths: 115 image_path = image_paths.get(os.path.basename(label_path)) 116 if image_path is not None: 117 raw_paths.append(image_path) 118 valid_label_paths.append(label_path) 119 120 assert len(raw_paths) == len(valid_label_paths) and len(raw_paths) > 0 121 122 return raw_paths, valid_label_paths 123 124 125def get_couinaud_dataset( 126 path: Union[os.PathLike, str], 127 patch_shape: Tuple[int, ...], 128 annotation: Literal["couinaud", "liver"] = "couinaud", 129 resize_inputs: bool = False, 130 download: bool = False, 131 **kwargs 132) -> Dataset: 133 """Get the Couinaud dataset for liver segment segmentation. 134 135 Args: 136 path: Filepath to a folder where the data is downloaded for further processing. 137 patch_shape: The patch shape to use for training. 138 annotation: The choice of annotations. Either 'couinaud' for the eight Couinaud segments 139 or 'liver' for a binary liver mask. 140 resize_inputs: Whether to resize inputs to the desired patch shape. 141 download: Whether to download the data if it is not present. 142 kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset`. 143 144 Returns: 145 The segmentation dataset. 146 """ 147 raw_paths, label_paths = get_couinaud_paths(path, annotation, download) 148 149 if resize_inputs: 150 resize_kwargs = {"patch_shape": patch_shape, "is_rgb": False} 151 kwargs, patch_shape = util.update_kwargs_for_resize_trafo( 152 kwargs=kwargs, patch_shape=patch_shape, resize_inputs=resize_inputs, resize_kwargs=resize_kwargs 153 ) 154 155 return torch_em.default_segmentation_dataset( 156 raw_paths=raw_paths, 157 raw_key="data", 158 label_paths=label_paths, 159 label_key="data", 160 patch_shape=patch_shape, 161 is_seg_dataset=True, 162 **kwargs 163 ) 164 165 166def get_couinaud_loader( 167 path: Union[os.PathLike, str], 168 batch_size: int, 169 patch_shape: Tuple[int, ...], 170 annotation: Literal["couinaud", "liver"] = "couinaud", 171 resize_inputs: bool = False, 172 download: bool = False, 173 **kwargs 174) -> DataLoader: 175 """Get the Couinaud dataloader for liver segment segmentation. 176 177 Args: 178 path: Filepath to a folder where the data is downloaded for further processing. 179 batch_size: The batch size for training. 180 patch_shape: The patch shape to use for training. 181 annotation: The choice of annotations. Either 'couinaud' for the eight Couinaud segments 182 or 'liver' for a binary liver mask. 183 resize_inputs: Whether to resize inputs to the desired patch shape. 184 download: Whether to download the data if it is not present. 185 kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset` or for the PyTorch DataLoader. 186 187 Returns: 188 The DataLoader. 189 """ 190 ds_kwargs, loader_kwargs = util.split_kwargs(torch_em.default_segmentation_dataset, **kwargs) 191 dataset = get_couinaud_dataset(path, patch_shape, annotation, resize_inputs, download, **ds_kwargs) 192 return torch_em.get_data_loader(dataset, batch_size, **loader_kwargs)
The Couinaud liver segments. The label id of a segment is its 1-based index.
Mapping from the Couinaud segment name to its label id.
59def get_couinaud_data( 60 path: Union[os.PathLike, str], annotation: Literal["couinaud", "liver"] = "couinaud", download: bool = False 61) -> Tuple[str, str]: 62 """Download the Couinaud dataset. 63 64 Args: 65 path: Filepath to a folder where the data is downloaded for further processing. 66 annotation: The choice of annotations. Either 'couinaud' for the eight Couinaud segments 67 or 'liver' for a binary liver mask. 68 download: Whether to download the data if it is not present. 69 70 Returns: 71 Filepath where the annotations are downloaded. 72 Filepath where the images are downloaded. 73 """ 74 if annotation not in URLS: 75 raise ValueError(f"'{annotation}' is not a valid annotation. Choose from {list(URLS.keys())}.") 76 77 label_dir = os.path.join(path, f"{annotation}_annotation") 78 if not os.path.exists(label_dir): 79 os.makedirs(path, exist_ok=True) 80 zip_path = os.path.join(path, f"{annotation}_annotation.zip") 81 util.download_source( 82 path=zip_path, url=URLS[annotation], download=download, checksum=CHECKSUMS[annotation] 83 ) 84 util.unzip(zip_path=zip_path, dst=path, remove=False) 85 86 # The images are the hepatic vessel scans of the Medical Segmentation Decathlon. 87 msd_dir = get_msd_data(path=path, task_name="hepaticvessel", download=download) 88 89 return label_dir, msd_dir
Download the Couinaud dataset.
Arguments:
- path: Filepath to a folder where the data is downloaded for further processing.
- annotation: The choice of annotations. Either 'couinaud' for the eight Couinaud segments or 'liver' for a binary liver mask.
- download: Whether to download the data if it is not present.
Returns:
Filepath where the annotations are downloaded. Filepath where the images are downloaded.
92def get_couinaud_paths( 93 path: Union[os.PathLike, str], 94 annotation: Literal["couinaud", "liver"] = "couinaud", 95 download: bool = False, 96) -> Tuple[List[str], List[str]]: 97 """Get paths to the Couinaud data. 98 99 Args: 100 path: Filepath to a folder where the data is downloaded for further processing. 101 annotation: The choice of annotations. Either 'couinaud' for the eight Couinaud segments 102 or 'liver' for a binary liver mask. 103 download: Whether to download the data if it is not present. 104 105 Returns: 106 List of filepaths for the image data. 107 List of filepaths for the label data. 108 """ 109 label_dir, msd_dir = get_couinaud_data(path, annotation, download) 110 111 image_paths = _get_image_paths(msd_dir) 112 label_paths = natsorted(glob(os.path.join(label_dir, "*.nii.gz"))) 113 114 raw_paths, valid_label_paths = [], [] 115 for label_path in label_paths: 116 image_path = image_paths.get(os.path.basename(label_path)) 117 if image_path is not None: 118 raw_paths.append(image_path) 119 valid_label_paths.append(label_path) 120 121 assert len(raw_paths) == len(valid_label_paths) and len(raw_paths) > 0 122 123 return raw_paths, valid_label_paths
Get paths to the Couinaud data.
Arguments:
- path: Filepath to a folder where the data is downloaded for further processing.
- annotation: The choice of annotations. Either 'couinaud' for the eight Couinaud segments or 'liver' for a binary liver mask.
- 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.
126def get_couinaud_dataset( 127 path: Union[os.PathLike, str], 128 patch_shape: Tuple[int, ...], 129 annotation: Literal["couinaud", "liver"] = "couinaud", 130 resize_inputs: bool = False, 131 download: bool = False, 132 **kwargs 133) -> Dataset: 134 """Get the Couinaud dataset for liver segment segmentation. 135 136 Args: 137 path: Filepath to a folder where the data is downloaded for further processing. 138 patch_shape: The patch shape to use for training. 139 annotation: The choice of annotations. Either 'couinaud' for the eight Couinaud segments 140 or 'liver' for a binary liver mask. 141 resize_inputs: Whether to resize inputs to the desired patch shape. 142 download: Whether to download the data if it is not present. 143 kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset`. 144 145 Returns: 146 The segmentation dataset. 147 """ 148 raw_paths, label_paths = get_couinaud_paths(path, annotation, download) 149 150 if resize_inputs: 151 resize_kwargs = {"patch_shape": patch_shape, "is_rgb": False} 152 kwargs, patch_shape = util.update_kwargs_for_resize_trafo( 153 kwargs=kwargs, patch_shape=patch_shape, resize_inputs=resize_inputs, resize_kwargs=resize_kwargs 154 ) 155 156 return torch_em.default_segmentation_dataset( 157 raw_paths=raw_paths, 158 raw_key="data", 159 label_paths=label_paths, 160 label_key="data", 161 patch_shape=patch_shape, 162 is_seg_dataset=True, 163 **kwargs 164 )
Get the Couinaud dataset for liver segment segmentation.
Arguments:
- path: Filepath to a folder where the data is downloaded for further processing.
- patch_shape: The patch shape to use for training.
- annotation: The choice of annotations. Either 'couinaud' for the eight Couinaud segments or 'liver' for a binary liver mask.
- 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.
167def get_couinaud_loader( 168 path: Union[os.PathLike, str], 169 batch_size: int, 170 patch_shape: Tuple[int, ...], 171 annotation: Literal["couinaud", "liver"] = "couinaud", 172 resize_inputs: bool = False, 173 download: bool = False, 174 **kwargs 175) -> DataLoader: 176 """Get the Couinaud dataloader for liver segment segmentation. 177 178 Args: 179 path: Filepath to a folder where the data is downloaded for further processing. 180 batch_size: The batch size for training. 181 patch_shape: The patch shape to use for training. 182 annotation: The choice of annotations. Either 'couinaud' for the eight Couinaud segments 183 or 'liver' for a binary liver mask. 184 resize_inputs: Whether to resize inputs to the desired patch shape. 185 download: Whether to download the data if it is not present. 186 kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset` or for the PyTorch DataLoader. 187 188 Returns: 189 The DataLoader. 190 """ 191 ds_kwargs, loader_kwargs = util.split_kwargs(torch_em.default_segmentation_dataset, **kwargs) 192 dataset = get_couinaud_dataset(path, patch_shape, annotation, resize_inputs, download, **ds_kwargs) 193 return torch_em.get_data_loader(dataset, batch_size, **loader_kwargs)
Get the Couinaud dataloader for liver segment 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.
- annotation: The choice of annotations. Either 'couinaud' for the eight Couinaud segments or 'liver' for a binary liver mask.
- 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_datasetor for the PyTorch DataLoader.
Returns:
The DataLoader.