torch_em.data.datasets.histopathology.icc
The ICC dataset contains annotations for interstitial cells of Cajal (ICC) segmentation in anti-CD117 immunohistochemistry stained anal canal wall images from haemorrhoidal disease patients.
The dataset is located at https://doi.org/10.5281/zenodo.14900511 under the CC BY-NC-SA 4.0 license. This dataset is from the publication https://doi.org/10.3390/cells14070550. Please cite it if you use this dataset in your research.
1"""The ICC dataset contains annotations for interstitial cells of Cajal (ICC) segmentation 2in anti-CD117 immunohistochemistry stained anal canal wall images from haemorrhoidal disease 3patients. 4 5The dataset is located at https://doi.org/10.5281/zenodo.14900511 under the 6CC BY-NC-SA 4.0 license. This dataset is from the publication https://doi.org/10.3390/cells14070550. 7Please cite it if you use this dataset in your research. 8""" 9 10import os 11import json 12from glob import glob 13from tqdm import tqdm 14from natsort import natsorted 15from collections import defaultdict 16from typing import List, Tuple, Union 17 18import numpy as np 19import imageio.v3 as imageio 20 21from torch.utils.data import Dataset, DataLoader 22 23import torch_em 24 25from .. import util 26 27 28URLS = { 29 "images": "https://zenodo.org/records/14900511/files/Images.zip", 30 "annotations": "https://zenodo.org/records/14900511/files/Annotations.coco.json", 31} 32CHECKSUMS = { 33 "images": "d51cb75091891437df80c4ab69412a622c2181ddb9b974ddbc84aeb326542380", 34 "annotations": "e98facfdbe04226eb004b40ef06a4c25179ce952ab036d9f00738ceda49708be", 35} 36 37 38def _rasterize_labels(coco, data_dir): 39 label_dir = os.path.join(data_dir, "labels") 40 if os.path.exists(label_dir) and len(glob(os.path.join(label_dir, "*.tif"))) == len(coco["images"]): 41 return label_dir 42 43 os.makedirs(label_dir, exist_ok=True) 44 45 from skimage.draw import polygon as draw_polygon 46 47 annotations_per_image = defaultdict(list) 48 for annotation in coco["annotations"]: 49 annotations_per_image[annotation["image_id"]].append(annotation) 50 51 for image in tqdm(coco["images"], desc="Rasterize the ICC annotations"): 52 shape = (image["height"], image["width"]) 53 labels = np.zeros(shape, dtype="uint16") 54 for instance_id, annotation in enumerate(annotations_per_image[image["id"]], start=1): 55 polygon = np.array(annotation["segmentation"][0], dtype=float).reshape(-1, 2) 56 rows, columns = draw_polygon(polygon[:, 1], polygon[:, 0], shape=shape) 57 labels[rows, columns] = instance_id 58 59 name = os.path.splitext(image["file_name"])[0] 60 imageio.imwrite(os.path.join(label_dir, f"{name}.tif"), labels, compression="zlib") 61 62 return label_dir 63 64 65def get_icc_data(path: Union[os.PathLike, str], download: bool = False) -> str: 66 """Download the ICC dataset. 67 68 Args: 69 path: Filepath to a folder where the downloaded data will be saved. 70 download: Whether to download the data if it is not present. 71 72 Returns: 73 The filepath to the folder where the images are stored. 74 """ 75 image_dir = os.path.join(path, "images") 76 if os.path.exists(image_dir): 77 return path 78 79 os.makedirs(path, exist_ok=True) 80 81 zip_path = os.path.join(path, "Images.zip") 82 util.download_source(path=zip_path, url=URLS["images"], download=download, checksum=CHECKSUMS["images"]) 83 util.unzip(zip_path=zip_path, dst=image_dir) 84 85 annotation_path = os.path.join(path, "Annotations.coco.json") 86 util.download_source( 87 path=annotation_path, url=URLS["annotations"], download=download, checksum=CHECKSUMS["annotations"] 88 ) 89 90 return path 91 92 93def get_icc_paths(path: Union[os.PathLike, str], download: bool = False) -> Tuple[List[str], List[str]]: 94 """Get paths to the ICC data. 95 96 Args: 97 path: Filepath to a folder where the downloaded data will be saved. 98 download: Whether to download the data if it is not present. 99 100 Returns: 101 List of filepaths for the image data. 102 List of filepaths for the label data. 103 """ 104 data_dir = get_icc_data(path, download) 105 106 with open(os.path.join(data_dir, "Annotations.coco.json")) as f: 107 coco = json.load(f) 108 109 label_dir = _rasterize_labels(coco, data_dir) 110 111 raw_paths = natsorted(glob(os.path.join(data_dir, "images", "*.jpg"))) 112 label_paths = natsorted(glob(os.path.join(label_dir, "*.tif"))) 113 114 assert len(raw_paths) == len(label_paths) and len(raw_paths) > 0 115 assert all( 116 os.path.splitext(os.path.basename(raw_path))[0] == os.path.splitext(os.path.basename(label_path))[0] 117 for raw_path, label_path in zip(raw_paths, label_paths) 118 ) 119 120 return raw_paths, label_paths 121 122 123def get_icc_dataset( 124 path: Union[os.PathLike, str], 125 patch_shape: Tuple[int, int], 126 resize_inputs: bool = False, 127 download: bool = False, 128 **kwargs, 129) -> Dataset: 130 """Get the ICC dataset for interstitial cells of Cajal segmentation. 131 132 Args: 133 path: Filepath to a folder where the downloaded data will be saved. 134 patch_shape: The patch shape to use for training. 135 resize_inputs: Whether to resize the inputs. 136 download: Whether to download the data if it is not present. 137 kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset`. 138 139 Returns: 140 The segmentation dataset. 141 """ 142 raw_paths, label_paths = get_icc_paths(path, download) 143 144 if resize_inputs: 145 resize_kwargs = {"patch_shape": patch_shape, "is_rgb": True} 146 kwargs, patch_shape = util.update_kwargs_for_resize_trafo( 147 kwargs=kwargs, patch_shape=patch_shape, resize_inputs=resize_inputs, resize_kwargs=resize_kwargs 148 ) 149 150 return torch_em.default_segmentation_dataset( 151 raw_paths=raw_paths, 152 raw_key=None, 153 label_paths=label_paths, 154 label_key=None, 155 patch_shape=patch_shape, 156 is_seg_dataset=False, 157 ndim=2, 158 with_channels=True, 159 **kwargs, 160 ) 161 162 163def get_icc_loader( 164 path: Union[os.PathLike, str], 165 batch_size: int, 166 patch_shape: Tuple[int, int], 167 resize_inputs: bool = False, 168 download: bool = False, 169 **kwargs, 170) -> DataLoader: 171 """Get the ICC dataloader for interstitial cells of Cajal segmentation. 172 173 Args: 174 path: Filepath to a folder where the downloaded data will be saved. 175 batch_size: The batch size for training. 176 patch_shape: The patch shape to use for training. 177 resize_inputs: Whether to resize the inputs. 178 download: Whether to download the data if it is not present. 179 kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset` or the PyTorch DataLoader. 180 181 Returns: 182 The DataLoader. 183 """ 184 ds_kwargs, loader_kwargs = util.split_kwargs(torch_em.default_segmentation_dataset, **kwargs) 185 dataset = get_icc_dataset(path, patch_shape, resize_inputs, download, **ds_kwargs) 186 return torch_em.get_data_loader(dataset, batch_size, **loader_kwargs)
66def get_icc_data(path: Union[os.PathLike, str], download: bool = False) -> str: 67 """Download the ICC dataset. 68 69 Args: 70 path: Filepath to a folder where the downloaded data will be saved. 71 download: Whether to download the data if it is not present. 72 73 Returns: 74 The filepath to the folder where the images are stored. 75 """ 76 image_dir = os.path.join(path, "images") 77 if os.path.exists(image_dir): 78 return path 79 80 os.makedirs(path, exist_ok=True) 81 82 zip_path = os.path.join(path, "Images.zip") 83 util.download_source(path=zip_path, url=URLS["images"], download=download, checksum=CHECKSUMS["images"]) 84 util.unzip(zip_path=zip_path, dst=image_dir) 85 86 annotation_path = os.path.join(path, "Annotations.coco.json") 87 util.download_source( 88 path=annotation_path, url=URLS["annotations"], download=download, checksum=CHECKSUMS["annotations"] 89 ) 90 91 return path
Download the ICC 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:
The filepath to the folder where the images are stored.
94def get_icc_paths(path: Union[os.PathLike, str], download: bool = False) -> Tuple[List[str], List[str]]: 95 """Get paths to the ICC data. 96 97 Args: 98 path: Filepath to a folder where the downloaded data will be saved. 99 download: Whether to download the data if it is not present. 100 101 Returns: 102 List of filepaths for the image data. 103 List of filepaths for the label data. 104 """ 105 data_dir = get_icc_data(path, download) 106 107 with open(os.path.join(data_dir, "Annotations.coco.json")) as f: 108 coco = json.load(f) 109 110 label_dir = _rasterize_labels(coco, data_dir) 111 112 raw_paths = natsorted(glob(os.path.join(data_dir, "images", "*.jpg"))) 113 label_paths = natsorted(glob(os.path.join(label_dir, "*.tif"))) 114 115 assert len(raw_paths) == len(label_paths) and len(raw_paths) > 0 116 assert all( 117 os.path.splitext(os.path.basename(raw_path))[0] == os.path.splitext(os.path.basename(label_path))[0] 118 for raw_path, label_path in zip(raw_paths, label_paths) 119 ) 120 121 return raw_paths, label_paths
Get paths to the ICC 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.
124def get_icc_dataset( 125 path: Union[os.PathLike, str], 126 patch_shape: Tuple[int, int], 127 resize_inputs: bool = False, 128 download: bool = False, 129 **kwargs, 130) -> Dataset: 131 """Get the ICC dataset for interstitial cells of Cajal segmentation. 132 133 Args: 134 path: Filepath to a folder where the downloaded data will be saved. 135 patch_shape: The patch shape to use for training. 136 resize_inputs: Whether to resize the inputs. 137 download: Whether to download the data if it is not present. 138 kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset`. 139 140 Returns: 141 The segmentation dataset. 142 """ 143 raw_paths, label_paths = get_icc_paths(path, download) 144 145 if resize_inputs: 146 resize_kwargs = {"patch_shape": patch_shape, "is_rgb": True} 147 kwargs, patch_shape = util.update_kwargs_for_resize_trafo( 148 kwargs=kwargs, patch_shape=patch_shape, resize_inputs=resize_inputs, resize_kwargs=resize_kwargs 149 ) 150 151 return torch_em.default_segmentation_dataset( 152 raw_paths=raw_paths, 153 raw_key=None, 154 label_paths=label_paths, 155 label_key=None, 156 patch_shape=patch_shape, 157 is_seg_dataset=False, 158 ndim=2, 159 with_channels=True, 160 **kwargs, 161 )
Get the ICC dataset for interstitial cells of Cajal 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.
164def get_icc_loader( 165 path: Union[os.PathLike, str], 166 batch_size: int, 167 patch_shape: Tuple[int, int], 168 resize_inputs: bool = False, 169 download: bool = False, 170 **kwargs, 171) -> DataLoader: 172 """Get the ICC dataloader for interstitial cells of Cajal segmentation. 173 174 Args: 175 path: Filepath to a folder where the downloaded data will be saved. 176 batch_size: The batch size for training. 177 patch_shape: The patch shape to use for training. 178 resize_inputs: Whether to resize the inputs. 179 download: Whether to download the data if it is not present. 180 kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset` or the PyTorch DataLoader. 181 182 Returns: 183 The DataLoader. 184 """ 185 ds_kwargs, loader_kwargs = util.split_kwargs(torch_em.default_segmentation_dataset, **kwargs) 186 dataset = get_icc_dataset(path, patch_shape, resize_inputs, download, **ds_kwargs) 187 return torch_em.get_data_loader(dataset, batch_size, **loader_kwargs)
Get the ICC dataloader for interstitial cells of Cajal 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_datasetor the PyTorch DataLoader.
Returns:
The DataLoader.