torch_em.data.datasets.medical.fuseg
The FUSeg dataset contains annotations for wound segmentation in clinical foot ulcer photographs.
The dataset consists of 1,210 foot ulcer images collected over two years from 889 patients for the 2021 MICCAI Foot Ulcer Segmentation (FUSeg) Challenge. Only the 'train' and 'validation' splits are used here, as they are the only splits with publicly released ground-truth masks; the 'test' split ground truth is kept private by the challenge organizers for the leaderboard.
The dataset is located at https://github.com/uwm-bigdata/wound-segmentation. The dataset is from the publication https://doi.org/10.3390/info15030140. Please cite it if you use this dataset for your research.
1"""The FUSeg dataset contains annotations for wound segmentation in clinical foot ulcer photographs. 2 3The dataset consists of 1,210 foot ulcer images collected over two years from 889 patients for the 42021 MICCAI Foot Ulcer Segmentation (FUSeg) Challenge. Only the 'train' and 'validation' splits are 5used here, as they are the only splits with publicly released ground-truth masks; the 'test' split 6ground truth is kept private by the challenge organizers for the leaderboard. 7 8The dataset is located at https://github.com/uwm-bigdata/wound-segmentation. 9The dataset is from the publication https://doi.org/10.3390/info15030140. 10Please cite it if you use this dataset for your research. 11""" 12 13import os 14import subprocess 15from glob import glob 16from natsort import natsorted 17from typing import Union, Tuple, Literal, List 18 19import imageio.v3 as imageio 20 21from torch.utils.data import Dataset, DataLoader 22 23import torch_em 24 25from .. import util 26from ..light_microscopy.neurips_cell_seg import to_rgb 27 28 29URL = "https://github.com/uwm-bigdata/wound-segmentation.git" 30 31CHALLENGE_DIR = "Foot Ulcer Segmentation Challenge" 32 33 34def get_fuseg_data(path: Union[os.PathLike, str], download: bool = False) -> str: 35 """Download the FUSeg dataset. 36 37 Args: 38 path: Filepath to a folder where the data is downloaded for further processing. 39 download: Whether to download the data if it is not present. 40 41 Returns: 42 Filepath where the data is downloaded. 43 """ 44 data_dir = os.path.join(path, "wound-segmentation", "data", CHALLENGE_DIR) 45 if os.path.exists(data_dir): 46 return data_dir 47 48 if not download: 49 raise RuntimeError(f"Cannot find the data at {path}, but download was set to False") 50 51 os.makedirs(path, exist_ok=True) 52 repo_dir = os.path.join(path, "wound-segmentation") 53 subprocess.run( 54 ["git", "clone", "--filter=blob:none", "--sparse", "--depth", "1", "--quiet", URL, repo_dir], check=True 55 ) 56 subprocess.run(["git", "sparse-checkout", "set", os.path.join("data", CHALLENGE_DIR)], cwd=repo_dir, check=True) 57 58 return data_dir 59 60 61def _binarize_mask(mask_path, out_path): 62 if os.path.exists(out_path): 63 return 64 mask = imageio.imread(mask_path) 65 if mask.ndim == 3: 66 mask = mask[..., 0] 67 mask = (mask > 127).astype("uint8") 68 imageio.imwrite(out_path, mask) 69 70 71def get_fuseg_paths( 72 path: Union[os.PathLike, str], split: Literal["train", "validation"] = "train", download: bool = False 73) -> Tuple[List[str], List[str]]: 74 """Get paths to the FUSeg data. 75 76 Args: 77 path: Filepath to a folder where the data is downloaded for further processing. 78 split: The choice of data split. Either 'train' or 'validation'. 79 download: Whether to download the data if it is not present. 80 81 Returns: 82 List of filepaths for the image data. 83 List of filepaths for the label data. 84 """ 85 if split not in ["train", "validation"]: 86 raise ValueError(f"'{split}' is not a valid split. Choose 'train' or 'validation'.") 87 88 data_dir = get_fuseg_data(path, download) 89 90 image_dir = os.path.join(data_dir, split, "images") 91 label_dir = os.path.join(data_dir, split, "labels") 92 preprocessed_dir = os.path.join(data_dir, split, "preprocessed_labels") 93 os.makedirs(preprocessed_dir, exist_ok=True) 94 95 image_paths = natsorted(glob(os.path.join(image_dir, "*.png"))) 96 97 label_paths = [] 98 for image_path in image_paths: 99 fname = os.path.basename(image_path) 100 mask_path = os.path.join(label_dir, fname) 101 out_path = os.path.join(preprocessed_dir, fname) 102 _binarize_mask(mask_path, out_path) 103 label_paths.append(out_path) 104 105 return image_paths, label_paths 106 107 108def get_fuseg_dataset( 109 path: Union[os.PathLike, str], 110 patch_shape: Tuple[int, int], 111 split: Literal["train", "validation"] = "train", 112 resize_inputs: bool = False, 113 download: bool = False, 114 **kwargs 115) -> Dataset: 116 """Get the FUSeg dataset for wound segmentation in foot ulcer photographs. 117 118 Args: 119 path: Filepath to a folder where the data is downloaded for further processing. 120 patch_shape: The patch shape to use for training. 121 split: The choice of data split. Either 'train' or 'validation'. 122 resize_inputs: Whether to resize the inputs to the expected patch shape. 123 download: Whether to download the data if it is not present. 124 kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset`. 125 126 Returns: 127 The segmentation dataset. 128 """ 129 image_paths, label_paths = get_fuseg_paths(path, split, download) 130 131 if resize_inputs: 132 resize_kwargs = {"patch_shape": patch_shape, "is_rgb": True} 133 kwargs, patch_shape = util.update_kwargs_for_resize_trafo( 134 kwargs=kwargs, 135 patch_shape=patch_shape, 136 resize_inputs=resize_inputs, 137 resize_kwargs=resize_kwargs, 138 ensure_rgb=to_rgb, 139 ) 140 141 return torch_em.default_segmentation_dataset( 142 raw_paths=image_paths, 143 raw_key=None, 144 label_paths=label_paths, 145 label_key=None, 146 patch_shape=patch_shape, 147 is_seg_dataset=False, 148 **kwargs 149 ) 150 151 152def get_fuseg_loader( 153 path: Union[os.PathLike, str], 154 batch_size: int, 155 patch_shape: Tuple[int, int], 156 split: Literal["train", "validation"] = "train", 157 resize_inputs: bool = False, 158 download: bool = False, 159 **kwargs 160) -> DataLoader: 161 """Get the FUSeg dataloader for wound segmentation in foot ulcer photographs. 162 163 Args: 164 path: Filepath to a folder where the data is downloaded for further processing. 165 batch_size: The batch size for training. 166 patch_shape: The patch shape to use for training. 167 split: The choice of data split. Either 'train' or 'validation'. 168 resize_inputs: Whether to resize the inputs to the expected patch shape. 169 download: Whether to download the data if it is not present. 170 kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset` or for the PyTorch DataLoader. 171 172 Returns: 173 The DataLoader. 174 """ 175 ds_kwargs, loader_kwargs = util.split_kwargs(torch_em.default_segmentation_dataset, **kwargs) 176 dataset = get_fuseg_dataset(path, patch_shape, split, resize_inputs, download, **ds_kwargs) 177 return torch_em.get_data_loader(dataset, batch_size, **loader_kwargs)
35def get_fuseg_data(path: Union[os.PathLike, str], download: bool = False) -> str: 36 """Download the FUSeg dataset. 37 38 Args: 39 path: Filepath to a folder where the data is downloaded for further processing. 40 download: Whether to download the data if it is not present. 41 42 Returns: 43 Filepath where the data is downloaded. 44 """ 45 data_dir = os.path.join(path, "wound-segmentation", "data", CHALLENGE_DIR) 46 if os.path.exists(data_dir): 47 return data_dir 48 49 if not download: 50 raise RuntimeError(f"Cannot find the data at {path}, but download was set to False") 51 52 os.makedirs(path, exist_ok=True) 53 repo_dir = os.path.join(path, "wound-segmentation") 54 subprocess.run( 55 ["git", "clone", "--filter=blob:none", "--sparse", "--depth", "1", "--quiet", URL, repo_dir], check=True 56 ) 57 subprocess.run(["git", "sparse-checkout", "set", os.path.join("data", CHALLENGE_DIR)], cwd=repo_dir, check=True) 58 59 return data_dir
Download the FUSeg 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 data is downloaded.
72def get_fuseg_paths( 73 path: Union[os.PathLike, str], split: Literal["train", "validation"] = "train", download: bool = False 74) -> Tuple[List[str], List[str]]: 75 """Get paths to the FUSeg data. 76 77 Args: 78 path: Filepath to a folder where the data is downloaded for further processing. 79 split: The choice of data split. Either 'train' or 'validation'. 80 download: Whether to download the data if it is not present. 81 82 Returns: 83 List of filepaths for the image data. 84 List of filepaths for the label data. 85 """ 86 if split not in ["train", "validation"]: 87 raise ValueError(f"'{split}' is not a valid split. Choose 'train' or 'validation'.") 88 89 data_dir = get_fuseg_data(path, download) 90 91 image_dir = os.path.join(data_dir, split, "images") 92 label_dir = os.path.join(data_dir, split, "labels") 93 preprocessed_dir = os.path.join(data_dir, split, "preprocessed_labels") 94 os.makedirs(preprocessed_dir, exist_ok=True) 95 96 image_paths = natsorted(glob(os.path.join(image_dir, "*.png"))) 97 98 label_paths = [] 99 for image_path in image_paths: 100 fname = os.path.basename(image_path) 101 mask_path = os.path.join(label_dir, fname) 102 out_path = os.path.join(preprocessed_dir, fname) 103 _binarize_mask(mask_path, out_path) 104 label_paths.append(out_path) 105 106 return image_paths, label_paths
Get paths to the FUSeg data.
Arguments:
- path: Filepath to a folder where the data is downloaded for further processing.
- split: The choice of data split. Either 'train' or 'validation'.
- 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.
109def get_fuseg_dataset( 110 path: Union[os.PathLike, str], 111 patch_shape: Tuple[int, int], 112 split: Literal["train", "validation"] = "train", 113 resize_inputs: bool = False, 114 download: bool = False, 115 **kwargs 116) -> Dataset: 117 """Get the FUSeg dataset for wound segmentation in foot ulcer photographs. 118 119 Args: 120 path: Filepath to a folder where the data is downloaded for further processing. 121 patch_shape: The patch shape to use for training. 122 split: The choice of data split. Either 'train' or 'validation'. 123 resize_inputs: Whether to resize the inputs to the expected patch shape. 124 download: Whether to download the data if it is not present. 125 kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset`. 126 127 Returns: 128 The segmentation dataset. 129 """ 130 image_paths, label_paths = get_fuseg_paths(path, split, download) 131 132 if resize_inputs: 133 resize_kwargs = {"patch_shape": patch_shape, "is_rgb": True} 134 kwargs, patch_shape = util.update_kwargs_for_resize_trafo( 135 kwargs=kwargs, 136 patch_shape=patch_shape, 137 resize_inputs=resize_inputs, 138 resize_kwargs=resize_kwargs, 139 ensure_rgb=to_rgb, 140 ) 141 142 return torch_em.default_segmentation_dataset( 143 raw_paths=image_paths, 144 raw_key=None, 145 label_paths=label_paths, 146 label_key=None, 147 patch_shape=patch_shape, 148 is_seg_dataset=False, 149 **kwargs 150 )
Get the FUSeg dataset for wound segmentation in foot ulcer photographs.
Arguments:
- path: Filepath to a folder where the data is downloaded for further processing.
- patch_shape: The patch shape to use for training.
- split: The choice of data split. Either 'train' or 'validation'.
- resize_inputs: Whether to resize the inputs to the expected 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.
153def get_fuseg_loader( 154 path: Union[os.PathLike, str], 155 batch_size: int, 156 patch_shape: Tuple[int, int], 157 split: Literal["train", "validation"] = "train", 158 resize_inputs: bool = False, 159 download: bool = False, 160 **kwargs 161) -> DataLoader: 162 """Get the FUSeg dataloader for wound segmentation in foot ulcer photographs. 163 164 Args: 165 path: Filepath to a folder where the data is downloaded for further processing. 166 batch_size: The batch size for training. 167 patch_shape: The patch shape to use for training. 168 split: The choice of data split. Either 'train' or 'validation'. 169 resize_inputs: Whether to resize the inputs to the expected patch shape. 170 download: Whether to download the data if it is not present. 171 kwargs: Additional keyword arguments for `torch_em.default_segmentation_dataset` or for the PyTorch DataLoader. 172 173 Returns: 174 The DataLoader. 175 """ 176 ds_kwargs, loader_kwargs = util.split_kwargs(torch_em.default_segmentation_dataset, **kwargs) 177 dataset = get_fuseg_dataset(path, patch_shape, split, resize_inputs, download, **ds_kwargs) 178 return torch_em.get_data_loader(dataset, batch_size, **loader_kwargs)
Get the FUSeg dataloader for wound segmentation in foot ulcer photographs.
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.
- split: The choice of data split. Either 'train' or 'validation'.
- resize_inputs: Whether to resize the inputs to the expected 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.